Docker Compose で Rails 開発環境を構築
はじめに
本記事では Docker Compose を使って Rails アプリの開発環境を構築する手順を紹介します。
Docker および Docker Compose を使うことで
- 作業PC(開発環境)の汚染を防止できる
- コンテナとして分離することで、インストールしたライブラリやツールが、他のアプリケーションに影響を与えない
- 環境の再現性が高い
- コンテナとして定義することで、開発環境を再現するために必要なライブラリやツールなどを含めた完全な環境を簡単に構築できる
- 他の開発者と環境を共有する場合にも、Dockerfile や docker-compose.yml ファイルなどを共有するだけで環境の再現が可能
- Amazon ECS など本番環境もコンテナで運用している場合は、Dockerfile を流用できる
といった利点があります。
前提
Ruby と Rails は記事執筆時の最新 version、データベースは PostgreSQL を今回利用します。
また最近フロントエンドは別アプリケーション(React / Next.js など)で構築することが多いため、Rails は API モードとします。
プロジェクトの定義
まずは作業ディレクトリを作成します。
$ mkdir rails-sandbox
つぎに、作業ディレクトリでアプリのビルドに必要となる 4 つのファイルを作ります。
$ touch Gemfile Gemfile.lock Dockerfile docker-compose.yml
$ tree
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
└── docker-compose.yml
1 directory, 4 files
Gemfile、Gemfile.lock
source 'https://rubygems.org'
gem 'rails', '7.0.8'
Gemfile
はビルド時に Rails をインストールするため作成します。 rails new
を行ったタイミングでこのファイルは書き換わります。
なお、Gemfile.lock
は空で大丈夫です。
Dockerfile、docker-compose.yml
FROM ruby:3.2.2
# YJIT を有効化
ENV RUBY_YJIT_ENABLE=1
# 必要なライブラリを追加
RUN apt-get update -qq \
&& apt-get install -y build-essential libpq-dev \
&& apt-get upgrade -y \
&& apt-get autoremove -y \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man
WORKDIR /myapp
COPY Gemfile Gemfile.lock ./
RUN bundle install
version: '3'
services:
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
ports:
- 3000:3000
depends_on:
- db
volumes: # ホストのカレントディレクトリ(.)とイメージ内の/myappディレクトリを同期
- .:/myapp/
# ブレークポイントを挟んだデバックのため
tty: true
stdin_open: true
db:
image: postgres:16
ports:
- 5432:5432
environment:
- POSTGRES_PASSWORD=mypassword
volumes: # データベースの永続化のため
- pg_data:/var/lib/postgresql/data
volumes:
pg_data:
Dockerfile
と docker-compose.yml
を上記のような形で作成します。
docker-compose.yml
では、Rails アプリとデータベース(PostgreSQL) 2つのコンテナを定義しています。
プロジェクトのビルド
ここまでの 4 つのファイルを使って docker-compose run
を実行し、Rails アプリの雛形を生成します。
--api
: API モードを指定--database=postgresql
: データベースを PostgreSQL に--skip-test
: テストは RSpec を利用するため
$ docker-compose run web rails new . --force --api --database=postgresql --skip-test
雛形の生成が完了したら、Gemfile が置き換わったので再度 build をします。
$ docker-compose build
データベース接続設定
database.yml の host / username / password を以下のように設定します。
環境ごとに値が変わることが想定されるので、環境変数として設定するのが良いと思います。開発環境用の値をデフォルト値とします。
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
host: <%= ENV.fetch("POSTGRES_HOST", "db")%>
username: <%= ENV.fetch("POSTGRES_USERNAME", "postgres")%>
password: <%= ENV.fetch("POSTGRES_PASSWORD", "mypassword")%>
development:
<<: *default
database: myapp_development
...
つぎに開発環境のデータベースを作成します。
$ docker-compose run --rm web rails db:create
Creating rails-sandbox_web_run ... done
Created database 'myapp_development'
Created database 'myapp_test'
サーバーの起動
docker-compose up
でサーバーを起動し、ブラウザで localhost:3000 でアクセスします。
以下の画面が表示されたら、完了です 🎉
