dipとは
dipは、Rails開発会社のEvil Martiansのメンバーが作った、docker-composeでの作業を能率的に行えるツールです。dipはDocker Interaction Processの略だそうです。
- リポジトリ: bibendi/dip: CLI gives the “native” interaction with applications configured with Docker Compose
Rubyで書かれていますが、Rubyがなくても使えます。元々Rails向けに作られたツールのようですが、Evil MartiansのReactアプリにもdip.xmlがあることからわかるように、Railsに限らず一般のdocker-composeでも使えます。私の場合はローカル開発環境でのみ使っています。
Evil Martiansはdipの記事を書くと言ってましたが、未だに出ていないので自分で記事を書いてみました。
dipのREADMEにはシェルと統合してdip
を省略する方法も書かれていますが、ちょいやりすぎ感あったので自分はやっていません。
必要なもの
- Ruby 2.3以上(Rubyを使う場合)
- Dockerとdocker-composeがインストールされていること
- docker-compose.ymlファイル
インストール
以下のいずれかの方法でdipをインストールし、dip.ymlをdocker-compose.ymlと同じ階層に置きます。
1. homebrewでのインストール
brew tap bibendi/dip
brew install dip
2. gemコマンドでのインストール
gem install dip
3. コンパイル済みバイナリのインストール
curl -L https://github.com/bibendi/dip/releases/download/4.2.0/dip-`uname -s`-`uname -m` > /usr/local/bin/dip
chmod +x /usr/local/bin/dip
dip.ymlの設定
リポジトリにある以下のdip.ymlはEvil MartiansのRails案件に寄った設定なので、自分の用途に応じてカスタマイズが必要です。interaction:
の下のサブコマンドを適宜カスタマイズします。
version: '4'
compose:
files:
- docker-compose.yml
interaction:
bash:
description: Open the app container bash shell
service: app
command: /bin/bash
dev:
service: app
command: exit
subcommands:
console:
description: Open the gem console
command: ./bin/console
clean:
description: Clean dependencies
command: rm -rf Gemfile.lock
bundle:
description: Run Bundler commands
service: app
command: bundle
rspec:
description: Run Rspec commands
service: app
command: bundle exec rspec
rubocop:
description: Run Rubocop commands
service: app
command: bundle exec rubocop
provision:
- dip app clean
- dip bundle install
なおprovision:
というコマンドは固定されているらしく、他の名前にできませんでした。
自分のカスタマイズ例
これは以下の記事で自分が使ったdip.ymlです。
dip bash
やdip rubocop
は長いのでdip sh
やdip cop
にしてみました。
なおtest:
というサブコマンドは予約語なのか認識できなかったので、minitest:
としました。
version: '4'
environment:
RAILS_ENV: development
compose:
files:
- docker-compose.yml
interaction:
sh:
description: Open the app container bash shell
service: backend
command: /bin/bash
compose_run_options: [no-deps]
bundle:
description: Run bundler command
service: backend
command: bundle
compose_run_options: [no-deps]
rake:
description: Run rake command
service: backend
command: bundle exec rake
rails:
description: Run rails command
service: backend
command: bundle exec rails
subcommands:
s:
description: Start rails server
service: rails
compose_run_options: [service-ports]
yarn:
description: Run yarn command
service: backend
command: yarn
minitest:
description: Run minitest
service: backend
environment:
RAILS_ENV: test
command: bundle exec rails test
cop:
description: Run rubocop
service: backend
default_args: -a
command: bundle exec rubocop
psql:
description: Run psql console
service: postgres
command: psql -h postgres -U postgres -d postgres
inspect_all:
description: Run all checkers
service: backend
command: bundle exec license_finder
command: bundle exec rails test
command: bundle exec rails_best_practices .
command: bundle exec bundle-audit
command: bundle exec brakeman
provision:
- dip compose down
- dip compose up -d postgres
- dip yarn install
- dip sh -c "./bin/setup 2> /dev/null; exit 0"
- dip sh -c ./bin/setup
- dip sh -c "RAILS_ENV=test ./bin/setup"
使い方
dip.ymlのあるディレクトリでdip ls
すると、dip.ymlで設定したサブコマンドの一覧が表示されます。dip help
とするとさらに詳しいヘルプが表示されます。
$ dip ls
sh # Open the app container bash shell
bundle # Run bundler command
rake # Run rake command
rails # Run rails command
rails s # Start rails server
yarn # Run yarn command
minitest # Run minitest
cop # Run rubocop
psql # Run psql console
inspect_all # Run all checkers
あとはdip サブコマンド
を実行するだけです。
サブコマンドにはdip bundle install
やdip rails console
のようにオプションも追加できます。
dip ssh
やdip nginx
など凝った機能がいろいろあるようですが、その辺りはまだ追求していません。
dipの便利な点
Dockerが公式にこういうツールを出せばいいのにと思っちゃいました。
1. コンテナにログインせずに作業できる
bundle install
やrails dbconsole
やyarn install --check-files
といった決まりきったコマンドを実行するのに、いちいちシェルでログインするのは面倒です。また、Dockerのシェルの安定性にもちょっと不安があります。
dipならdip bundle install
、dip rails dbconsole
、dip yarn install --check-files
で実行できます。
なおGemfileがない状態でのrails new
はさすがにログインが必要でした。
2. コンテナの起動状態を気にしなくてよい
docker-composeでコンテナに入る場合、コンテナが起動していなければdocker-compose run app bash
、コンテナが起動していればdocker-compose exec app bash
とするなど、面倒な使い分けが必要になります。
そもそもdocker-compose
というコマンドが長すぎですよね。自分はdcom
というbashエイリアスを作っているほどです。
dipなら、たとえば自分の設定したdip sh
やdip rails s
はコンテナが起動していなくても使え、dipが終了すればコンテナも終了してくれます。コンテナの二重起動を気にしなくてよくなるのは本当にありがたいです。
その分起動は少々遅くはなると思います。
まあ自分は何か作業した後はdcom down
を実行する癖が付いてしまいましたが。
3. 複数のサブコマンド実行が書きやすい
docker-composeの中でシェルコマンドを複数実行しようとすると、たとえば以下のように&&
でつなげてbash -c
で実行するというダルい書き方になってしまいます。
command: bash -c "elasticsearch -d && elasticsearch --http.port=9250"
コマンドを5つも6つもつなげると美しくありませんし、シェルスクリプトに追い出すのも何だか敗北感があります。
dipなら自分のサブコマンドにcommand:
を複数書けます。ただしこの方法はドキュメントに見当たらないので、サポート外機能のつもりで使っています。
inspect_all:
description: Run all checkers
service: backend
command: bundle exec license_finder
command: bundle exec rails test
command: bundle exec rails_best_practices .
command: bundle exec bundle-audit
command: bundle exec brakeman
4. Dockerfileやdocker-compose.ymlの変更が基本的に不要
dip.ymlはDockerfileやdocker-compose.ymlと別に設定できるので、うかつにこれらを変更してチームの人に怒られずに済みます。dip.ymlを~/.gitignore_globalに加えておけば自分用に心ゆくまでカスタマイズできます。
試していませんが、さすがにsshログイン機能などを使う場合はdocker-compose.ymlの変更も必要そうです。
services:
web:
environment:
- SSH_AUTH_SOCK=/ssh/auth/sock
volumes:
- ssh-data:/ssh:ro
volumes:
ssh-data:
external:
name: ssh_data
おまけ
以下のprovision:
コマンドは自分のRails開発環境の初期設定用にbin/setup
などを実行します。
provision:
- dip compose down
- dip compose up -d postgres
- dip yarn install
- dip sh -c "./bin/setup 2> /dev/null; exit 0"
- dip sh -c ./bin/setup
- dip sh -c "RAILS_ENV=test ./bin/setup"
4つ目のdip sh -c "./bin/setup 2> /dev/null; exit 0"
は本来不要なはずなのですが、自分の環境ではなぜか./bin/setup
が1回目で必ずデータベース接続に失敗し、2度目だと成功するので、仕方なく加えています。そのうち直したいです。
おたより発掘
おーこれは便利そうだ。Railsのコンテナ環境を作るのに初回実行コマンドがいくつかあったりするので、それらを簡単に呼び出せるのはいいな。 / 他2件のコメント https://t.co/I1z24OHvu6 “docker-composeを便利にするツール「dip」を使ってみた” (94 users) https://t.co/ryyCa64Br3
— Inamuu (@kzm0211) November 28, 2019