📝

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 ~/.bashrceval "$(rbenv init -)"を実行
  • その後にrails consolebundle exec rails sなど必要なコマンドを打つ

公式リファレンス

rbenv README: Shell Initialization
https://github.com/rbenv/rbenv#installation

Docker公式: ENTRYPOINT と CMD の使い分け
https://docs.docker.com/engine/reference/builder/#entrypoint


おすすめチェックコマンド

docker compose exec web /bin/bash
source ~/.bashrc
rails -v
bundle exec rails console

Discussion