Ruby on Rails + MySQLのローカル開発環境をDockerで構築
Contents
はじめに
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_HOST
はcompose.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