はじめに
近しい記事はあれど、欲しい環境の記事を見つけられなかった
妥協して近しい記事をコピペで使おうとしたらエラーで動かなかった。
この際勉強にもなるし、自分で組んでみようということで作成しました。
前提
M1 Mac
基本的なDockerコマンドはわかる
エラーでハマった箇所を中心に少しだけ説明も入れる
求めた条件
Rails7 API
Mysql8 (認証プラグインを旧バージョンに変更)
React TypeScriptを使用する
backend
frontend
docker-compose.yml
のシンプルな構成
docker compose run <サービス> /bin/sh
等でコンテナに入って直接作業するのはなし
最近発生しているbundler特有のエラーを抑制する記載もいれたい
構成
backend
- Dockerfile
frontend
- Dockefile
docker-compose.yml
バックエンド
Dockerfile
FROM ruby:3.1
ARG RUBYGEMS_VERSION=3.3.20
# WORKDIRは指定したディレクトリがなければ自動で作成する
WORKDIR /backend
COPY Gemfile* /backend/
# Bundlerのversionが起因してエラーが発生するのを防いでいる (結構苦労した)
# 過去には問題なく動いていた環境で急に動かなくなった人もいたみたい
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"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
FROM node:18.7.0-alpine3.16
WORKDIR /frontend
RUN npm i -g create-react-app
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>7.0.3'
Gemfile.lock
# 空で良い
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 "$@"
フロントエンド
Dockerfile
FROM node:18.7.0-alpine3.16
WORKDIR /frontend
# create-react-appのinstallはdocker compose run時にしても良いが
# 今回はImageの時点で入れている
# ここは変更してもよさそう
RUN npm i -g create-react-app
docker-compose.yml
version: '3.8'
services:
db:
image: mysql:8.0.29
command: --default-authentication-plugin=mysql_native_password
volumes:
- ./tmp/db:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
ports:
- "3306:3306"
backend:
build: ./backend/
volumes:
- ./backend:/backend
ports:
- "3001:3000"
depends_on:
- db
frontend:
build: ./frontend/
volumes:
- ./frontend:/frontend
command: sh -c "npm start"
ports:
- "3000:3000"
コマンド
バックエンド
# コンテナ内で railsアプリを作成
docker compose run --rm backend rails new . --force --no-deps -d mysql --api
# config/database.ymlを編集してコンテナのmysqlに接続する
password: root
host: db
# Gemfileが更新されたので再度buildする
docker compose build
# DBを作成
docker compose run --rm backend rails db:create
フロントエンド
# Dockerfileをrootに移す アプリを作成 Dockerfileを元に戻す作業を行なっている
# create-react-app . する際余計なファイルが存在すると作成してくれないのでこの形にしている(苦労した)
docker compose run --rm frontend sh -c "mv Dockerfile .. && npx create-react-app . && mv /Dockerfile /frontend/Dockerfile"
全てのコンテナを立ち上げる
docker compose up -d
http://localhost:3000
→ rails
http://localhost:3001
→ react
知識系 小ネタ
docker comose run <サービス> <コマンド>
で複数のコマンドを実行したい時
sh -c "A && B"
とする必要がある
A && B
とすると2個目以降はホストで実行されてしまう。
yml
にcommand
が設定されている場合
docker compose run
やdocker compose up
ではDockerfile
のCMD
は無視される
docker container <Image>
名で起動する場合はCMD
docker compose run <コマンド>
とする場合は設定したコマンドを優先する
ちょっと脱線
最近はバックエンドとフロントエンドのリポジトリを分けて開発することも多いようです。
バックエンドのAPIだけDocker化して別々のプロジェクトとして連携したほうがCI/CDの構築が簡単
コミットにバックエンドとフロントエンドが混ざることがなくなる。等利点があるようですので
どちらを利用するか考えないとですね。
自分はこの環境を作っている際に知ったのですが、最後まで完成させたくて時間を使ってしまった・・・
参考
今回は10サイト以上見ましたが、その中でも特に参考にしたものを貼っておきます。