はじめに
現在、Webアプリを開発中です。AWSへのデプロイ、CI/CD対応、そして開発環境のDocker対応まで一区切りついたので、技術メモとして残します。
今回は Dockerfile.dev で bin/dev を起動しようとしたらハマった話です。
問題
Dockerfile.dev の以下のCMDでエラーが発生しました。
CMD ["bash", "-lc", "rm -f tmp/pids/server.pid && bin/dev"]
やりたいことは rails s ではなく、bin/dev での起動です。
原因
- bush -lc を使ったことで PATH が上書きされ、 /usr/local/bundle/bin が見えなくなった
- foreman を Dockerfileで gem install しただけ => bundle 管理外
- その結果 bundle exec foreman は「Gemfileに無い」と怒られる
- bin/dev は foreman の存在を前提にしてるので失敗
追記
後述の解決方法の場合、Docker側で問題なく起動しますが、ローカル側で問題が発生したので、記事を追加しました。
解決方法
2パターン試してみました。どちらも正常に動作しましたが、チーム開発を想定するならパターンB。
パターンA
CMDを直接 foreman に置き換える。
CMD ["bash", "-c", "rm -f tmp/pids/server.pid && foreman start -f Procfile.dev"]
パターンB
Gemfileに foreman を追加して bundle exec で呼ぶ。
group :development do
gem 'foreman'
end
CMD ["bash", "-c", "rm -f tmp/pids/server.pid && bundle exec foreman start -f Procfile.dev"]
動作確認
Procfile.dev に web と css を定義。
web: bin/rails server -b 0.0.0.0 -p 3000
css: ./bin/tailwindcss -i app/assets/stylesheets/application.tailwind.css -o app/assets/builds/application.css --watch
foreman が Rails と Tailwind を並列起動して無事に動作しました。
学び
- Docker環境では「PATHの扱い」と「Gemfile外のgem利用」に注意
- 依存をGemfileに明示しておくと再現性が高く、チーム開発でも安心
その他
すぐ忘れるのでメモ📝
docker compose -f compose.dev.yml down --remove-orphans
docker compose -f compose.dev.yml build --no-cache web
docker compose -f compose.dev.yml up -d
docker compose -f compose.dev.yml logs -f web