7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Next.js + Railsの開発環境をdocker-composeで構築してみる

Posted at

今更ながらフロントエンドをNext.js、バックエンドとしてRuby on Railsを使用し、WEBアプリを作る際の初期開発環境構築をしてみたので、コンテナ立ち上げまでの手順を備忘として残します。
docker、node.jsのドキュメントを参考にしています。

node.js
https://nodejs.org/ja/docs/guides/nodejs-docker-webapp

docker
https://docs.docker.jp/compose/rails.html

前提環境

docker、docker-composeはすでにインストール済みとします。
多少バージョンが違っても大丈夫だとは思います。
docker

 Engine:
  Version:          23.0.5

docker-compose

Docker Compose version v2.17.3

ディレクトリ構成

下記の通りのディレクトリ、ファイル構成としています。

ディレクトリ構成
.
│
├ docker-compose.yml
├ .env               # docker-compose.yml内の環境変数の定義用のファイル
│
├ front              # Next.js用のディレクトリ
│    ├ Dockerfile    # frontのdockerイメージ作成用のファイル
│
├ back               # Ruby on Rail用のディレクトリ
│    ├ Dockerfile    # backのdockerイメージ作成用のファイル
│    ├ Gemfile
│    ├ Gemfile.lock
│
├ docker
│    ├ db            # dbコンテナのvolumeマウント先ディレクトリ
│    │
│    ├ redis
│        ├ data       # redisのvolumeマウント先ディレクトリ  

それぞれのファイル内容

docker-compose.yml

フロント側を8080ポート、バックエンド側を3000ポートで公開するようにしました。
またDBの環境変数などは.envファイルに記述し、そこから取得するようにしています。

docker-compose.yml
version: '3.8'

services: 
  front:                             # Next.js用コンテナ
    build:
      context: ./front/
    volumes:
      - ./front/app:/usr/src/app     # ボリュームのバインド設定
    command: 'yarn dev'              # コンテナ起動時に実行されるコマンド
    ports:
      - "8080:3000"                  # host側の8080ポートをコンテナの3000ポートに対してフォワード
  back:                              # Rails用コンテナ
    build:
      context: ./back/
    ports:
      - 3000:3000
    volumes:
      - ./back:/app                  # ボリュームのバインド設定
    environment:                     # 環境変数の設定 .envファイルから取得
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_HOST: ${MYSQL_HOST}
    depends_on:                      # コンテナの依存設定
      - db
      - redis
  db:                                # Mysql用コンテナ
    image: mysql:8.0.33
    environment:                     # 環境変数の設定 .envファイルから取得
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    volumes:
      - "./docker/db:/var/lib/mysql"
  redis:                              # redis用コンテナ
    image: "redis:latest"
    volumes:
      - "./docker/redis/data:/data"

.env

key=value の形で記述します。docker-compose.ymlファイルと同階層に配置することで、.envファイルのKeyの値をコンテナ起動時に展開してくれます。
なお、bash_profileなどですでに同keyの環境変数が設定されていた場合は、bash_profileの方の値が優先される(はず)ので注意。

.env
MYSQL_ROOT_PASSWORD=password
MYSQL_DATABASE=testdb
MYSQL_PASSWORD=password
MYSQL_USER=root
MYSQL_HOST=db

front/Dockerfile

こちらはnode.jsのドキュメントを参考にしました。
package.jsonはまだない状態なので、元のimageそのままです。

Dockerfile
FROM node:18.16-alpine
WORKDIR /usr/src/app

back/Dockerfile

こちらはdockerのドキュメントを参考にしました。
今回dbはmysqlのためdefault-mysql-clientをapt-get installしています。

Dockerfile
FROM ruby:3.2

RUN mkdir /app
WORKDIR /app
RUN apt-get update -qq && apt-get install -y default-mysql-client
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN gem update && \
    bundle install
ADD . /app

CMD ["rails", "server", "-b", "0.0.0.0", "-p", "3000"]

back/Gemfile

アプリ生成時のrailsのバージョンを指定しておきます

Gemfile
source "https://rubygems.org"

gem "rails", "~> 7.0.5"

back/Gemfile.lock

こちらは空ファイルを準備しておけばOK

Gemfile.lock

イメージのビルド

必要なファイルが揃ったらまずはfront、backでそれぞれ作成したDockerfileをもとにターミナルからdockerイメージの作成をします。

コマンド
docker-compose build

Next.jsのプロジェクト作成

続けてNext.jsのプロジェクト自動生成を行います。
途中で聞かれる質問(TypeScriptを使うかなど)はお好みで。
実行後frontディレクトリ配下に各種ファイルが生成されます。

コマンド
docker-compose run --rm front yarn create next-app .

Railsのプロジェクト作成

Railsのプロジェクト自動生成を行います。
今回はapiモードでmysqlを使用するため「--api -d mysql」のオプションを付与しています。
実行後backディレクトリ配下に各種ファイルが生成されます。

コマンド
docker-compose run --rm back bundle exec rails new . --api -d mysql

Railsの設定ファイルの編集

DBの接続設定ファイルをdocker-compose.ymlで設定した値に変更します。
<%= ENV["key"] %> の形式でコンテナに設定した環境変数を取得します。

database.yml 一部抜粋
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV["MYSQL_USER"] %>
  password: <%= ENV["MYSQL_PASSWORD"] %>
  host: <%= ENV["MYSQL_HOST"] %>

development:
  <<: *default
  database: <%= ENV["MYSQL_DATABASE"] %>

動作確認

docker-compose upコマンドで全てのコンテナを立ち上げます。
-d オプションでバックグラウンド実行
--build オプションで起動前にimageのビルドを行います。

コマンド
docker-compose up -d --build

うまくいけば下記のように標準出力されます。

実行後
 ✔ Container db-1     Started
 ✔ Container redis-1  Started
 ✔ Container front-1  Started
 ✔ Container back-1   Started 

念の為psコマンドでコンテナの状態を確認します。

コマンド
docker-compose ps

STATUSが「Up」となっていればコンテナが起動されている状態です。

実行後
NAME      IMAGE                       COMMAND                  SERVICE             CREATED             STATUS              PORTS
back-1    back                        "rails server -b 0.0…"   back                3 minutes ago       Up 3 minutes        0.0.0.0:3000->3000/tcp
db-1      mysql:8.0.33                "docker-entrypoint.s…"   db                  7 days ago          Up 3 minutes        3306/tcp, 33060/tcp
front-1   front                                            "docker-entrypoint.s…"   front               3 minutes ago       Up 3 minutes        0.0.0.0:8080->3000/tcp
redis-1   redis:latest                "docker-entrypoint.s…"   redis               7 days ago          Up 3 minutes        6379/tcp

ここまでくれば、Next.jsとRailsの初期ページが表示できるはずです。
http://localhost:8080
スクリーンショット 2023-06-06 18.00.17.png
http://localhost:3000
スクリーンショット 2023-06-06 18.00.34.png

おわり

docker-composeを使う際のディレクトリ構成だったり、
docker-composeの書き方のベストプラクティス的なものに沿っているかは微妙。。
この辺は、人それぞれだったりプロジェクトによりけりなのかなぁ(独り言)

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?