📦

docker-composeでRails 6×MySQLの開発環境を構築する方法

2022/06/03に公開約6,500字

こんにちは、Masuyama です。

近年では、Webアプリケーションを構築・運用する時には
コンテナ技術である Docker を使う、または選択肢に入れることが普通になっています。

その影響か、エンジニア転職を目指す方を見ていると
Ruby on Rails (以下、Rails) のポートフォリオに Docker を組み込む方が増えています。
(実際、私も転職時のポートフォリオには Docker ベースで Rails アプリを作りました。)

しかし、初学者の方にとっては Rails だけでも大変なのに
それを Docker 化するのは、かなり骨が折れる仕事になるかと思います。

そこで、今回は docker-compose を用いて
Rails 6系のアプリを Docker ベースで構築する方法をチュートリアル形式で解説します。

この記事で解説するチュートリアルの流れは以下の通りです。

  1. 前提条件の確認
  2. 必要なファイルを準備
  3. コンテナイメージのビルド
  4. Rails プロジェクトを作成
  5. データベースの準備
  6. 必要なパッケージをインストール
  7. コンテナを起動
  8. ブラウザで動作確認
  9. コンテナを削除

チュートリアルを通して学ぶことで、
Rails を Docker ベースで動かすために必要なファイル、そして流れを掴めるようになります。

初心者向けに、手順には適宜説明を加えているので安心してください。

チュートリアル

0. 前提条件の確認

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

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

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

$ mkdir rails-docker
$ cd rails-docker

なお、基本的には Mac や Linux (AWS Cloud9の人もコレ) を想定して
mkdir, cd, touch といったコマンドを書いていることがありますが
Windows の方は適宜読み替えていただければと思います。

1. 必要なファイルを準備

空ファイルの準備

まずは 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 ファイルを編集していきます。

Dockerfile を編集

Docker では、 Dockerfile という名前のファイルで定義した通り
コンテナイメージの作成が行われます。

そのため、Rails を動かすために必要なパッケージのインストール等は
この Dockerfile の中で指定することになります。

また、Dockerfile 内でベースとなるコンテナイメージを指定することも可能です。

空の Linux から Ruby をインストールしていくのは大変なので、
通常は任意のバージョンの Ruby が最初からインストールされている
Ruby公式のイメージを使用するのがいいでしょう。

今回は Ruby 2.7.5 を指定してみましょう。

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

Dockerfile

FROM ruby:2.7.5

# yarnパッケージ管理ツールをインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget && \
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
apt-get update && apt-get install -y yarn

RUN apt-get update -qq && apt-get install -y nodejs yarn
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

RUN yarn install --check-files
RUN bundle exec rails webpacker:compile

# コンテナ起動時に実行させるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Rails サーバ起動
CMD ["rails", "server", "-b", "0.0.0.0"]

docker-compose.yml を編集

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

Docker Compose は、複数のコンテナで構成されるアプリケーションについて
Docker イメージのビルドや、各コンテナの起動・停止といった管理を行うためのツールです。

Docker Compose では、Dockerビルドやコンテナ起動のオプションも含め
複数のコンテナのための定義を docker-compose.yml というファイルに記述することで、
Docker イメージのビルドやコンテナの起動を一括で行うことができるようになります

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

db という欄で MySQL (DB) のコンテナサービス(以下、コンテナ)の起動に関する設定をし、
web という欄で Rails (アプリ) サービス起動に関する設定をしています。

docker-compose.yml

version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "3306:3306"
    volumes:
      - ./tmp/db:/var/lib/mysql

  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

Gemfile の編集

Gemfile

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

entrypoint.sh の編集

entrypoint.sh

#!/bin/bash
set -e

rm -f /myapp/tmp/pids/server.pid

exec "$@"

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

2. コンテナイメージのビルド

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

ここで、

$ docker-compose build

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

3. Rails プロジェクトを作成

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

docker-compose run に続けてサービス名を指定し、
さらにコンテナ内で実行したいコマンド(=railsコマンド) を続けていきます。

Rails が動くサービスには web という名前を docker-compose.yml で付けたので
コマンドでのコンテナ名としては web を当てはめます。

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

$ docker-compose run web rails new . --force --no-deps --database=mysql

rails new した時と同じように、ディレクトリ内に関連ファイルが生成されます。

4. データベースの準備

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

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

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

config/database.yml

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

development:
  <<: *default
  database: myapp_development
  host: db
  username: root
  password: password

test:
  <<: *default
  database: myapp_test
  host: db
  username: root
  password: password

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

db は docker-compose.yml で指定した MySQL のコンテナ名ですね。

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

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

$ docker-compose run web rails db:create

5. 必要なパッケージをインストール

Rails 6系からは Webpacker が必要となっているため
webコンテナ内に Webpacker をインストールしておきます。

これも rails コマンドから実行できます。

$ docker-compose run web rails webpacker:install
...
Webpacker successfully installed 🎉 🍰

これで Rails サーバを起動させるための準備が整いました!

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

6. コンテナを起動

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

$ docker-compose up -d

docker-compose up は、コンテナ docker-compose.yml に基づいて起動するコマンドです。

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

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

7. ブラウザで動作確認

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

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

Rails ではお馴染みの画面が表示されれば完了です!

ここまでお疲れ様でした。

8. コンテナを削除

さて、動作確認ができたらコンテナは停止させておきましょう。

docker-compose コマンドを使うと、一括でコンテナを削除させることができます。
開発用サーバを止めるため、コンテナを一括で削除するには以下のコマンドを実行します。

$ docker-compose down

まとめ

今回は 今回は docker-compose を用いて
Rails 6系のアプリを Docker ベースで構築する方法をチュートリアル形式で解説しました。

実務などの本番運用を想定する場合には
Nginx 等で別途 Web サーバのコンテナを起動させたり、
コンテナイメージを軽量化させる工夫などが必要になりますが
開発環境のために作って壊す程度であれば、今回ご紹介した方法で十分だと思います。

初学者の方は開発環境の構築で詰まることが多いですが、
Docker であれば環境 (PC) との依存による問題を回避しやすいので
ぜひ Docker を使った開発環境の構築を頑張ってみてください。

Discussion

ログインするとコメントできます