Rails7 APIモード + PostgreSQL + React (TypeScript)でのDocker環境を構築
Docker学習のために、タイトルのような環境構築をしました。
私のようなDocker初学者の方の参考になれば幸いです。
バージョン
Ruby:v3.1.3
Ruby on Rails:v7.0.4
React:v18.2.0
docker-compose:v3.8
1 ディレクトリ構成
今回はバックエンドとフロントエンドのディレクトリを分けて構築します。(Gitも分けて管理)
myapp
という名前のプロダクトを作る前提で進めます。
以下のような構成になります。
└── myapp
├── backend
│ ├── Dockerfile
│ ├── Gemfile
│ ├── Gemfile.lock
│ └── entrypoint.sh
├── frontend
│ └── Dockerfile
└── docker-compose.yml
環境構築したいディレクトリに移動し、以下コマンドを打っていきます。
mkdir myapp
cd myapp
mkdir backend
mkdir frontend
touch docker-compose.yml
touch backend/Dockerfile
touch backend/Gemfile
touch backend/Gemfile.lock
touch backend/entrypoint.sh
touch frontend/Dockerfile
2 バックエンド(Rails)側の設定
Dockerfileの設定
バックエンドのDockerfileには以下を記述していきます。
- 使用したいRubyのimageを指定
- 追加したいライブラリ(PostgreSQLクライアント, yarnパッケージ管理ツール, Node.js
- Gemのインストール
- Rails固有のエントリーポイント対応(entrypoint.shにて説明)
- Railsサーバーの起動
# 使用したいRubyのimageを指定
FROM ruby:3.1.3
ARG RUBYGEMS_VERSION=3.3.20
# PostgreSQLクライアントをインストール
RUN apt-get update -qq && apt-get install -y postgresql-client
# yarnパッケージ管理ツールをインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget
RUN curl https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update && apt-get install -y yarn
# Node.jsをインストール
RUN curl https://deb.nodesource.com/setup_14.x | bash -
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1655A0AB68576280
RUN apt-get update && apt-get install -y nodejs
RUN mkdir /backend
WORKDIR /backend
# Gemをインストール
COPY Gemfile /Gemfile
COPY Gemfile.lock /Gemfile.lock
RUN gem install bundler
RUN cd /backend
RUN gem update --system ${RUBYGEMS_VERSION} && \
bundle install
COPY . /backend
# Rails固有のエントリーポイント対応
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
# Railsサーバーの起動
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
Railsでは特定のserver.pidファイルが存在するとサーバーが再起動できない仕様があります。
Docker環境ではこの仕様が邪魔になってしまうので、起動前にserver.pidを削除する処理を追加する必要があります。
このentrypoint.shによってそれを実行しています。
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /backend/tmp/pids/server.pid
# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
Gemfile
最低限のrailsを設定しておきます。
source 'https://rubygems.org'
gem 'rails', '7.0.4'
docker-compose.ymlの設定
docker-compose.ymlには複数のDockerコンテナを動かすための設定を書きます。
後ほど説明しますが、docker-compose
コマンドで実行します。
今回は以下の環境を設定していきます。
※()内はdocker-compose.ymlに設定するサービス名です。任意に命名してOKです。
- データベース(db)
- バックエンド(api)
- フロントエンド(front)
まずはdbとapiのみ記述していきます。
version: "3.8"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
- POSTGRES_PASSWORD=admin
ports:
- "15432:5432"
api:
build: ./backend/
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
image: api
volumes:
- ./backend:/backend
environment:
RAILS_ENV: development
ports:
- "3000:3000"
depends_on:
- db
コマンドを打っていく
これから打っていくコマンド の中にdocker-compose run xxx 〜
というものがあります。
xxx
にはdocker-compose.yml
に記述したサービス名のどれかを記述します。
つまりどのコンテナに対してのコマンドを打つのか明示するということです。
例えばバックエンドは今回api
と言うコサービス名にしたので、以下のように記述します。
docker-compose run [オプション] api 〜〜〜
docker-compose run api
の後はローカルで普段使うコマンドと同じで大丈夫です。
例えばrails new
したいのであれば、以下のようになります。
docker-compose run [オプション] api rails new 〜〜〜
Railsアプリケーションの作成
Docker環境にてrails new
していきます。
今回はAPIモードかつ、DBはpostgresqlを指定していきます。
docker-compose run --no-deps api rails new . --force --database=postgresql --api
指定したオプションについて
--no-deps
リンクしたサービスを起動しないようにします。今回はdocker-compose.ymlにてdepends_on: - db
を設定しているため必要になります。
--force
ファイルが存在する場合に上書きします。
--database
databseを指定します。
--api
APIモードで構築します。
build
rails new
により、Gemfileが更新されたと思います。
通常はbundle install
を行うと思いますが、Docker環境においては以下を実行します。
docker-compose build
database.ymlの設定
default: &default
adapter: postgresql
encoding: unicode
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: postgres #デフォルトでは無いので設定
password: admin #デフォルトでは無いので設定
host: db #デフォルトでは無いので設定
development:
<<: *default
database: myapp_development #適宜修正
test:
<<: *default
database: myapp_test #適宜修正
production:
<<: *default
database: myapp_production #適宜修正
username: myapp #適宜修正
password: <%= ENV["MYAPP_DATABASE_PASSWORD"] %> #適宜修正
Databaseを作成する
$ docker-compose run api rails db:create
Railsを起動してみる。
ここまでできたら一度Railsを起動してみましょう!
docker-compose up
localhost:3000
にアクセスして以下のような画面が出ればOKです。
3 フロントエンド(React)側の設定
続いてフロントエンド側を構築します。
Dockerfile
フロント側ではnodeのイメージを指定してWORKDIRのみを設定しておきます。
FROM node:16.16.0-alpine
WORKDIR /frontend
docker-compose.yml
先ほど作成したファイルの末尾に以下を追加します。
version: "3.8"
services:
db:
~~~~~
api:
~~~~~
# 以下を追加
front:
build:
context: ./frontend/
dockerfile: Dockerfile
volumes:
- ./frontend:/frontend
command: sh -c "cd app &&PORT=3001 yarn start"
ports:
- "3001:3001"
build
再度以下を実行します。
docker-compose build
Reactアプリケーションを作成
今回は以下を実行していきます。
npmで管理していくため、npx create-react-app
にしています。
docker-compose run front sh -c "npx create-react-app app --template typescript"
Reactを起動する
ここまでできたら再度以下でコンテナを起動しましょう。
docker-compose up
localhost:3001
にアクセスして以下が表示されればOKです。
4 まとめ
今回はRails7 APIモード + PostgreSQL + React (TypeScript)で作るSPAサービスのDocker環境を構築しました。
docker-composeには他にもさまざまなオプションが設定できるみたいですが、今回は最低限で試してみました。
以上です!
Discussion