はじめに
Ruby on Railsは強力なWebアプリケーションフレームワークですが、開発環境の構築には時間がかかることがあります。特に、チーム全体で一貫した環境を維持することは困難な場合があります。
Dockerを使用することで、Ruby on Railsの開発環境を簡単に構築し、チーム全体で一貫性のある環境を維持することができます。
本記事では、Dockerを使ってRuby on Railsの開発環境を構築する方法を解説します。初心者の方でも理解しやすいよう、各ステップの詳細な説明と、そのステップが必要な理由を併せて紹介していきます。
Dockerのインストール
Docker Desktopをインストールします。
Dockerを使用するときはDocker Desktopを常に起動しておく必要があります。
Docker環境構築
ディレクトリの作成
プロジェクトのディレクトリを作成します。
% cd ~/Products
% mkdir rails-on-docker
% cd rails-on-docker
設定ファイルの作成
Dockerfile
Docker
ファイルを作成し、以下を記述します。
Dockerfile
FROM ruby:3.1.2
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
このファイルは、Ruby on Railsアプリケーションのための開発環境を構築しています。各行の意味は以下の通りです。
FROM ruby:3.1.2
- Ruby 3.1.2がインストールされた公式のDockerイメージを使用
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
- Node.jsとPostgreSQLクライアントをインストール
- Node.jsはRailsのアセットパイプラインに必要で、PostgreSQLクライアントはデータベース接続に使用
WORKDIR /myapp
- コンテナ内の作業ディレクトリを /myapp に設定
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
- ホストマシンからGemfileとGemfile.lockをコンテナにコピー
RUN bundle install
- Gemfileに記載された依存関係をインストール
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
- エントリーポイントスクリプトをコンテナにコピーし、実行可能にする
ENTRYPOINT ["entrypoint.sh"]
- コンテナ起動時に実行されるコマンドを指定
EXPOSE 3000
- コンテナがリッスンするポートを指定(Railsのデフォルトポート)
CMD ["rails", "server", "-b", "0.0.0.0"]
- コンテナ起動時のデフォルトコマンドを指定
- Railsサーバーを起動し、全てのインターフェースでリッスンするよう設定
Gemfile
Gemfile
を作成し、以下を記述します。
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>7'
Gemfile.lock
Gemfile.lock
を作成します。中身は空で大丈夫です。
docker-compose.yml
docker-compose.yml
を作成し、以下を記述します。
docker-compose.yml
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
このファイルは、Ruby on Railsアプリケーション(web
)とそのデータベース(PostgreSQL)(db
)の開発環境を定義しています。
このファイルを使用すると、docker-compose up
コマンドで簡単に開発環境を起動できます。PostgreSQLデータベースとRailsアプリケーションが連携して動作し、コードの変更がすぐに反映される開発に適した環境が構築されます。
db
サービスimage: postgres
- 公式のPostgreSQLイメージを使用します。
volumes
- ホストマシンの
./tmp/db
ディレクトリをコンテナの/var/lib/postgresql/data
にマウント - これにより、データベースのデータが永続化される
- ホストマシンの
environment
- データベースのrootパスワードを 'password' に設定します。
web
サービスbuild
- カレントディレクトリにあるDockerfileを使用してイメージをビルド
command
- コンテナ起動時に実行されるコマンドを指定
rm -f tmp/pids/server.pid
- 古いサーバーPIDファイルを削除(クリーンな起動のため)
bundle exec rails s -p 3000 -b '0.0.0.0'
- Railsサーバーを起動
volumes
- カレントディレクトリ(.)をコンテナの /myapp にマウント
- これにより、ホストマシンでのコード変更がコンテナにすぐに反映される
ports
- ホストの3000ポートをコンテナの3000ポートにマッピング
depends_on
- このサービスが
db
サービスに依存していることを指定(db
サービスが先に起動される)
- このサービスが
entrypoint.sh
entrypoint.sh
を作成し、以下を記述します。
entrypoint.sh
#!/bin/bash
set -e
rm -f /myapp/tmp/pids/server.pid
exec "$@"
このスクリプトは、Dockerコンテナが起動する際に実行される重要なスクリプトです。
- 古いサーバープロセスIDファイルを確実に削除し、クリーンな状態でRailsサーバーを起動できるようにする
- Dockerfileで指定されたメインプロセス(Railsサーバー)を適切に起動する
これにより、コンテナの再起動時や開発中の繰り返しの起動時に、クリーンで一貫した環境でアプリケーションを実行できます。
#!/bin/bash
- このスクリプトがbashシェルで実行されることを指定
set -e
- エラーが発生した場合にスクリプトの実行を即座に停止するよう設定
- これにより、エラーの早期検出と対応が可能になる
rm -f /myapp/tmp/pids/server.pid
- Railsアプリケーションの一時ファイル(server.pid)を強制的に削除
- このファイルは前回の実行時に残っている可能性があり、新しいサーバープロセスの起動を妨げる可能性がある
-f
オプションは、ファイルが存在しない場合でもエラーを発生させずに続行することを意味する
exec "$@"
- Dockerfileで指定されたCMDコマンド(
rails server -b 0.0.0.0
)を実行 $@
は、このスクリプトに渡されたすべての引数を表すexec
コマンドは、現在のプロセスを指定されたコマンドで置き換える- これにより、Railsサーバーがコンテナのメインプロセス(PID 1)として実行される
- Dockerfileで指定されたCMDコマンド(
Dockerコンテナー起動
以下のコマンドを実行して、Docker Composeを使用して新しいRuby on Railsプロジェクトを作成します。
% docker compose run --no-deps web rails new . --force --database=postgresql
docker compose run
- Docker Composeで定義されたサービスを一時的に実行
--no-deps
- 依存サービス(
db
サービス)を起動せずに実行
- 依存サービス(
web
- docker-compose.ymlで定義された
web
サービスを使用
- docker-compose.ymlで定義された
rails new .
- 現在のディレクトリ(.)に新しいRailsプロジェクトを作成
--force
- 既存のファイルがある場合、それらを上書きする
--database=postgresql
- デフォルトのデータベースとしてPostgreSQLを指定
Dockerコンテナーを再度ビルドします。
% docker compose build
Railsはデフォルトでlocalhost上でデータベースが動作していることを想定しているので、代わりにdbコンテナを指定する必要があります。そのため、代わりにdbコンテナのデータベースを使用するよう変更します。
また、データベースとユーザ名を、postgresイメージで設定されているデフォルトに合わせて変更します。
config/database.yml
を以下のように修正します。
config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db
username: postgres
password: password
pool: 5
development:
<<: *default
database: myapp_development
test:
<<: *default
database: myapp_test
以下のコマンドを実行して、Dockerコンテナーを起動します。
% docker compose up
Dockerコンテナーをバックグラウンドで起動したい場合、-d
オプションをつけます。
% docker compose up -d
バックグラウンドで起動したDockerコンテナーを停止するには以下のコマンドを実行します。
% docker compose down
最後に、以下のコマンドを実行してデータベースを作成します(別のターミナルで実行)。
% docker compose run web rake db:create
Docker環境のデバッグ方法
Dockerで構築したRailsアプリケーションをpryを使ってデバッグする方法について説明します。
Gemfileの設定
Gemfile
に以下を追記します。
Gemfile
group :development, :test do
gem 'pry-rails'
gem 'pry-byebug'
end
次に、以下のコマンドを実行します。
% docker-compose run web bundle install
Dockerfileの設定
Dockerfileに以下の行を追加して、pryが正しく動作するように設定します。
Dockerfile
ENV TERM xterm-256color
docker-compose.ymlの設定
docker-compose.ymlファイルのwebサービスに以下の設定を追加します。
docker-compose.yml
web:
tty: true
stdin_open: true
コードにブレークポイントを設定
デバッグしたい箇所にbinding.pry
を追加します。
アプリケーションの起動
以下のコマンドでアプリケーションを起動します。
% docker-compose up
デバッグセッションの開始
以下のコマンドを実行してコンテナー名を確認します。
% docker ps
# => 右端の NAMES を確認
続いてコンテナーにアタッチします。
% docker attach CONTAINER-NAME
するとデバッグセッションが始まるので、変数の確認やコード実行してデバッグを行います。
デバッグの終了
デバッグセッションを終了するには、pryプロンプトで [Ctrl+P, Ctrl+Q] を入力します。[Ctrl+C] を入力するとコンテナーが停止してしまうので注意してください。
まとめ
Dockerを使用してRuby on Railsの開発環境を構築する方法を解説しました。Dockerを使うことで以下のような利点を得られます。
- 環境の一貫性:チーム全員が同じ環境で開発できる
- 簡単なセットアップ:新しいメンバーも簡単に環境を構築できる
- 移植性:異なるマシンや環境でも同じ設定で動作する
- 分離:他のプロジェクトや、システムの他の部分に影響を与えない
Dockerを使った開発環境の構築は、最初は少し手間がかかるかもしれません。しかし、一度セットアップすれば、その後の開発プロセスがスムーズになり、チームの生産性が向上します。
本記事を参考にして、Dockerを使用してRuby on Railsの開発環境を構築していただければと思います。