h1k Blog

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:

Dockerfiledocker-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 でアクセスします。

以下の画面が表示されたら、完了です 🎉

Rails Welcome Page

参考