{"id":13416562,"url":"https://github.com/bibendi/dip","last_synced_at":"2025-05-13T19:05:03.586Z","repository":{"id":11615076,"uuid":"70123996","full_name":"bibendi/dip","owner":"bibendi","description":"The dip is a CLI dev–tool that provides native-like interaction with a Dockerized application.","archived":false,"fork":false,"pushed_at":"2024-12-25T09:38:57.000Z","size":574,"stargazers_count":1287,"open_issues_count":15,"forks_count":47,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-28T00:40:04.521Z","etag":null,"topics":["bash","cli","docker","docker-compose","gem","ruby","thor","zsh"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bibendi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["bibendi"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2016-10-06T04:56:38.000Z","updated_at":"2025-04-21T13:45:24.000Z","dependencies_parsed_at":"2024-03-14T07:39:22.654Z","dependency_job_id":"44d6e94f-8c35-4ac0-884b-af5600743962","html_url":"https://github.com/bibendi/dip","commit_stats":{"total_commits":306,"total_committers":26,"mean_commits":11.76923076923077,"dds":"0.13398692810457513","last_synced_commit":"f8406a29f8c29c6b25f70b89784b66b9a3551d39"},"previous_names":[],"tags_count":76,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fdip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fdip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fdip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bibendi%2Fdip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bibendi","download_url":"https://codeload.github.com/bibendi/dip/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254010799,"owners_count":21998993,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","docker","docker-compose","gem","ruby","thor","zsh"],"created_at":"2024-07-30T21:01:00.944Z","updated_at":"2025-05-13T19:05:03.543Z","avatar_url":"https://github.com/bibendi.png","language":"Ruby","readme":"[![Gem Version](https://badge.fury.io/rb/dip.svg)](https://badge.fury.io/rb/dip)\n[![Build Status](https://github.com/bibendi/dip/actions/workflows/ci.yml/badge.svg)](https://github.com/bibendi/dip/actions/workflows/ci.yml)\n[![Maintainability](https://api.codeclimate.com/v1/badges/d0dca854f0930502f7b3/maintainability)](https://codeclimate.com/github/bibendi/dip/maintainability)\n\n\u003cimg src=\"https://raw.githubusercontent.com/bibendi/dip/master/.github/logo.png\" alt=\"dip logo\" height=\"140\" /\u003e\n\nThe dip is a CLI dev–tool that provides native-like interaction with a Dockerized application. It gives the feeling that you are working without using mind-blowing commands to run containers.\n\n\u003ca href=\"https://evilmartians.com/?utm_source=dip\"\u003e\n\u003cimg src=\"https://evilmartians.com/badges/sponsored-by-evil-martians.svg\" alt=\"Sponsored by Evil Martians\" height=\"80\" /\u003e\u003c/a\u003e\n\n## Presentations and examples\n\n- [Local development with Docker containers](https://slides.com/bibendi/dip)\n- [Dockerized Ruby on Rails application](https://github.com/Kuper-Tech/outbox-example-apps)\n- Dockerized Node.js application: [one](https://github.com/bibendi/twinkle.js), [two](https://github.com/bibendi/yt-graphql-react-event-booking-api)\n- [Dockerized Ruby gem](https://github.com/bibendi/schked)\n- [Dockerizing Ruby and Rails development](https://evilmartians.com/chronicles/ruby-on-whales-docker-for-ruby-rails-development)\n- [Reusable development containers with Docker Compose and Dip](https://evilmartians.com/chronicles/reusable-development-containers-with-docker-compose-and-dip)\n\n[![asciicast](https://asciinema.org/a/210236.svg)](https://asciinema.org/a/210236)\n\n## Installation\n\n```sh\ngem install dip\n```\n\n### Integration with shell\n\nDip can be injected into the current shell (ZSH or Bash).\n\n```sh\neval \"$(dip console)\"\n```\n\n**IMPORTANT**: Beware of possible collisions with local tools. One particular example is supporting both local and Docker frontend build tools, such as Yarn. If you want some developer to run `yarn` locally and other to use Docker for that, you should either avoid adding the `yarn` command to the `dip.yml` or avoid using the shell integration for hybrid development.\n\nAfter that we can type commands without `dip` prefix. For example:\n\n```sh\n\u003crun-command\u003e *any-args\ncompose *any-compose-arg\nup \u003cservice\u003e\nktl *any-kubectl-arg\nprovision\n```\n\nWhen we change the current directory, all shell aliases will be automatically removed. But when we enter back into a directory with a `dip.yml` file, then shell aliases will be renewed.\n\nAlso, in shell mode Dip is trying to determine manually passed environment variables. For example:\n\n```sh\nVERSION=20180515103400 rails db:migrate:down\n```\n\nYou could add this `eval` at the end of your `~/.zshrc`, or `~/.bashrc`, or `~/.bash_profile`.\nAfter that, it will be automatically applied when you open your preferred terminal.\n\n## Usage\n\n```sh\ndip --help\ndip SUBCOMMAND --help\n```\n\n### dip.yml\n\nThe configuration is loaded from `dip.yml` file. It may be located in a working directory, or it will be found in the nearest parent directory up to the file system root. If nearby places `dip.override.yml` file, it will be merged into the main config.\n\nAlso, in some cases, you may want to change the default config path by providing an environment variable `DIP_FILE`.\n\nBelow is an example of a real config.\nConfig file reference will be written soon.\nAlso, you can check out examples at the top.\n\n```yml\n# Required minimum dip version\nversion: '8.0'\n\nenvironment:\n  COMPOSE_EXT: development\n  STAGE: \"staging\"\n\ncompose:\n  files:\n    - docker/docker-compose.yml\n    - docker/docker-compose.$COMPOSE_EXT.yml\n    - docker/docker-compose.$DIP_OS.yml\n  project_name: bear\n\nkubectl:\n  namespace: rocket-$STAGE\n\ninteraction:\n  shell:\n    description: Open the Bash shell in app's container\n    service: app\n    command: bash\n    compose:\n      run_options: [no-deps]\n\n  bundle:\n    description: Run Bundler commands\n    service: app\n    command: bundle\n\n  rake:\n    description: Run Rake commands\n    service: app\n    command: bundle exec rake\n\n  rspec:\n    description: Run Rspec commands\n    service: app\n    environment:\n      RAILS_ENV: test\n    command: bundle exec rspec\n\n  rails:\n    description: Run Rails commands\n    service: app\n    command: bundle exec rails\n    subcommands:\n      s:\n        description: Run Rails server at http://localhost:3000\n        service: web\n        compose:\n          run_options: [service-ports, use-aliases]\n\n  stack:\n    description: Run full stack (server, workers, etc.)\n    runner: docker_compose\n    compose:\n      profiles: [web, workers]\n\n  sidekiq:\n    description: Run sidekiq in background\n    service: worker\n    compose:\n      method: up\n      run_options: [detach]\n\n  psql:\n    description: Run Postgres psql console\n    service: app\n    default_args: db_dev\n    command: psql -h pg -U postgres\n\n  k:\n    description: Run commands in Kubernetes cluster\n    pod: svc/rocket-app:app-container\n    entrypoint: /env-entrypoint\n    subcommands:\n      bash:\n        description: Get a shell to the running container\n        command: /bin/bash\n      rails:\n        description: Run Rails commands\n        command: bundle exec rails\n      kafka-topics:\n        description: Manage Kafka topics\n        pod: svc/rocket-kafka\n        command: kafka-topics.sh --zookeeper zookeeper:2181\n\n  setup_key:\n    description: Copy key\n    service: app\n    command: cp `pwd`/config/key.pem /root/keys/\n    shell: false # you can disable shell interpolations on the host machine and send the command as is\n\n  clean_cache:\n    description: Delete cache files on the host machine\n    command: rm -rf $(pwd)/tmp/cache/*\n\nprovision:\n  - dip compose down --volumes\n  - dip clean_cache\n  - dip compose up -d pg redis\n  - dip bash -c ./bin/setup\n```\n\n### Predefined environment variables\n\n#### $DIP_OS\n\nCurrent OS architecture (e.g. `linux`, `darwin`, `freebsd`, and so on). Sometime it may be useful to have one common `docker-compose.yml` and OS-dependent Compose configs.\n\n#### $DIP_WORK_DIR_REL_PATH\n\nRelative path from the current directory to the nearest directory where a Dip's config is found. It is useful when you need to mount a specific local directory to a container along with ability to change its working dir. For example:\n\n```\n- project_root\n  |- dip.yml (1)\n  |- docker-compose.yml (2)\n  |- sub-project-dir\n     |- your current directory is here \u003c\u003c\u003c\n```\n\n```yml\n# dip.yml (1)\nenvironment:\n  WORK_DIR: /app/${DIP_WORK_DIR_REL_PATH}\n```\n\n```yml\n# docker-compose.yml (2)\nservices:\n  app:\n    working_dir: ${WORK_DIR:-/app}\n```\n\n```sh\ncd sub-project-dir\ndip run bash -c pwd\n```\n\nreturned is `/app/sub-project-dir`.\n\n#### $DIP_CURRENT_USER\n\nExposes the current user ID (UID). It is useful when you need to run a container with the same user as the host machine. For example:\n\n```yml\n# dip.yml (1)\nenvironment:\n  UID: ${DIP_CURRENT_USER}\n```\n\n```yml\n# docker-compose.yml (2)\nservices:\n  app:\n    image: ruby\n    user: ${UID:-1000}\n```\n\nThe container will run using the same user ID as your host machine.\n\n### Modules\n\nModules are defined as array in `modules` section of dip.yml, modules are stored in `.dip` subdirectory of dip.yml directory.\n\nThe main purpose of modules is to improve maintainability for a group of projects.\nImagine having multiple gems which are managed with dip, each of them has the same commands, so to change one command in dip you need to update all gems individualy.\n\nWith `modules` you can define a group of modules for dip.\n\nFor example having setup as this:\n\n```yml\n# ./dip.yml\nmodules:\n - sasts\n - rails\n\n...\n```\n\n```yml\n# ./.dip/sasts.yml\ninteraction:\n  brakeman:\n    description: Check brakeman sast\n    command: docker run ...\n```\n\n```yml\n# ./.dip/rails.yml\ninteraction:\n  annotate:\n    description: Run annotate command\n    service: backend\n    command: bundle exec annotate\n```\n\nWill be expanded to:\n\n```yml\n# resultant configuration\ninteraction:\n  brakeman:\n    description: Check brakeman sast\n    command: docker run ...\n  annotate:\n    description: Run annotate command\n    service: backend\n    command: bundle exec annotate\n```\n\nImagine `.dip` to be a submodule so it can be managed only in one place.\n\nIf you want to override module command, you can redefine it in dip.yml\n\n```yml\n# ./dip.yml\nmodules:\n - sasts\n\ninteraction:\n  brakeman:\n    description: Check brakeman sast\n    command: docker run another-image ...\n```\n\n```yml\n# ./.dip/sasts.yml\ninteraction:\n  brakeman:\n    description: Check brakeman sast\n    command: docker run some-image ...\n```\n\nWill be expanded to:\n\n```yml\n# resultant configuration\ninteraction:\n  brakeman:\n    description: Check brakeman sast\n    command: docker run another-image ...\n```\n\nNested modules are not supported.\n\n### dip run\n\nRun commands defined within the `interaction` section of dip.yml\n\nA command will be executed by specified runner. Dip has three types of them:\n\n- `docker compose` runner — used when the `service` option is defined.\n- `kubectl` runner — used when the `pod` option is defined.\n- `local` runner — used when the previous ones are not defined.\n\n```sh\ndip run rails c\ndip run rake db:migrate\n```\n\nAlso, `run` argument can be omitted\n\n```sh\ndip rake db:migrate\n```\n\nYou can pass in a custom environment variable into a container:\n\n```sh\ndip VERSION=12352452 rake db:rollback\n```\n\nUse options `-p, --publish=[]` if you need to additionally publish a container's port(s) to the host unless this behaviour is not configured at dip.yml:\n\n```sh\ndip run -p 3000:3000 bundle exec rackup config.ru\n```\n\nYou can also override docker compose command by passing `DIP_COMPOSE_COMMAND` if you wish. For example if you want to use [`mutagen-compose`](https://mutagen.io/documentation/orchestration/compose) run `DIP_COMPOSE_COMMAND=mutagen-compose dip run`.\n\nIf you want to persist that change you can specify command in `compose` section of dip.yml :\n\n```yml\ncompose:\n  command: mutagen-compose\n\n```\n\n### dip ls\n\nList all available run commands.\n\n```sh\ndip ls\n\nbash     # Open the Bash shell in app's container\nrails    # Run Rails command\nrails s  # Run Rails server at http://localhost:3000\n```\n\n### dip provision\n\nRun commands each by each from `provision` section of dip.yml\n\n### dip compose\n\nRun Docker Compose commands that are configured according to the application's dip.yml:\n\n```sh\ndip compose COMMAND [OPTIONS]\n\ndip compose up -d redis\n```\n\n### dip infra\n\nRuns shared Docker Compose services that are used by the current application. Useful for microservices.\n\nThere are several official infrastructure services available:\n- [dip-postgres](https://github.com/bibendi/dip-postgres)\n- [dip-kafka](https://github.com/bibendi/dip-kafka)\n- [dip-nginx](https://github.com/bibendi/dip-nginx)\n\n```yaml\n# dip.yml\ninfra:\n  foo:\n    git: https://github.com/owner/foo.git\n    ref: latest # default, optional\n  bar:\n    path: ~/path/to/bar\n```\n\nRepositories will be pulled to a `~/.dip/infra` folder. For example, for the `foo` service it would be like this: `~/.dip/infra/foo/latest` and clonned with the following command: `git clone -b \u003cref\u003e --single-branch \u003cgit\u003e --depth 1`.\n\nAvailable CLI commands:\n\n- `dip infra update` pulls updates from sources\n- `dip infra up` starts all infra services\n- `dip infra up -n kafka` starts a specific infra service\n- `dip infra down` stops all infra services\n- `dip infra down -n kafka` stops a specific infra service\n\n### dip ktl\n\nRun kubectl commands that are configured according to the application's dip.yml:\n\n```sh\ndip ktl COMMAND [OPTIONS]\n\nSTAGE=some dip ktl get pods\n```\n\n### dip ssh\n\nRuns ssh-agent container based on https://github.com/whilp/ssh-agent with your ~/.ssh/id_rsa.\nIt creates a named volume `ssh_data` with ssh socket.\nAn application's docker-compose.yml should contains environment variable `SSH_AUTH_SOCK=/ssh/auth/sock` and connects to external volume `ssh_data`.\n\n```sh\ndip ssh up\n```\n\ndocker-compose.yml\n\n```yml\nservices:\n  web:\n    environment:\n      - SSH_AUTH_SOCK=/ssh/auth/sock\n    volumes:\n      - ssh-data:/ssh:ro\n\nvolumes:\n  ssh-data:\n    external:\n      name: ssh_data\n```\n\nif you want to use non-root user you can specify UID like so:\n\n```\ndip ssh up -u 1000\n```\n\nThis especially helpful if you have something like this in your docker-compose.yml:\n\n```yml\nservices:\n  web:\n    user: \"1000:1000\"\n```\n\n### dip validate\n\nValidates your dip.yml configuration against the JSON schema. The schema validation helps ensure your configuration is correct and follows the expected format.\n\n```sh\ndip validate\n```\n\nThe validator will check:\n\n- Required properties are present\n- Property types are correct\n- Values match expected patterns\n- No unknown properties are used\n\nIf validation fails, you'll get detailed error messages indicating what needs to be fixed.\n\nYou can skip validation by setting `DIP_SKIP_VALIDATION` environment variable.\n\nAdd `# yaml-language-server: $schema=https://raw.githubusercontent.com/bibendi/dip/refs/heads/master/schema.json` to the top of your dip.yml to get schema validation in VSCode. Read more about [YAML Language Server](https://github.com/redhat-developer/vscode-yaml?tab=readme-ov-file#associating-schemas).\n\n## Changelog\n\nhttps://github.com/bibendi/dip/releases\n","funding_links":["https://github.com/sponsors/bibendi"],"categories":["Development with Docker","Ruby","cli","Awesome Ruby CLIs"],"sub_categories":["Development Environment","DevOps"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbibendi%2Fdip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbibendi%2Fdip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbibendi%2Fdip/lists"}