はじめに
最近、Dockerについて学習したので、実際にRailsの新規プロジェクトを作成し、Docker化する手順について書いていきます。
なお、データベースにはPostgreSQLを、オーケストレーションツールにはdocker-composeを利用します。Docker Containerは1コンテナ1アプリケーションの構成とします。
補足となりますが、私は以下の学習教材を利用してDockerの理解を深めました。もしDockerについて理解を深めたい方はご参考にしていただけるとよいかもしれません。
作業手順
- 必要なファイルの作成
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock
- Docker Containerの起動とRailsプロジェクトの新規作成
- database.ymlの編集
- データベースの接続
必要なファイルを作成する
任意の名前のディレクトリ配下に必要なファイルを新規作成し、中身を記述していきます。
※ 任意の名前のディレクトリが、build context
となるイメージです。
Dockerfile
Railsで開発するためのDockerfileを作成します。Docker Hub上にあるRubyのDocker Official Imageを使用しています。
なお、Railsバージョンに合うRubyバージョンを使用しないとエラーとなる可能性があるため、ご注意ください。
FROM ruby:3.2.2
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
nodejs \
postgresql-client \
yarn
WORKDIR /myapp
COPY Gemfile Gemfile.lock /myapp/
RUN bundle install
docker-compose.yml
以下2点の懸念から、オーケストレーションツール(docker-compose)を使用しています。
-
docker run
コマンドの記述が長くなるため - 複数のDocker Containerを一括で起動したいため
以下の内容をファイルに記述します。なお、Rubyのデフォルトポートは3000番です。
version: '3'
volumes:
db-data:
services:
web:
build: .
ports:
- '3000:3000'
volumes:
- '.:/myapp'
environment:
- 'DATABASE_PASSWORD=postgres'
tty: true
stdin_open: true
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
念のため、上記ファイル内のパラメータごとの説明を表形式で書いておきます。
サービス名 | キー名 | 内容 |
---|---|---|
web | build | Dockerfileをビルドするディレクトリ |
web | ports | ポストフォーワードするHost側、Docker Container側のポート番号 |
web | volumes | マウントするファイルシステムのHost側、Docker Container側のパス |
web | environment | 定義する環境変数名とその値 |
web | tty | 出力結果をprettyにするかどうか |
web | stdin_open | STDIN(入力チャネル)を開くかどうか |
web | command | Docker Container起動時に実行するコマンド |
- ports
- Host側の3000番ポートをDocker Container側の3000番ポートにポストフォーワードしている
- volumes
- Host側のパスは、他の人の環境でもスムーズにDocker Containerを起動できるよう相対パスで記述するとよい
Dockerfileとdocker-compose.ymlの違い
- Dockerfile
- Dokcer Containerの中身を定義するもの
- docker-compose.yml
- Docker Containerをどのように起動するか定義するもの
Gemfile
RailsでのWebアプリ開発に必要なgemのリストを記載するファイルです。今回は、Railsをインストールする必要があるため、以下の通りに記述します。
source 'https://rubygems.org'
gem 'rails', '~> 7.0.6'
bundle install
を実行すると、BundlerがGemfileに記載されたgemをインストールします。Dockerfile内のCOPY
、RUN
部分とGemfileとの関係ですが、以下の通りとなります。
-
COPY
- HostにあるGemfileと後述のGemfile.lockをDocker Container内にコピーする
-
RUN
- Docker Container内のGemfileを使用して、
bundle install
を実行し、必要なgemをインストールする
- Docker Container内のGemfileを使用して、
Gemfile.lock
ファイルの作成のみです。前述のbundle install
コマンドを実行すると、インストールされたgemの一覧が本ファイルに自動的に記述されます。
Docker Containerの起動とRailsプロジェクトの新規作成
以下のコマンドをCLI上で実行し、Docker Containerを作成、起動します。
$ docker-compose run --build -d
先ほど作成、起動したDocker Containerの中に入るため、以下のコードを実行します。
$ docker-compose exec web bash
Dockerコンテナ内で、Railsの新規プロジェクトを作成します。
また、Dockerfile上ですでにbundle install
を記述しており、rails.new
で
Gemfileが更新された後にコンテナから抜けて再度Docker Imageをビルドし直すため
bundle install
はスキップします。
$ rails new . --force --database=postgresql --skip-bundle
$ exit
$ docker-compose down //すべてのContainerとImageを削除する
$ docker-compose up --build -d
ただ、現時点でlocalhost:3000
にアクセスしてもデータベースが作成されていない、接続設定がされていないため、データベース関連のエラーが出てしまいます。
database.ymlの編集
Railsの新規プロジェクトを作成すると、configフォルダ配下にdatabase.ymlが自動で作成されます。database.yml内にデータベースの接続のための設定を追記します。
コメントアウトで「追加行」と記載された部分を追記します。
すべてPostgresSQLのデフォルトのユーザー、パスワード、ポートを使用しています。
また、パスワードの値には、環境変数「DATABASE_PASSWORD
」を記述し
docker-compose.yml内で記述された同名の環境変数とリンクさせます。
default: &default
adapter: postgresql
encoding: unicode
host: db #追加行
user: postgres #追加行
port: 5432 #追加行
password: <%= ENV.fetch("DATABASE_PASSWORD") %> #追加行
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
docker-compose.ymlの編集
docker-compose.ymlにおいてもコメントアウト「以下追加」より下の行を追記し、PostgresSQL関連の設定を行います。
version: '3'
volumes:
db-data:
services:
web:
build: .
ports:
- '3000:3000'
volumes:
- '.:/myapp'
environment:
- 'DATABASE_PASSWORD=postgres'
tty: true
stdin_open: true
#以下追加
depends_on:
- db
links:
- db
command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
db:
image: postgres:12
volumes:
- 'db-data:/var/lib/postgresql/data'
environment:
- 'POSTGRES_USER=postgres'
- 'POSTGRES_PASSWORD=postgres'
追記したパラメータの説明を表形式で書いておきます。
サービス名 | キー名 | 内容 |
---|---|---|
web | depends_on | 事前に起動するサービス名(Docker Container名) |
web | links | web(サービス名 / Docker Container名)からアクセスするサービス名 |
db | image | 使用するDocker Image |
db | volumes | データベースのデータをマウントするHost側のvolume |
データベースの接続
前回同様に、Docker Containerを以下のコマンドで起動し、Containerの中に入ります。
$ docker-compose up --build -d
$ docker-compose exec web bash
最後に、データベースを作成し、Railsのサーバーを立ち上げて完了です。
$ rails db:create
$ rails s -b 0.0.0.0
localhost:3000
にアクセスしてみると、Railsの画面が表示されているはずです。
おわりに
個人的に、Dockerを理解するにはかなりの時間がかかりました。ただ、諦めずに何度もUdemyの講座を見返すことで徐々に理解できたのでよかったです。
どなたかの参考になれば、幸いです。