Docker で Rails の開発環境を構築する
Docker で Rails の開発環境を配れたら、楽できるのでは?思い、サンプルを作ったのでまとめる。
サンプルコード
Dockerfile と docker-compose.yml は以下の通り
FROM ruby:2.4.1 MAINTAINER mmts1007 ENV APP_ROOT=/usr/src/app WORKDIR $APP_ROOT EXPOSE 3000 RUN apt-get update && apt-get install -y \ nodejs \ mysql-client COPY . $APP_ROOT RUN bundle install CMD ["bundle", "exec", "rails", "s", "-b", "0.0.0.0"]
version: '3' services: db: image: mysql environment: MYSQL_ROOT_PASSWORD: root volumes: - mysql-data:/var/lib/mysql web: build: context: . dockerfile: Dockerfile.development volumes: - .:/usr/src/app ports: - "3000:3000" depends_on: - db volumes: mysql-data:
工夫した点
- 開発時は DB も必要になるため、 docker-compose を利用して 1コマンドで開発に必要がものが揃うようにした
- 修正したソースコードをすぐに反映したかったため、ソースコードは Docker コンテナにマウント
- DB に書き込んだデータは保持したかったので、 volumes を使って永続化
使い方
docker-compose build
$ pwd
/path/to/docker-rails/simple_note
$ docker-compose build
...
Successfully tagged simplenote_web:latest
docker-compose up
$ docker-compose up Starting simplenote_db_1 ... Starting simplenote_db_1 ... done Recreating simplenote_web_1 ... Recreating simplenote_web_1 ... done Attaching to simplenote_db_1, simplenote_web_1 ... web_1 | Use Ctrl-C to stop
ブラウザから http://localhost:3000 にアクセス
その他
初回起動時は DB、テーブルが存在しないため作成する
$ docker-compose run web bundle exec rake db:create $ docker-compose run web bundle exec rake db:migrate
追記
Gem ファイルの永続化
記事を公開したところ、先輩に「Gemfile 更新時に、全 Gem インストールし直しになっちゃうから Gem ファイルのインストール先も Volume にするのが良いよ」とコメントを頂きました。(ありがとうございます!)
確かに Gemfile 更新した時に毎回 build して、イメージに含めてあげないと動かない状態でした・・・
Gemfile に Kaminari を追加
gem 'kaminari'
bundle install
$ docker-compose run web bundle install ... Fetching kaminari-core 1.0.1 Installing kaminari-core 1.0.1 ... Fetching kaminari-activerecord 1.0.1 Installing kaminari-activerecord 1.0.1 Fetching kaminari-actionview 1.0.1 Installing kaminari-actionview 1.0.1 ... Fetching kaminari 1.0.1 Installing kaminari 1.0.1 ... Bundle complete! 18 Gemfile dependencies, 76 gems now installed. Bundled gems are installed into /usr/local/bundle.
もう一度 bundle install を実行すると キャッシュされて Gem は何もインストールされないことを期待していましたが・・・
$ docker-compose run web bundle install ... Fetching kaminari-core 1.0.1 Installing kaminari-core 1.0.1 ... Fetching kaminari-activerecord 1.0.1 Installing kaminari-activerecord 1.0.1 Fetching kaminari-actionview 1.0.1 Installing kaminari-actionview 1.0.1 ... Fetching kaminari 1.0.1 Installing kaminari 1.0.1 ... Bundle complete! 18 Gemfile dependencies, 76 gems now installed. Bundled gems are installed into /usr/local/bundle.
全く同じログが出ました・・・
新たに作成したコンテナに Gem をインストールし、そのコンテナは破棄されてしまうため、このような現象が起きてしまいました。
docker-compose.yml を以下のように変更し、インストールした Gem を永続化するようにしました。
iff --git a/simple_note/docker-compose.yml b/simple_note/docker-compose.yml index 18e6132..c824f93 100644 --- a/simple_note/docker-compose.yml +++ b/simple_note/docker-compose.yml @@ -12,9 +12,11 @@ services: dockerfile: Dockerfile.development volumes: - .:/usr/src/app + - gem-store:/usr/local/bundle ports: - "3000:3000" depends_on: - db volumes: mysql-data: + gem-store:
この状態であればコンテナが破棄されたとしても Gem 自体は残るので、先ほどの問題は発生しなくなりました!