【Docker】MySQL+Rails7の開発環境を準備する
Railsでの開発環境をDockerで準備していく手順をまとめました。
本記事では、開発用の環境構築を目標とし、本番用の環境構築については、深くは触れていません。
実行環境(OSや各種バージョンなど)
今回、試した環境は、以下のとおりです。
OS | Windows11 |
Docker Desktop | v4.22.1 |
MySQL | 8.0 |
Ruby | 3.2.2 |
Rails | 7.1.3 |
手順
Docker Desktopがインストール済み・起動済みの状態で、以降の手順に沿って、開発環境を準備していきます。
各種ファイルの準備
以下のようなフォルダ構成で、各ファイルを準備します。
rails-app/(作業フォルダ)
├ .env
├ docker-compose.yml
├ Dockerfile
├ entrypoint.sh
├ Gemfile
└ Gemfile.lock
.env
docker-compose.yml
や、プロジェクト作成後に生成される config/database.yml
で参照する環境変数を定義しておきます。
MYSQL_ROOT_USER=root
MYSQL_ROOT_PASSWORD=password
MYSQL_DB=db_docker_rails7
MYSQL_USER=user
MYSQL_PASSWORD=password
RAILS_HOST=0.0.0.0
RAILS_PORT=3000
Dockerfile
Dockerイメージのビルド手順を記述します。
FROM ruby:3.2.2
# 環境変数
ENV APP_HOME /app
# 作業ディレクトリ指定
WORKDIR ${APP_HOME}
# コンテナがリッスンするポートを指定
EXPOSE 3000
# ローカルのGemfileをコンテナ内にコピー
COPY Gemfile ${APP_HOME}/Gemfile
COPY Gemfile.lock ${APP_HOME}/Gemfile.lock
# パッケージリストを最新にする
RUN apt-get update
# Gemをアップデート
RUN bundle install
# コンテナ起動時に実行させるスクリプト
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
# コンテナ実行時にRailsサーバーを起動
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
Dockerコンテナを管理する設定を記述します。
${MYSQL_ROOT_PASSWORD}
など、${}で囲まれた部分で、先ほど定義した環境変数の値を使用しています。
version: "3"
services:
# MySQLの設定
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} # 環境変数(.env)から参照
MYSQL_DATABASE: ${MYSQL_DB} # 環境変数(.env)から参照
MYSQL_USER: ${MYSQL_USER} # 環境変数(.env)から参照
MYSQL_PASSWORD: ${MYSQL_PASSWORD} # 環境変数(.env)から参照
TZ: "Asia/Tokyo"
volumes:
# db-dataというボリュームをコンテナ内の/var/lib/mysqlにマウントする
- db-data:/var/lib/mysql
ports:
- "3306:3306"
# Railsの設定
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
# カレントディレクトリの内容をコンテナ内の/appにマウントする
- .:/app
env_file:
- .env
ports:
- ${RAILS_PORT}:3000 # 環境変数(.env)から参照
# コンテナを起動したままにする
tty: true
# 標準入出力とエラー出力をコンテナに結び付ける設定
stdin_open: true
# dbサービスを起動してからwebサービスを起動させる
depends_on:
- db
volumes:
db-data:
entrypoint.sh
初回起動時のみに実行させたい内容を記述します。
server.pidファイルを消す内容を記述しています。
#!/bin/bash
set -e
rm -f /app/tmp/pids/server.pid
exec "$@"
Gemfile
RailsのGemを記述します。
バージョンを指定しておくこともできます。
今回は、最新の安定版にしたいので、バージョン指定はしません。
source 'https://rubygems.org'
gem 'rails'
Gemfile.lock
空のままでOKです。
bundle installコマンドで、中身が生成されます。
Dockerfileに以下の記述があるので、空でもファイルを準備しておく必要があります。
COPY Gemfile.lock ${APP_HOME}/Gemfile.lock
Railsプロジェクトの作成
以下のコマンドで、Railsプロジェクトを作成します。
docker-compose run --rm web bundle exec rails new . -f -d mysql --api -T
- -f:ファイルが存在する場合、上書きして作成する
- -d mysql:データベースをMySQLに指定
- –api:APIモード
- -T:テストフレームワークをスキップ
開発環境用と本番環境用とでファイルを分ける
rails new
でDockerfileが上書きされます。
生成されたDockerfileの中身を見ていくと、以下の記述があり、RAILS_ENV="production"
というところから、本番環境用のDockerfileであることがわかります。
ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development"
開発用の環境を用意したいので、本番環境用のものとファイルを分けます。
Dockerfileをコピーして、Dockerfile.dev
とDockerfile.prod
という2つのファイルを作成します。
(Dockerfileは削除してOKです)
Dockerfile.devには、上書きされる前の内容を記述します。
FROM ruby:3.2.2
# 環境変数
ENV APP_HOME /app
# 作業ディレクトリ指定
WORKDIR ${APP_HOME}
# コンテナがリッスンするポートを指定
EXPOSE 3000
# ローカルのGemfileをコンテナ内にコピー
COPY Gemfile ${APP_HOME}/Gemfile
COPY Gemfile.lock ${APP_HOME}/Gemfile.lock
# パッケージリストを最新にする
RUN apt-get update
# Gemをアップデート
RUN bundle install
# コンテナ起動時に実行させるスクリプト
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
# コンテナ実行時にRailsサーバーを起動
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
Dockerfile.prodは、Dockerfileの内容そのままでOKです。
docker-compose.ymlもdocker-compose-dev.yml
とdocker-compose-prod.yml
に分けます。
それぞれ、webサービスのbuild項目の箇所を変更します。
docker-compose-dev.yml
(省略)
web:
build:
context: .
dockerfile: "Dockerfile.dev"
(省略)
docker-compose-prod.yml
(省略)
web:
build:
context: .
dockerfile: "Dockerfile.prod"
(省略)
dotenv-railsのgemを追加
環境変数.env
を読み込むために、Gemfileに以下の記述を追加します。
Gemfileもrails new
で上書きされています。
# 環境変数
gem 'dotenv-rails'
Dockerイメージ作成
以下のコマンドで、Dockerイメージをビルドします。
開発環境用にビルドしたいので、-f
オプションで、docker-compose-dev.yml
を指定しています。
docker-compose -f docker-compose-dev.yml build
コンテナの立ち上げ
以下のコマンドで、作成されたDockerコンテナを立ち上げます。
docker-compose -f docker-compose-dev.yml up -d
DBの設定
config/database.yml
を編集して、データベースファイルの設定を変更します。.env
の値を使って設定します。
(省略)
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
database: <%= ENV['MYSQL_DB'] %> # 追加
username: <%= ENV['MYSQL_ROOT_USER'] %> # 変更
password: <%= ENV['MYSQL_ROOT_PASSWORD'] %> # 変更
host: db # 変更
development:
<<: *default
database: <%= ENV['MYSQL_DB'] %>_development # 変更
(省略)
test:
<<: *default
database: <%= ENV['MYSQL_DB'] %>_test # 変更
(省略)
DBの作成
以下のコマンドで、データベースを作成します。(少し時間がかかります)
docker-compose -f docker-compose-dev.yml exec web rails db:create
コンソールログが以下のようになればデータベースが作成できています。
Created database 'db_docker_rails7_development'
Created database 'db_docker_rails7_test'
動作確認
ブラウザからhttp://localhost:3000/
にアクセスして、以下のような画面が出たら成功です。
参考サイト
https://blog.pentagon.tokyo/3544/
https://musclecoding.com/rails7-mysql8-docker/
https://zenn.dev/yoiyoicho/articles/90e1ea64772ea8