Dockerを使ってRails7+MySQL8のAPIモード環境構築

### はじめに
この記事は初めてDockr Composeを使ってRailsのAPIモードを構築した時忘れない為のメモです。
### 最初に準備して作成するファイルとディレクトリ
今回は<font color='red'>sample-api</font>という名前のディレクトリを作成します。
```bash:bash
$ mkdir sample-api
```
作成したsample-apiディレクトリに移動します。
```bash:bash
$ cd sample-api
```
[Gemfile Gemfile.lock Dockerfile docker-compose.yml entrypoint.sh .env]をsample-apiディレクトリ内作成します。
```bash:bash
$ touch Gemfile Gemfile.lock Dockerfile docker-compose.yml entrypoint.sh .env
```
### Gemfile内容作成
```:Gemfile
source "https://rubygems.org"
gem "rails", "~> 7.0.5", ">= 7.0.5.1"
```
### Dockerfile内容作成
```:Dockerfile
# FROM：rubyのイメージバージョン
FROM ruby:3.2.2

# Rails 7ではWebpackerが標準では組み込まれなくなったので、yarnやnodejsのインストールが不要
# ruby3.22に合わせて、gemのバージョンを3.4.14に指定
ARG RUBYGEMS_VERSION=3.4.14

# RUN：実行【コンテナ内appディレクトリ作成】
RUN mkdir /app

# WORKDIR：作業ディレクトリを指定
WORKDIR /app

# COPY：コピー元とコピー先を指定
# ローカルのGemfileをコンテナ内の/app/Gemfileに
COPY Gemfile Gemfile.lock /app/

# RubyGemsをアップデート
RUN gem update --system ${RUBYGEMS_VERSION} && \
    bundle install
# ホストディレクトリ内のファイルをコンテナ内フォルダにコピーする
COPY . /app

# コンテナ内の/usr/bin/ディレクトリにスクリプトファイルentrypoint.shをコピーする
COPY entrypoint.sh /usr/bin/

# スクリプトファイルを実行できるように権限の変更
RUN chmod +x /usr/bin/entrypoint.sh

# entrypointファイルの指定
ENTRYPOINT ["entrypoint.sh"]

# 公開するポートの設定
EXPOSE 3000

# CMD:コンテナ実行時、デフォルトで実行したいコマンド
# Rails サーバ起動
CMD ["rails", "server", "-b", "0.0.0.0"]
```
### docker-compose.ymlの内容作成
```:docker-compose.yml
version: '3'
services:
  # データベースコンテナ設定
  db:
    # データベースイメージの指定
    image: mysql:8.0.33

    # M1のCPUは、linux/arm64/v8なのですが、使用しようとしたimageがこれに対応していないというエラーが起きる
    # m1はplatformを指定して、linux/amd64にエミュレートする指定をすることで正常に動くようになります
    platform: linux/amd64

    # DBのレコードが日本語だと文字化けするので、utf8をセットする
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    
    # ボリュームの設定
    volumes:
      - db-volume:/var/lib/mysql
    
    # 環境変数
    env_file:
      - .env
    environment:
      MYSQL_ROOT_PASSWORD: password # MYSQLのパスワードを設定
      TZ: "Asia/Tokyo" # タイムゾーンをAsia/Tokyoに設定

    # ホストのポート：コンテナのポート
    ports:
      - "3306:3306"

  # webコンテナ設定
  web:

    # build: .でdocker-compose.ymlと同じフォルダにDockerfileがあることを示す
    build: .

    # railsサーバー起動
    # railsサーバー起動毎に rm tmp/pids/server.pid するのも手間のため、・事前に手元で/tmp/pids/server.pidを削除する
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - 3000:3000
    
    # docker-compose起動時先に起動するコンテナを指定
    depends_on:
      - db
    
    # railsでデバッグする用
    # true を指定することでコンテナを起動させ続けることができます。   
    tty: true

    # stdin_openとは標準入出力とエラー出力をコンテナに結びつける設定です。
    stdin_open: true

# PC上にdb-volumeという名前でボリューム（データ領域）が作成される
# コンテナを作り直したとしてもPC上に残るようにするために設定
volumes:
  db-volume:
```
### entrypoint.shの内容作成
```:entrypoint.sh
#!/bin/bash
# set -e は「エラーが発生するとスクリプトを終了する」オプション
set -e

# rm ではrailsのpidを削除
# Rails に対応したファイル server.pid が存在しているかもしれないので削除する。
rm -f /app/tmp/pids/server.pid

# exec "$@"でCMDで渡されたコマンドを実行しています。(→rails s)
# コンテナのプロセスを実行する。（Dockerfile 内の CMD に設定されているもの。）
exec "$@"
```
### .env環境設定内容作成
```:.env
MYSQL_ROOT_PASSWORD=password
TZ=Asia/Tokyo
```
### Dockerイメージの生成
```:bash
$ docker-compose build
```
### Railsのプロジェクト作成
```:bash
$ docker-compose run --rm web rails new . --skip-bundle --force --database=mysql --api
```
### Rails内のデータベース設定の修正
```:config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db
```
### Railsのプロジェクト作成時追加したGemfileの内容のインストール
```:bash
docker-compose build
```
### データベースの作成
```:bash
$ docker-compose run --rm web rails db:create
[+] Running 1/0
 ✔ Container sample-api-db-1  Running            0.0s 
Created database 'app_development'
Created database 'app_test'
```
### コンテナの作成と立ち上げ
```:bash
docker-compose up -d
# -d:バクグラウンドで実行
```
### ローカルに接続
ブラウザのアドレスバーに<font color=red>localhost:3000</font>を入力する<br>または<br><font color=red>127.0.0.1:3000</font>を入力する