【初心者向け】Rails 7+MySQL 8.0の開発環境をDocker composeで作る方法

当サイトでは一部リンクに広告が含まれています
目次

はじめに

本記事は、Dockerを利用してRails 7とMySQLの開発環境を構築するための詳細なチュートリアルを提供します。

具体的には、以下のような内容を説明します。

  • Dockerのインストール
  • コンテナイメージのビルド
  • Railsプロジェクトの作成
  • データベースの準備
  • コンテナの起動と削除
  • 簡単な CRUD アプリケーションの作成

前提条件の確認

今回のチュートリアルを実施していくにあたり、 開発に使用する PC に Docker をインストールしておきます。

Docker をインストールしていない人は、 公式サイトからインストーラをダウンロードしてインストールしておきましょう。

また、デスクトップなどに任意の作業フォルダを作成しておきます。
ここでは “rails-docker” というディレクトリを作成し、 その中で作業していくことにします。

mkdir rails-docker
cd rails-docker

Docker で Ruby on Rails を動かす準備

空ファイルの準備

まずは rails-docker ディレクトリローカルの中に 以下の 5 つの空ファイルを作成しましょう。

  • Dockerfile
  • docker-compose.yml
  • Gemfile
  • Gemfile.lock
  • entrypoint.sh

一つひとつファイルの作るのが面倒であれば 以下のコマンドをターミナルで叩くと一発で作れます。

touch {Dockerfile, docker-compose.yml, Gemfile, Gemfile.lock, entrypoint.sh}

作成できたら、Gemfile.lock 以外の 4 ファイルを編集していきます。

RailsとMySQLの開発環境構築に必要なDockerfileの準備

Docker では、 Dockerfile という名前のファイルで定義した通りに コンテナイメージの作成が行われます。
そのため、Rails を動かすために必要なパッケージのインストール等は この Dockerfile の中で指定することになります。

また、Dockerfile 内でベースとなるコンテナイメージを指定することも可能です。
空の Linux から Ruby をインストールしていくのは大変なので、 通常は任意のバージョンの Ruby が最初からインストールされている Ruby 公式のイメージを使用するのがいいでしょう。
今回は、執筆時点で最新のイメージである Ruby 3.2.2 を指定してみましょう。

Dockefile を以下のように編集してください。

Dockerfile

FROM ruby:3.2.2
ARG RUBYGEMS_VERSION=3.3.20

# 作業ディレクトリを指定
WORKDIR /sample_rails

# ホストのGemfileをコンテナ内の作業ディレクトリにコピー
COPY Gemfile Gemfile.lock /sample_rails/

# bundle installを実行
RUN bundle install

# ホストのファイルをコンテナ内の作業ディレクトリにコピー
COPY . /sample_rails/

# entrypoint.shをコンテナ内の作業ディレクトリにコピー
COPY entrypoint.sh /usr/bin/

# entrypoint.shの実行権限を付与
RUN chmod +x /usr/bin/entrypoint.sh

# コンテナ起動時にentrypoint.shを実行するように設定
ENTRYPOINT ["entrypoint.sh"]

# コンテナ起動時に実行するコマンドを指定
CMD ["rails", "server", "-b", "0.0.0.0"]

なお、Rails 6 までは Webpacker を動かすために Node.js が必要でした。
しかし、Rails 7 では Webpacker がデフォルトでインストールされなくなるため、 Node.js は不要になります。

初期設定がシンプルになるのは嬉しいですね。

複数のDockerコンテナを動かす準備

今回のように Rails を動かすコンテナサービス以外にも MySQL (DB) を動かすコンテナサービスを起動し、サービス間での連携が必要な場合には Docker Compose というツールを利用します。

Docker Compose は、複数のコンテナで構成されるアプリケーションについて Docker イメージのビルドや、各コンテナの起動・停止といった管理を行うためのツールです。
Docker Compose では、Docker ビルドやコンテナ起動のオプションも含め 複数のコンテナのための定義を docker-compose.yml というファイルに記述することで、 Docker イメージのビルドやコンテナの起動を一括で行うことができるようになります

では、docker-compose.yml の中身を以下のように編集します。

docker-compose.yml

version: '3'
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mydatabase
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - mysql_volume:/var/lib/mysql
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password

  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails tailwindcss:build && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/sample_rails
    ports:
      - 3000:3000
    stdin_open: true
    tty: true
    depends_on:
      - db
volumes:
  mysql_volume:

db という欄で MySQL (DB) のコンテナサービス(以下、コンテナ)の起動に関する設定をし、 web という欄で Rails (アプリ) サービス起動に関する設定をしています。
この db という名前で、後ほど Rails から MySQL にアクセスするための設定をしていきます。

これまでは MySQL といえばバージョン 5.7 が人気でしたが、 2020 年 4 月にバージョン 8.0 がリリースされたことで、 5.7 から 8.0 への移行が進んでいます。

Qiita 等で Docker と Rails の情報を探すとまだまだ 5.7 を使っている記事が多いですが、今から始めるなら 8.0 に慣れておくことをおすすめします。

また、コマンドのうち以下の部分は Rails 7 からの新機能である Tailwind CSS を使うためのコマンドです。

command: (略) bundle exec rails tailwindcss:build && (略)

Tailwind CSS は、CSS を簡単に書けるようにするためのフレームワークであり、私は現場でもよく使っているので、今回も使えるようにしてあります。
もし Tailwind CSS を使わない場合は、この部分を削除しても OK です。

Gemfile の編集

Gemfile とは、Rails で使用する Gem を管理するためのファイルです。
今回はもちろん Rails 7 を使うので、Gemfile の中身を以下のように編集します。

Gemfile

source 'https://rubygems.org'
gem 'rails', '~> 7.0'

これで Rails のバージョンのうち、メジャーバージョンが 7 であることを指定できました。

entrypoint.sh の編集

続いで、entrypoint.sh を編集します。

entrypoint.sh は、コンテナ起動時に実行するスクリプトを記述するためのファイルです。

entrypoint.sh

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /sample_rails/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

ここでは、Rails でよくある server.pid のエラーを回避するために、 一度 server.pid を削除しています。

また、最後の exec "$@" は、コンテナ起動時に実行するコマンドを指定するためのものです。
これにより、Dockefile で指定した CMD ["rails", "server", "-b", "0.0.0.0"] が実行されます。

これでスタート時点で必要なファイルは準備できました!

Ruby on Rails プロジェクトの準備

Rails プロジェクトの作成

まず docker-compose コマンドを使って rails new を実行し、 Rails プロジェクトを作成しましょう。

以下のコマンドを実行してください。

docker-compose run web rails new . --force --no-deps --database=mysql --css=tailwind --skip-jbuilder --skip-action-mailbox --skip-action-mailer --skip-test

docker-compose run に続けてサービス名を指定し、 さらにコンテナ内で実行したいコマンド(=rails コマンド) を続けています。また、今回は MySQL を使用するため、 --database=mysql を指定しています。

他には、--css=tailwind というオプションを指定しており、これにより Tailwind CSS を使うための設定が自動で行われます。

--skip-jbuilder や --skip-action-mailbox などは、今回は必要がない機能をスキップするためのオプションです。

コマンド実行後、rails new した時と同じように、ディレクトリ内に appconfig などのフォルダが作成されていることが確認できると思います。

Dockerコンテナイメージの作成

次は、前項で作成した Docker 関連ファイルを使って 早速コンテナイメージをビルドします。

docker-compose build

ここで数分かかることがあるので、気長に待ちましょう。

MySQL データベースの準備

では次に、データベースの準備をしていきましょう。

まずは Rails で使用しているデータベースファイルの設定を編集します。
config ディレクトリ内の database.yml というファイルが対象です。

下記のように、まるっと書き換えてください。

config/database.yml

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: user
  password: password
  host: db

development:
  <<: *default
  database: sample_rails_development

test:
  <<: *default
  database: sample_rails_test

ポイントは、host の欄が db であることです。

db は docker-compose.yml で指定した MySQL のコンテナ名ですね。
同じ docker-compose.yml で指定したコンテナ間であれば、 コンテナ名をホストとして名前解決してアクセスすることができます。

さて、これで Rails がデータベースと連携できるようになったので rails db:create コマンドを docker-compose 経由で実行して データベースを作成しておきましょう。

docker-compose run web rails db:create

コマンド実行後、以下のように表示されれば OK です。

$ docker-compose run web rails db:create
[+] Running 1/0
 ⠿ Container rails-docker-db-1  Running                                                                                                                                   0.0s
Created database 'sample_rails_development'
Created database 'sample_rails_test'

次はいよいよ、docker-compose で Rails サーバを起動させましょう。

動作確認

コンテナの起動

コンテナを起動するため、次のコマンドを実行します。

docker-compose up -d

docker-compose up は、コンテナ docker-compose.yml に基づいて起動するコマンドです。
コンテナ起動時にコンテナ内で実行させたいコマンド (= rails s) は Dockerfile で設定しているので、 コンテナを起動させると Rails サーバが立ち上がります。

また、オプションの -d を付けるとバックグラウンドで起動させることができます。

以下のように表示されれば OK です。

$ docker-compose up -d
[+] Running 2/2
 ⠿ Container rails-docker-db-1   Running             0.0s
 ⠿ Container rails-docker-web-1  Started             0.5s

念のため、起動したコンテナを確認してみましょう。
以下のように、2つとも running と表示されていれば OK です。

$ docker-compose ps
NAME                 COMMAND                  SERVICE             STATUS              PORTS
rails-docker-db-1    "docker-entrypoint.s…"   db                  running             0.0.0.0:3306->3306/tcp, 33060/tcp
rails-docker-web-1   "entrypoint.sh bash …"   web                 running             0.0.0.0:3000->3000/tcp

これで無事に Rails の開発用サーバが起動したことになります。

画面表示の確認

ブラウザのアドレスバーに http://localhost:3000/ と入力し、起動を確認してみましょう。

Rails 7 の初期画面が表示されればOKです!

簡単なCRUDアプリケーションを作成

scaffold で簡単な CRUD アプリケーションを作成

続いて、簡単な CRUD アプリケーションを作成してみましょう。

今回は scaffold というコマンドを使って、簡単に CRUD アプリケーションを作成します。

docker-compose run web rails g scaffold post title:string body:text

scaffold は、Rails でよく使われる機能のひとつで、 データベースのテーブルを作成し、そのテーブルに対応するモデルやコントローラ、ビューを一括で作成してくれます。

$ docker-compose run web rails g scaffold post title:string body:text
[+] Running 1/0
 ⠿ Container rails-docker-db-1  Running                                                                                                                                   0.0s
      invoke  active_record
      create    db/migrate/20230913232901_create_posts.rb
      create    app/models/post.rb
      invoke  resource_route
       route    resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    tailwindcss
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      create      app/views/posts/_post.html.erb
      invoke    resource_route
      invoke    helper
      create      app/helpers/posts_helper.rb

データベースのマイグレーション

次に、データベースのマイグレーションを行います。

マイグレーションとは、データベースのテーブルを作成したり、 テーブルのカラムを追加したりするための仕組みです。

docker-compose run web rails db:migrate

以下のように表示されれば OK です。

$ docker-compose run web rails db:migrate
[+] Running 1/0
 ⠿ Container rails-docker-db-1  Running                                                                                                                                   0.0s
== 20230913232901 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0155s
== 20230913232901 CreatePosts: migrated (0.0155s) =============================

Rails サーバの再起動

最後に、Rails サーバを再起動しておきましょう。

docker-compose restart

CRUD アプリケーションの動作確認

では、実際にアプリを動かしてみましょう。

ブラウザのアドレスバーに http://localhost:3000/posts/new と入力し、起動を確認してみます。

以下のように、新規投稿画面が表示されるはずですので、こちらからポストを投稿できます。

また、投稿すると詳細ページにリダイレクトされて投稿内容が表示されていれば OK です。

後片付け – Dockerコンテナを削除

さて、動作確認ができて開発を始めることができましたが、もし開発を終えてコンテナを削除したい場合は以下のコマンドを実行するだけでOKです。

docker-compose down

docker-compose down は、コンテナを停止して削除するコマンドです。

ちなみにコンテナを停止するだけであれば docker-compose stop を使い、また開発をするときにdocker-compose up -d でコンテナを起動しつつ、Rails サーバを起動できます。

補足:コンテナの起動に失敗した場合

もしコンテナの起動に失敗した場合は、以下のコマンドでログを確認してみましょう。

docker-compose logs

docker-compose logs は、コンテナのログを確認するコマンドです。

コンテナのログを確認することで、どこでエラーが発生しているのかを確認することができます。

または、以下のコマンドでコンテナを削除してみましょう。

docker-compose down

先述の通り、docker-compose down は、コンテナを停止して削除するコマンドです。

コンテナを削除することで、コンテナの状態をリセットすることができます。

そして、もう一度コンテナを起動してみましょう。

docker-compose up -d
目次