こんにちは、hachi8833です。いつからrails new
が面倒になってきたのでしょう。
小さめのアプリケーションをスクラッチで書くことをrails new力と呼んでるけど、保守や負債解消や機能追加だけやってると、めちゃくちゃこの力が衰える。くだらないアプリをいっぱい作らないとなーって思った。
— 鶏胸肉 (@yoshi_hirano) October 27, 2019
rails new力が少しずつ返ってきた。これ定期的にやらないとだめだな。
— 鶏胸肉 (@yoshi_hirano) October 26, 2019
私の場合rails new
する機会が多いので、Evil Martians流のDocker開発環境構築の次の段階として、自分用にDocker環境ビルドとrails new
のためのしくみを作りました。
概要
やりたいこと
- 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(以下の記事をどうぞ)
リポジトリ
- SQLite3版: hachi8833/rails6_docker_quicksetup_sqlite3: Generic Docker configs for Rails 6 + Webpacker + SQLite3
-
PostgreSQL版: hachi8833/rails6_docker_quicksetup_postgres: Generic Docker configs for Rails 6 + Webpacker + PostgreSQL
手順
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