こんにちは、Masuyama です。
今回は docker-compose を用いて
Rails 6系のアプリを Docker ベースで構築する方法をチュートリアル形式で解説します。
この記事で解説するチュートリアルの流れは以下の通りです。
- 前提条件の確認
- 必要なファイルを準備
- コンテナイメージのビルド
- Rails プロジェクトを作成
- データベースの準備
- 必要なパッケージをインストール
- コンテナを起動
- ブラウザで動作確認
- コンテナを削除
チュートリアルを通して学ぶことで、
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 を使った開発環境の構築を頑張ってみてください。