Feedforce Developer Blog

フィードフォース開発者ブログ

Rails 5.2 開発環境を Docker で構築する

どうも、バックエンドエンジニアのサトウリョウスケです ✌︎('ω')✌︎

僕が所属している ソーシャルPLUS チームでは Rails の開発環境を Docker で構築しています。 自分も日々お世話になっている Docker ですが、イチから Dockerfile 書いた事が無かったので、やってみました。

こちらのチュートリアルを参考にしています。

クイックスタート・ガイド:Docker Compose と Rails — Docker-docs-ja 17.06.Beta ドキュメント

やってみた✨

早速ですがこちらが完成品の GitHub リポジトリになります。 github.com

この記事は v1.0.0 時点で書いていますが、リポジトリは今後も更新されていく可能性があります。

環境

  • Debian Stretch
  • Ruby 2.5.0
  • Rails 5.2.0.rc1
  • MySQL 5.7

つかいかた

Rails 5.2 で環境構築したと言いましたが、リポジトリには Rails のソースコードが一切含まれていません。 これは rails new から Docker でやっていくためです。 以下に手順を示しますので、興味ある方はぜひ記事を読みながら一緒にやってみて下さい 🙏

0. リポジトリをローカルにクローンする

$ git clone https://github.com/ryz310/rails-on-docker.git

1. 以下のコマンドを実行する

$ docker-compose run web rails new . --force --database=mysql --skip-bundle --skip-git

rails new によって必要なファイルがインストールされます。同時に Gemfile も Rails 用に更新されます。 残念ながらアプリ名は指定できないので、必要に応じて変更して下さい。

なお、後述の MySQL データの永続化のため MySQL のデータファイルを含めないようにリポジトリの方で .gitignore を用意しています。 そのため --skip-git を付けて Rails に .gitignore ファイルを作成させないようにしていますが、永続化が不用な場合はオプションを外して下さい。

2. 更新された Gemfile で以下のコメントアウトを外す

# gem 'mini_racer', platforms: :ruby

以前であれば therubyracer だったのですが、いつの間にか mini_racer に変わっていたのですね。

techracho.bpsinc.jp

TechRacho さんの週刊Railsウォッチにはいつもお世話になっております 🙏

3. $ docker-compose build を実行する

Gemfile を変更したので再読イメージを作り直します。

4. config/database.yml を以下のように変更する

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: xxxxxx # <- ここを変更
  host: db # <- ここを変更

あくまでローカルの開発環境構築なのでパスワードを隠したりとかはしません。本番運用とかでやっちゃダメですよ! MySQL の Root ユーザーのパスワードは docker-compose.yml で指定しています。必要に応じて書き換えて下さい。

  db:
    image: mysql:5.7
    volumes:
      - .mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: xxxxxx # <- ここ!

5. $ docker-compose up を実行する

コンテナを起動させます。

6. $ docker-compose exec spring spring rake db:create を実行する

コンテナは起動していますが、Rails で使用する DB テーブルはまだ作成されていないので作成します。 何気に spring を使っている点に注目です。

7. http://localhost:3000/ にアクセスして Rails が動いていることを確認

ここまでの操作で Rails が正しく動作しているはずです。

f:id:ryz310:20180211110115p:plain

Yay! You’re on Rails!

ポイント

bundle install が毎回走らないように工夫している

Dockerfile で WORKDIR に /tmp ディレクトリを指定しているところがポイントです。 これをせずに WORKDIR /myapp からの ADD . /myapp をやってしまうと、 Rails のコードに変更がある度に bundle install が最初から実行されてしまいます。 Gemfile と Gemfile.lock を /tmp に格納することで、これらのファイルに変更がない限り bundle install が実行されないようになっています。

WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install
WORKDIR /myapp
ADD . /myapp

参考: DockerでRails + MySQLの開発環境を構築 | EasyRamble

spring に対応

Rails で開発する上で欠かせない spring も利用できるようにしてあります。 前述の rake db:create の時にも出てきましたが、$ docker-compose exec spring spring rails console のようにして使います。 spring が 2 回出てくるところがポイントです。一つ目はコンテナのサービス名です。

毎回書くのはだるいので僕は alias にしています。fish shell 用なので良いように読み替えて下さい 🙏

# ~/.config/fish/config.fish

# docker-compose aliases
function fig
  docker-compose $argv
end

function figspring
  docker-compose exec spring spring $argv
end
# USAGE
$ figspring rails c

参考: 高速に開発できる Docker + Rails開発環境のテンプレートを作った - Qiita

MySQL データの永続化

イメージを作り直した時に MySQL のデータが失われてしまうのは辛いものがあります。 毎回テスト用のデータを一から作り直したくないので、 docker-compose.yml で以下のように指定してMySQL のデータを永続化させています。

  db:
    image: mysql:5.7
    volumes:
      - .mysql_data:/var/lib/mysql # <- これ!
    environment:
      MYSQL_ROOT_PASSWORD: xxxxxx

.mysql_data ディレクトリ以下に MySQL のデータが格納されています。リポジトリの .gitignore で無視させています。 試していませんが、参考にさせて頂いた記事によると Docker for Mac 以外の環境では問題が発生するようですのでご注意下さい。 対応方法も記事内で紹介されています 🙏

参考: docker composeでMySQLのデータ領域をローカルにマウントする | WEB EGG

まとめ

週末に何かアプリでも書こうかと思った時に、ついでに Docker で環境構築もやっちゃうか、と思い立って書きました。 そうこうしてるうちに週末の半分くらいが過ぎ去っていますが、きっと今後は捗るはず。。 😇 何度も確認していますが、もし間違っている点、不便な点などありましたらそっと教えて頂けますと幸いです 🙏 Fork も大歓迎ですし、誰かに使ってもらえると嬉しいです 😁