どうも、バックエンドエンジニアのサトウリョウスケです ✌︎('ω')✌︎
僕が所属している ソーシャル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 さんの週刊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 が正しく動作しているはずです。
ポイント
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 も大歓迎ですし、誰かに使ってもらえると嬉しいです 😁