Docker ComposeでRails開発

最近はDocker for Windowsでの開発がいい感じにできるようになったのでメモ。

サンプルプロジェクト

GitHub - fly1tkg/rails_docker: docker composeの開発構成サンプル

Dockerfile

Dockerfileは開発用イメージでは bundle install しないほうがいいと思います。 これを含めてしまうと Gemfile が変更されるたび、このコマンドからイメージのビルドが始まるので、すべてのgemのインストールし直しが発生してしまうからです。

なので僕はdocker-composeでローカルのフォルダとリンクしてから vendor/bundle にgemをインストールするようにしています。

FROM ruby:2.3.3
RUN apt-get update -qq && apt-get install -y build-essential nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock
#開発向けはbundle installしない
#RUN bundle install
ADD . /myapp

Docker Compose

docker-compose.ymlの設定項目については以下のQiita記事が詳しいです。

qiita.com

僕はdocker-compose.yml は以下を使っています。

version: '2'
services:
  # Databaseのコンテナ
  db:
    image: mysql:5.7
    # Mysqlコンテナは以下の環境変数でrootのパスワードを指定できる
    environment:
      MYSQL_ROOT_PASSWORD: password
    # ホストOSの3306番ポートとコンテナ内の3306番ポートを設定
    ports:
      - "3306:3306"
    # ローカルのボリュームとフォルダを共有してしてデータを永続化する
    volumes:
      - db-data:/var/lib/mysql

  # railsのコンテナ
  web:
    # DBとは違って、こっちはカレントディレクトリでdocker buildしてイメージを作成
    build: .
    # コンテナ実行時のコマンドを指定
    command: bash -c "rm -f ./tmp/pids/server.pid && (bundle check || bundle install -j4 --retry 3) && bundle ex rails s -b 0.0.0.0 -p 3000"
    environment:
      BUNDLE_PATH: vendor/bundle
    # ホストOSのカレントディレクトリをコンテナ内の/myappと共有させる
    volumes:
      - .:/myapp
    # ホストOSの3000番ポートとコンテナ内の3000番ポートを設定
    ports:
      - "3000:3000"
    # 以下設定しておくとコンテナ内のホスト名dbがdbコンテナのIPアドレスとして引けるようになる
    links:
      - db

# ローカルのボリュームの設定
volumes:
  db-data:
    driver: local

webコンテナのコマンドは以下の感じになっています。

rm -f ./tmp/pids/server.pid

コンテナが正常終了しなかったときにpidが残っちゃうのであったら削除します。

bundle check || bundle install -j4 --retry 3

必要であればbundle installします。

bundle ex rails s -b 0.0.0.0 -p 3000

最後はrails起動コマンドです。

頑張って1行で納めてるけど、別途シェルスクリプトを準備してそれを呼び出したほうが可読性は高そうです、お好みで。

database.yml

docker-compose.yml の設定で dbdb ホストに起動していて、 root のパスワードは password なので、database.ymlを以下のように設定します。

default: &default
  adapter: mysql2
  encoding: utf8
  database: myapp_development
  pool: 5
  username: root
  password: password
  host: db

development:
  <<: *default
  database: myapp_development

開発開始

docker-compose up

出力が読みづらければ -d で呼び出して tail -f log/development.log とかでもいいと思います。

docker-compose up -d

rakeやrailsのコマンドなどコンテナ内での作業

docker-compose execでできます。

僕はcygwinのターミナル利用してるのでwinptyを挟んで実行してます。

winpty docker-compose exec web bundle exec rails g model user name:string

railsジェネレーター。

winpty docker-compose exec web rake db:create db:migrate

dbマイグレーション

winpty docker-compose exec web bash

コンテナのシェルにも入れます。

その他

linksでコンテナのホストが引けるようになっている

上のdocker-compose.ymlの例だとwebコンテナ内でdbのホスト名でdbコンテナのIPが引けるようになっている。

root@f69a3de1fdf2:/myapp# ping db
PING db (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.072 ms
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.197 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.329 ms

エディタ設定

Windowsで開発してると文字コード utf-8 と改行コード LF の設定をエディタに忘れずするようにしないといろいろ混ざります、、、