Rails8.0APIモードとnext.jsのDocker環境構築

# はじめに
RailsAPIモードとnext.jsのDocker環境構築を、自分の学習用にまとめてみました。参考になれば幸いです。
リポジトリ
https://github.com/HERUESTA/RailsAPI_Next.js_sample

## この記事でできること
- Rails8.0での開発環境が構築できる
- next.jsでの開発環境が構築できる

## この記事の対象者
- RailsAPIとNext.jsのDocker開発環境構築がしたい方

## バージョンと使用技術
| 技術 | バージョン |
|:-:|:-:|
|  Ruby |  3.4.3 |
| Rails  |  8.0.2 |
|  Next.js |  15.3.2 |
|  MySQL |  8.4 |
|  Node.js |  22.16.0 |




## おおまかな流れ
この記事の流れは以下のようになっています。
1. 参考にした記事紹介
1. DockerFile作成
1. フロントの環境構築
1. バックの環境構築

# 参考資料
Rails8.0やNext.jsで開発環境構築をした際に参考した記事です。
- RailsAPIモードでの環境構築参考記事
[【入門】DockerでRailsのAPIモードを環境構築しHerokuへ本番反映する手順](https://qiita.com/ippei_jp/items/1163a40a86d07fa691b2)
- RailsAPIとNext.jsでの開発環境構築の参考記事
    - 今記事をベースに執筆させていただきました
[DockerでRailsAPIモード/Next.jsの環境構築をして、Fly.ioとVercelへデプロイしてみた](https://qiita.com/ippei_jp/items/1163a40a86d07fa691b2)
- MySQLでのDockerの設定での参考記事
[Dockerを使ってMySQLの環境を構築してみました](https://zenn.dev/bloomer/articles/7c879ab2a67abc)

# DockerFileの作成
## docker-compose.ymlの作成
- 好きなフォルダに移動して、まずは`docker-compose.yml`を作成してください
```
cd RailsApiSample
touch docker-compose.yml
```
- 次に`docker-compose.yml`で以下のように定義してください
- コメントアウトでそれぞれ行なっていることに説明を加えています。不要な場合は、削除して定義してください
```yml
services:
  db:
    image: mysql:8.4 #Mysqlの2025年5月31日現在のLTS最新バージョン
    environment: #環境変数の設定
      MYSQL_DATABASE: sample_db
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: root_password #Mysqlはroot_passwordも必須
    ports:
      - "3306:3306" #Mysqlのデフォルトポートは3306
    volumes:
      - mysql_data:/var/lib/mysql #Mysqlのデータディレクトリ。volumesでデータの永続を指定
  back:
    build:
      context: ./back #Dockerファイルがあるディレクトリパスを指定
      dockerfile: Dockerfile
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -b '0.0.0.0'" #コンテナが起動するときに実行されるコマンドを指定
    volumes:
      - ./back:/app
    ports:
      - "3000:3000"
    depends_on: #db→Railsの順に起動するように設定
      - db
    tty: true
    stdin_open: true
    environment:
      - RAILS_ENV=development
  front:
    build:
      context: ./front/
      dockerfile: Dockerfile
    volumes:
      - ./front:/app
    command: yarn dev -p 4000
    ports:
      - "8000:4000"
volumes:
  mysql_data:
```
## frontのDockerfileを作成
- フロントの`Dockerfile`を作成します
```
cd front
touch Dockerfile
```
- 以下のように定義します
```Dockerfile
FROM node:22.16.0
```
## backのDockerfileとentrypoint.shを作成
- frontディレクトリからbackディレクトリに移動して作成します
```
cd ..
cd back
touch Dockerfile
touch entrypoint.sh
```
- Dockerfile
    - :pencil: default-libmysqlclient-devとbuild-essentialがmysqlをインストールする際に必要です
```Dockerfile
FROM ruby:3.4.3

# 最新のパッケージ情報を取得
RUN apt-get update -qq \
    && apt-get install -y --no-install-recommends \
        nodejs \
        mariadb-client \
        default-libmysqlclient-dev \
        build-essential \
        vim \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /app
COPY entrypoint.sh /usr/bin
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3002
CMD ["rails", "server", "-b", "0.0.0.0"]
```

- ローカルでも`Gemfile`と`Gemfile.lock`を作成します
```
touch Gemfile
touch Gemfile.lock
```
- Gemfileには以下を記載します
    - Railsのバージョンは適宜好きなバージョンを使用してください。今回はRails8.0.2を使用します
```Gemfile
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.4.3"

gem "rails", "~> 8.0.2"
```
- ルートディレクトリに移動して、`docker compose build`を実行して、Dockerをビルドします
```
cd ..
docker compose build
```

# Next.jsの環境構築
- frontディクレクトリに移動して、フロント環境を構築します
```
cd front
rm README.md
mv Dockerfile ../
docker compose run --rm front yarn create next-app .
```
- パッケージについて聞かれるのですが、以下の画像のように選択します
    - :pencil: Turbopackは従来のwebpackに変わるもので高速にビルドをしてくれるツールになります
    - 今回は個人開発を対象としているので、従来のwebpackを選択するため、Noにします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733438/ec8736fc-3216-499d-ab13-3c87a649833a.png)
- 作成が完了したら、`Dockerfile`をfrontディレクトリに戻します
```
mv Dockerfile front/
```
- `docker compose up front`をして`http://localhost:8000`にアクセス
- 以下の画面が表示されれば、成功です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733438/bd1a257b-cc22-48bb-bb78-4e5b3b9dd887.png)
![[Pasted image 20250531174351.png]]

# RailsAPIの環境構築
- backディレクトリに移動して、RailsAPIの開発環境を構築します
```
cd back
docker compose run --rm --no-deps back bundle exec rails new . --api --database=mysql
```
- Override Dockerfile以外は全てOKで大丈夫です

:::note warn
※Override DockerfileをOKすると今まで設定を記載したDockerfileが上書きされてしまうので、注意してください
:::
![Google Chrome 2025-06-01 22.14.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733438/3e18e40a-0176-49b3-8983-f88e3985233e.png)

- 国際化とタイムゾーンの設定
`config/application.rb`に以下のコードを設定

```ruby
module App
  class Application < Rails::Application
    # Rails8.0のデフォルト設定を読み込む
    config.load_defaults 8.0
    config.autoload_lib(ignore: %w[assets tasks])
    config.api_only = true
    config.time_zone = 'Tokyo'
    # ActiveRecordがデータベースから取得する時刻を、東京に合わせる
    config.active_record.default_timezone = :local
    config.i18n.default_locale = :ja
  end
end
```

- Host機能設定
    - 許可するホスト名に"api"を追加します
    - Host Headerインジェクション等の攻撃を防ぐセキュリティ設定になります
```ruby
config.hosts << "api"
```

- データベースのセットアップ
    - `config/database.yml`に以下を設定
:::note info
Rails8.0から`solid queue`が標準で入っているので、そのための設定を通常のデータベース設定に加えて`solid queue`の設定もまとめて行なっています
:::

```ruby
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: user
  password: password
  host: db

development:
  <<: *default
  database: sample_db_development

production:
  primary: &primary_production
    <<: *default
    database: sample_db_production
    username: app
    password: <%= ENV["APP_DATABASE_PASSWORD"] %>
  cache:
    <<: *primary_production
    database: sample_db_production_cache
    migrations_paths: db/cache_migrate
  queue:
    <<: *primary_production
    database: sample_production_queue
    migrations_paths: db/queue_migrate
  cable:
    <<: *primary_production
    database: sample_production_cable
    migrations_paths: db/cable_migrate
```
- 最後に以下コマンドを実行します
```
docker compose run --rm back bundle install
docker compose build back
docker compose run --rm back rails db:create
```
- `docker compose up`をして、`http://localhost:3000`に入って、以下画面が表示されたら成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733438/0502b223-3885-44fb-a959-bf4f6c3ec522.png)

# 最後に
ここまでみていただいてありがとうございます！
みなさんの環境構築の参考になれば幸いです