📝
Docker × Rails × rbenv環境でrailsコマンドが見つからない理由と対処法
はじめに
RailsやRubyプロジェクトをDocker+rbenvで運用する際、
「railsコマンドが見つからない」「bundle exec railsが動かない」といったトラブルに悩まされたことはありませんか?
この記事では、docker-compose.ymlのcommand:設定の影響や、正しいコンソール起動方法をまとめます。
1. docker-compose.ymlのcommand:設定の正体
例えば、下記のようなcommand:が指定されていることがあります。
command: /bin/bash -c "source ~/.bashrc && rm -f /<サーバー名>/tmp/pids/server.pid && rbenv exec bundle _2.3.5_ exec rails s -p 3000 -b '0.0.0.0' -e development"
それぞれの意味を整理します。
-
/bin/bash -c "..."
→ bashシェルを起動し、複数コマンドをまとめて実行 -
source ~/.bashrc
→ シェルの初期化ファイルを読み込み(ここでrbenvの初期化もされる) -
rm -f /<サーバー名>/tmp/pids/server.pid
→ RailsのサーバーPIDファイルを削除(再起動エラー防止) -
rbenv exec bundle _2.3.5_ exec rails s ...
→ rbenv経由でbundle/railsを実行(指定バージョンで起動)
2. これが引き起こす落とし穴
重要なポイント:
このcommand:の中でrbenvやPATHの初期化がされているのは「bash -c 'source ~/.bashrc' ...」内だけです。
つまり、通常のdocker compose execでコンテナに入った場合には、rbenvの環境やPATHが自動で引き継がれません。
そのため…
-
docker compose exec web rails console
→railsが見つからないエラー -
docker compose exec web bundle exec rails ...
→ PATHエラーやshim経由でのエラー発生
なぜ?
- rbenvや各種PATHの初期化がbashrcを読み込んだ時だけ有効だからです。
3. 対策方法
方法1:シェルに入って自分で初期化
docker compose exec web /bin/bash
source ~/.bashrc
# または
eval "$(rbenv init -)"
rails -v
bundle exec rails console
方法2:ワンライナーで初期化+コマンド
docker compose exec web /bin/bash -c "source ~/.bashrc && bundle exec rails console"
方法3:entrypoint.shで自動初期化
Dockerfileやdocker-compose.ymlで、
entrypoint.sh を使い、常に初期化+実行するように設計すると、
開発者ごとに「初期化忘れ」の事故を防げます。
#!/bin/bash
source ~/.bashrc
exec "$@"
4. まとめ(初心者向け)
-
command:でsource ~/.bashrcしている場合、普通にexecしても同じ環境にはならない - execでコンテナに入った後は、必ず手動で
source ~/.bashrcやeval "$(rbenv init -)"を実行 - その後に
rails consoleやbundle exec rails sなど必要なコマンドを打つ
公式リファレンス
rbenv README: Shell Initialization
Docker公式: ENTRYPOINT と CMD の使い分け
おすすめチェックコマンド
docker compose exec web /bin/bash
source ~/.bashrc
rails -v
bundle exec rails console
Discussion