Ruby on Rails + MySQLのローカル開発環境をDockerで構築

はじめに

Dockerを使用して、Ruby on Railsのローカル開発環境をコンテナで構築する方法を調べてみました。
公式ドキュメントはDBがPostgreSQLであったり、Web上の記事は情報が古いものや前提となる環境が異なる場合もあり、自分なりに試行錯誤しながら検証しています。ご指摘等あればコメントいただけるとありがたいです!

前提条件

検証を行った環境は以下の通りです。

  • ホストマシン
    • macOS Monterey (12.5.1)
    • Docker Desktop 4.12.0
  • コンテナ
    • Ruby 3.1.2
    • Ruby on Rails 6.1.7
    • MySQL 8.0.31

初期ファイル準備

今回はsample-appという名前のプロジェクトディレクトリを作成します。同ディレクトリに移動して作業を行います。

$ mkdir sample-app
$ cd $_

以下のファイルをディレクトリ配下に作成します。

  • Gemfile
  • Dockerfile
  • compose.yml
  • .env

Gemfile

Gemfileには、インストールするRuby on Railsのバージョンを指定します。今回は、6.1系の最新バージョンをインストールします。

source 'https://rubygems.org'

gem 'rails', '~> 6.1.0'

Dockerfile

Dockerfileには、コンテナイメージのビルド処理内容を記載します。
開発環境ではgemやnodeモジュールの構成を変更するたびにコンテナイメージを再ビルドするのは煩雑なので、別途コンテナにマウントしたボリュームにモジュールをインストールする方針としました。ここでは必要なツールのインストールのみ行います。

FROM ruby:3.1-slim
USER root
WORKDIR /app
EXPOSE 3000
RUN \
  apt-get update -qq && \
  apt-get install -y build-essential libmysqld-dev nodejs npm git && \
  npm install -g yarn

compose.yml

コンテナは、DB(db)とアプリケーション(app)の2つを定義します。
gemとnodeモジュールは永続的なボリュームにインストールする構成としています。bundleおよびnode_modulesという名前のボリュームを定義して、それぞれコンテナのモジュールインストール先ディレクトリにマウントします。

services:
  db:
    image: mysql:8.0
    volumes:
      - mysql:/var/lib/mysql:delegated
    command: --default-authentication-plugin=mysql_native_password
    env_file: .env

  app:
    build: .
    command: >
      sh -c
      "rm -f tmp/pids/server.pid &&
      bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app:delegated
      - bundle:/usr/local/bundle:delegated
      - node_modules:/app/node_modules:delegated
    ports:
      - "3000:3000"
    depends_on:
      - db
    env_file: .env
    stdin_open: true
    tty: true

volumes:
  mysql: {}
  bundle: {}
  node_modules: {}

.env

.envでは、コンテナに渡す環境変数を定義します。MYSQL_HOSTcompose.ymlで定義したDBコンテナのサービス名を指定します。MYSQL_ROOT_PASSWORDの値はMySQLのDBパスワードです。任意の値を指定してください。
本ファイルはGit等のSCMで管理しないよう注意してください。

MYSQL_HOST=db
MYSQL_ROOT_PASSWORD=password
TZ=Asia/Tokyo

初期構築

Ruby on Railsおよび関連するモジュールのインストール、Railsアプリケーションの作成を行います。まだコンテナイメージがビルドされていない状態でこのコマンドを実行すると、最初にコンテナイメージのビルドも実行されます。
ボリューム名のsample-app_の部分は、Docker Composeでコンテナを実行するとき先頭に自動的に付与されるプレフィックスです。作成したプロジェクトディレクトリの名前に合わせて適宜変更してください。

$ docker compose run --rm \
  -v sample-app_bundle:/usr/local/bundle:delegated \
  -v sample-app_node_modules:/app/node_modules:delegated \
  -v $PWD:/app:delegated \
  app sh -c \
  'bundle install && \
  bundle exec rails new . --force -d mysql'

Railsアプリケーションの作成自体は完了しますが、処理中に以下の警告メッセージが出てきます。

You don't have net-smtp installed in your application. Please add it to your Gemfile and run bundle install

Ruby 3.1ではnet-smtpを別途インストールする必要があります。Gemfileの末尾に以下を追記します。

gem 'net-smtp'

bundle installで追加したgemをインストールします。

$ docker compose run --rm \
  -v sample-app_bundle:/usr/local/bundle:delegated \
  -v $PWD:/app:delegated \
  app bundle install

DB初期化

DBコンテナへ接続するための認証情報をRuby on Railsに設定します。config/database.ymlを編集します。passwordは、DBのパスワードを示す環境変数MYSQL_ROOT_PASSWORDを指定します。hostはデフォルトのlocalhostを削除して、接続先DBホスト名を示す環境変数MYSQL_HOSTを指定します。

(略)
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
  host: <%= ENV['MYSQL_HOST'] %>
(略)

アプリケーションで使用するDBの作成とマイグレーションを行います。

$ docker compose run --rm \
  -v sample-app_bundle:/usr/local/bundle:delegated \
  -v $PWD:/app:delegated \
  app sh -c \
    'bundle exec rails db:create && \
     bundle exec rails db:migrate'

コンテナ実行

コンテナを実行して開発用サーバを起動します。

$ docker compose up -d

以下コマンドで、appコンテナのログをリアルタイム表示できます。開発用サーバ(Puma)が起動するまでしばらく待機します。開発用サーバが起動したら、Ctrl + Cを入力してログ表示から抜けます。

$ docker compose logs app -f 
(略)
sample-app-app-1  | Puma starting in single mode...
sample-app-app-1  | * Puma version: 5.6.5 (ruby 3.1.2-p20) ("Birdie's Version")
sample-app-app-1  | *  Min threads: 5
sample-app-app-1  | *  Max threads: 5
sample-app-app-1  | *  Environment: development
sample-app-app-1  | *          PID: 8
sample-app-app-1  | * Listening on http://0.0.0.0:3000
sample-app-app-1  | Use Ctrl-C to stop

作業端末のWebブラウザでhttp://127.0.0.1:3000にアクセスし、以下の画面が表示されれば環境構築は完了です。

参考文献

クィックスタート: Compose と Rails
DockerでのRuby on Rails環境構築を一つずつ詳解する
DockerでのRails開発環境構築
rubyバージョンUP後 rails sできない
Rails6.1 + MySQL + ReactでのDocker環境を構築する
DevContainer で Ruby 開発する際に厄介な BUNDLE_APP_CONFIG

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です