この記事は WESEEK Advent Calendar 2020 20日目の記事です。
はじめに
みなさんフルスタックで全部盛りな Ruby on Rails の開発環境はどうやって作っていますでしょうか?
ローカルに ruby や DB を直にインストール?
VirtualBox などを使って VM を立ててその上に必要なものをインストール?
はたまた vagrant の box のような技術を使い、諸々インストール済みの VM を使う?
やり方は色々ありますね。
この記事では VSCode と devcontainer を使って Rails の開発環境の作り方を紹介したいと思います。
VScode と devcontainer そのもにについては こちらの記事 を参照していただければと思います。
こちらで紹介したエッセンスをふんだんに使っています。
御託はいいからとにかく立ち上げたい人へ
https://github.com/haruhikonyan/rails-devcontainer/tree/rails6.1.0-and-mysql
こちらをクローンして VSCode から devcontainer を立ち上げて devcontainer 内で # rails s -b 0.0.0.0
と打てば rails new
しただけの Rails6.1 が立ち上がります。
$ git clone https://github.com/haruhikonyan/rails-devcontainer -b rails6.1.0-and-mysql rails6.1.0-and-mysql
$ cd rails6.1.0-and-mysql
$ code .
VSCode が立ち上がる、もしくは手動で VSCode から開く
こちら を参考に VSCode から devcontainer を立ち上げられる環境を構築して開く。
devcontainer が無事立ち上がったら以下実行
# rails s -b 0.0.0.0
ブラウザから localhost:3000
にアクセスすると。。。
clone して開くだけで開発がスタートできます!!
コチラ で紹介している Remote Explorer を使って CONTAINERS の Other Containers にある rails_devcontainer (rails_devcontainer_webpack_1)
を選択して Show Container Log
を出しておけば webpacker のログも見ることができ、rails でのフロントエンド開発に役立つと思います。
おまけではありますが、mysql を利用しているので、中身のデータが手軽に WebUI から見られる phpmyadmin が localhost:8000
でアクセスできるようになっています。
id:
root
password:password
このリポジトリを使う注意点
- master.key コミットしてるので注意
- サンプルとしてすぐ動かせるようにコミットしています
- あえて .gitignore のコメントアウトを外している状態
- production で使う場合は credentials.yml.enc と合わせて再作成してコミットには含めないようにしましょう
- ポート競合
ERROR: for rails Cannot start service rails: driver failed programming external connectivity on endpoint rails610-and-mysql_devcontainer_rails_1 (3ae06361400910dfa02e66e6f05319a1323da5fe5be0086f62783aa7cd51db81): Bind for 0.0.0.0:3000 failed: port is already allocated
こんなエラーが出てきた場合
書いてあるとおりですが、すでに 3000 番ポートを別の何かが使用していないでしょうか?
3000 番ポートは非常に被りやすく、いろいろなものを立ち上げてるとすぐに競合してしまいます。とはいえデフォルトがそうなだけですぐ変えることができるので変更してみましょう。
ココ の値を下記のように変えるだけです。
services:
rails: &app
build:
context: .
dockerfile: Dockerfile
working_dir: /app
ports:
- 8080:3000 # 前半を任意の値に変更
この例だっとホスト側の 8080 番ポートをコンテナの 3000 番ポートにフォワードするっという設定になります。
同じようにおまけの phpmyadmin は 8000 番ポートを利用している のでもし被ってしまうようであれば同様に修正しましょう。
解説
Dockerfile
- ベースイメージ
devcontainer の解説記事 では microsoft が用意してくれた専用の image を使うと良い と書き、ruby の image も用意はされているのですが ruby のバージョンが細かく指定できなかったため今回は採用を見送ってます。
2.7系とざっくりとは指定ができるのでバージョンを細かく指定する必要が無いとかであればそちらを採用してもよいかもしれません。その場合 node はすでに image に入っている ため下記の node に関連するもののインストールは不要だと思います。 - node インストール
rails6 系ではそのままrails new
すると標準で webpacker が付いてくるため、実行環境に node が必要です。
そのために FROM で node image を指定し、そこから node の実行ファイルを COPY してきています。 - npm インストール
npm も必要なのでこちらは そのままインストールしています。 - bundler と yarn のバージョン指定
ruby イメージと node イメージには標準で bunder と yarn がインストールされていますが、バージョンによって挙動が違ったりするので、明示的にバージョンを指定してインストール するようにしています。
docker-compose.yml
rails
-
environment
- 日本対応
environment でタイムゾーンと言語を設定してます。
特に言語の設定をしないとrails c
で日本語が打てなかったり何かと不便だったりします。 -
DB に関する環境変数
database.yml と合わせて確認してほしいのですが、全環境を環境変数で設定できるようにして、environment を意識するだけで良いようにしています。もちろん好みはあると思うので本番は別 key にしたり config gem を使うようにしたりしても良いかもしれません。 -
WEBPACKER_DEV_SERVER_HOST
こちら webpack-dev-server を rails の実行しているホスト以外で実行する場合の連携を制御できる環境変数であり、後述する webpack を別のコンテナで起動し、1コンテナ1プロセス を実現しています。
- 日本対応
-
env_file
.env ファイルを指定しており、独自の環境変数が設定できます。.gitignore で除外設定しているのでコミットはされないので、外部サービスのアクセストークンなどはこちらに設定するのが良いと思います。この設定を行うとファイルが存在しないと起動時にエラーが出るので注意です。後述する initializeCommand にて自動生成されるのでこのリポジトリを使う分にはエラーは気にする必要はないはずです。 -
volumes
基本的には コチラ で紹介してる用法を使っています。-
リポジトリのディレクトリ
大元 -
Rails が作成する動的ファイルのディレクトリ
コミットに含めなくても良いかつ、保持する必要もないディレクトリを volume にしています。もしかしたら logs 以外にもあるかも? -
依存ライブラリが格納されるディレクトリ
bundle install
でダウンロードされる ruby のライブラリとyarn install
でダウンロードされる node のライブラリを docker の named volume で保持します。
-
リポジトリのディレクトリ
webpack
- webpack-dev-server 専用コンテナ
yaml アンカー で rails の設定をまるまる持っておき、流用 しています。 - weboack-dev-server 起動コマンド
devcontainer として bash を使う rails コンテナとは違い command を定義し、自動的に webpack-dev-server が起動するようにしています。 - auto reload 用ポート設定
webpack-dev-server では js ファイルを監視してくれてファイルが save されると自動的にブラウザを更新してくれます。そのための ポートの設定 をしています。
db
- 認証設定変更
mysql8 系から認証の設定が変わり、そのままだと rails からのアクセスができないので 元に戻すコマンド を設定しています。 -
phpmyadmin
phpmyadmin の公式コンテナの デフォルトの設定で接続先の DB ホスト名は db なので明示的な設定は必要ありません。
devcontainer.json
-
postCreateCommand
見ての通りコンテナ作成時に Rails 起動に必要なことをすべてやっています。 -
initializeCommand
ぱっと見良くわからないコマンドなのですがやっていることは単純でコメントにもあるとおり、.devcontainer/.env
が無ければ、.devcontainer/.env.sample
をコピーしています。
docker-compose.yml で env_file を設定しているので起動時のエラー防止です。
カスタマイズ方法
自分で rails new したい
master リポジトリには rails new できる状態に各所コメントアウトした状態をコミットしてます。
- リポジトリクローン
$ git clone https://github.com/haruhikonyan/rails-devcontainer -b master
$ cd rails-devcontainer
$ code .
- DB のコンテナ設定
使いたい DB のコンテナを設定します。
mysql か postgrsql であれば コチラ のどちらかのコメントアウトを外せば設定完了します。
volume のコメントアウトも忘れずに - rails new
devcontainer を立ち上げ、rails new
を実行します。
$ gem install rails
$ rails new .
-
DB の gem 追加
デフォルトの sqlite ならそのままで良いと思います。
mysql なら こんな具合に -
database.yml 修正
デフォルトだと sqlite の設定になっているかと思うので、それ以外の DB を選択した場合は設定変更が必要です。
環境変数を利用する場合は docker-compose.yml なども一緒に変更しましょう。 -
devcontainer 各種設定
どれも必須ではありませんが好みに合わせて諸々自動起動するように devcontainer の設定を整えていきましょう。-
webpack 用コンテナ の設定
rails コンテナの environment の設定も忘れずに。 - コンテナ作成時の実行コマンド の設定
-
webpack 用コンテナ の設定
-
devcontainer rebuild
上記で設定した項目反映させるために devcontainer を rebuild します。
左下の><
みたいな ボタンからRemote - Containers Rebuild container
を選択すれば全てのコンテナが再作成されます。 -
起動
あとは起動するだけです!
コンテナ作成時の実行コマンド をすべて設定していれば依存ライブラリのダウンロードと DB の作成、マイグレーションまで自動で終わるはずです。
設定してない場合はコンソールから手で実行しましょう。
# rails s -b 0.0.0.0
既存の Rails プロジェクトで使いたい
基本的には上記の rails new
する場合と同じで、rails new
はせず、既存リポジトリに .devcontainer ディレクトリとファイル一式 を作成し、devcontainer を起動するだけです。
※この記事の内容は一部 WESEEK Tips wiki に投稿された記事の転載です。
Tips wiki では、IT企業の技術的な情報やプロジェクトの情報を公開可能な範囲で公開してます。