Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails 6: Docker/docker-compose/dipで`rails new`力を取り戻す

こんにちは、hachi8833です。いつからrails newが面倒になってきたのでしょう。

私の場合rails newする機会が多いので、Evil Martians流のDocker開発環境構築の次の段階として、自分用にDocker環境ビルドとrails newのためのしくみを作りました。

Rails 6のDocker開発環境構築をEvil Martians流にやってみた

概要

やりたいこと

  • Dockerで楽にrails newできるようにする
  • Rails 6 + Ruby 2.7以降のWebpackerを前提とする開発環境をDocker上に構築する
    • Evil Martians流のDocker開発環境構築に倣う
  • 無駄にカスタマイズしない
    • DockerでRailsとWebpackerを動かすために必要な最小限のカスタマイズに留める
  • 今後RailsやRubyやNodeやYarnがアップグレードされてもdocker-compose.ymlのバージョン番号を調整するだけで使えるようにする

前提とする環境

  • macOS(Docker for Mac)
  • Linux(Ubuntuなど)

なおWindows環境では試していません。

必要なもの

  • Docker
  • Docker Compose
  • dip(以下の記事をどうぞ)

docker-composeを便利にするツール「dip」を使ってみた

リポジトリ

手順

1. 準備

  • リポジトリをgit cloneし、ディレクトリ名を適宜変更する
    • ディレクトリ名がDockerコンテナ名に使われる
    • .gitを削除して自分用にgit-flow initなどする
  • 必要に応じてdocker-compose.ymlのアプリ名やバージョンを修正する。
# PostgreSQL版の場合
x-var: &APP_IMAGE_TAG
  "my_app:1.0.0"
x-var: &RUBY_VERSION
  "2.7.0-slim-buster"
x-var: &PG_MAJOR
  12
x-var: &POSTGRES
  "postgres:12"
x-var: &NODE_MAJOR
  12
x-var: &YARN_VERSION
  1.21.1

なお、Ruby 2.7にはbundlerが同梱されているので、別途インストールはしない前提にしました。

  • 必要に応じてdip.ymlのrails new行にオプションを追加しておく。
  - dip rails new . -d postgresql --webpacker --skip-listen --skip-git

2. ビルド

ここまで行えば、後はプロジェクトディレクトリで以下を実行するだけです。

  • SQLite3版の場合
dip provision
  • PostgreSQL版の場合
dip provision
dip rails db:prepare
dip rails db:prepare RAILS_ENV=test # 必要なら

PostgreSQL版だとdip provisionの中でrails db:prepareを呼んだときにPostgreSQLへの接続に失敗する問題が解決できなかったので、db:prepareは手動で実行することにしました。

3. 起動

dip rails sしてhttp://localhost:3000をブラウザで開けばいつものWelcome画面が表示されます。

scaffoldなどで作ったページを開くとWebpackerが動き出します。

[Webpacker] Compiling...
[Webpacker] Compiled all packs in /app/public/packs
[Webpacker] Hash: 32e57f147dbdcbbf0c82
Version: webpack 4.41.6
Time: 3765ms
Built at: 02/27/2020 1:51:09 AM
                                     Asset       Size       Chunks                         Chunk Names
    js/application-bbe9c4a129ab949e0636.js    124 KiB  application  [emitted] [immutable]  application
js/application-bbe9c4a129ab949e0636.js.map    139 KiB  application  [emitted] [dev]        application
                             manifest.json  364 bytes               [emitted]
Entrypoint application = js/application-bbe9c4a129ab949e0636.js js/application-bbe9c4a129ab949e0636.js.map
[./app/javascript/channels sync recursive _channel\.js$] ./app/javascript/channels sync _channel\.js$ 160 bytes {application} [built]
[./app/javascript/channels/index.js] 211 bytes {application} [built]
[./app/javascript/packs/application.js] 749 bytes {application} [built]
[./node_modules/webpack/buildin/module.js] (webpack)/buildin/module.js 552 bytes {application} [built]
    + 3 hidden modules

Completed 200 OK in 7683ms (Views: 7664.0ms | ActiveRecord: 1.8ms | Allocations: 24008)

Docker向けにチューニングした点

基本的にEvil Martians流にしていますが、以下をカスタマイズしてあります。

1. listen gemをインストールしない(Mac向け)

listen gemはRailsでデフォルトでインストールされます。しかし、Docker for Macでこのgemがあると、ソースを更新してブラウザをリロードしても、Docker環境で起動したサーバーで、Dockerボリュームの変更が反映されないという既知の問題がありました。

そのため、--skip-listenを指定してlisten gemをインストールしないようにしています。listenがあっても大丈夫になったら--skip-listenを外すつもりです。

2. node_modules/ディレクトリをgitignoreする

rails newで生成される.gitignoreには、node_modules/やpublic/packs/、public/packs-testといったディレクトリをignoreする設定が含まれていません。

そのため、dipのrails new--skip-gitを追加してgit関連ファイルを生成しないようにしています。

スクリプトで.gitignoreに追加する手もありますが、定番のignoreエントリも含めてキットに.gitignoreを最初から入れておくことにしました。

3. node version manager ‘n’を追加

ビルド時点で最新のNode.jsをインストールし、アップグレードを行いやすくするために、nというバージョンマネージャをインストールする設定をDockerfileに追加しました。dip shでログインし、n ltsなどを実行することでNode.jsを最新にできます。

おまけ

なお、Evil Martians流ではyarnをnpmではインストールせず、curlとaptでインストールしていることに気が付きました。実際、Yarnの公式情報↓にはyarnをnpmでインストールすべきでないと書かれています。

参考: インストール | Yarn

関連記事

Fullstaq Rubyの第一印象とDocker/Kubenetes Rubyアプリとの統合(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。