記事一覧に戻る

Next.js 13 + Ruby on Rails + Dockerの開発環境を構築する

2023-09-183 min read技術記事
#Rails#環境構築#Docker#備忘録#Next.js

はじめに

  • エンジニア歴半年の備忘録
  • いろんな記事を参考に作ってます(マジで感謝)

やりたいこと

  • Next.js 13 + Railsを使ったWebアプリを作りたい
  • それをDockerの仮想環境で作りたい

バージョン

  • Ruby 3.2.2
  • Rails 7.0.6
  • node.js 18
  • next.js 13

早速構築する

以下のディレクトリ構造をまずは作る。

(SuwaSystemsとは今回作ったアプリの固有名詞です。気にしないで)

SuwaSystems
├── docker 
│   ├── db // dbコンテナのマウント先
│   └── redis
│       └── data
├── suwasystems-backend
│   ├── // ここにRails
└── suwasystems-app
		└── // ここにNext.js

Next.jsを入れる

フロントエンド(今回はapp)のディレクトリに移動して

> npx create-next-app --typescript

—typescriptのオプション(—tsでもおけ)を付けるとTypeScriptの形式でコードを生成してくれる。

Railsを入れる

バックエンド(今回はbackend)のディレクトリに移動して

> rails new project-backend --skip-spring --api

で完成。

Gitの調節

各Next.jsとRailsのフォルダにはめんどくさいことに初期から.gitが用意されている。各ディレクトリに移動して以下を実行、削除しておく。

> rm -rf .git

.gitignoreの統合を済ませておくとなおよし。(バラバラでも機能するが見た目が良くない)

Docker環境を構築する

さっきのディレクトリに以下を追加する

SuwaSystems
├── docker
│  
├── suwasystems-backend
│   ├── // railsのファイル諸々
│   ├── Dockerfile // 追加
│   ├── Gemfile.   // 追加
│   └── Gemfile.lock  // 追加
│
├── docker-compose.yml // 追加
├── .env //追加
│
└── suwasystems-app
		├── // next.jsのファイル諸々
		└── Dockerfile // 追加

docker-compose.ymlはルートディレクトリに一つ、Dockerfileはフロントとバックに一つずつ置いておきます。

docker-compose.yml:

version: '3.8'

services: 
  front:                             # Next.js用コンテナ
    build:
      context: ./suwasystems-app/
    volumes:
      - ./suwasystems-app:/app       # ボリュームのバインド設定
    command: 'yarn dev'              # コンテナ起動時に実行されるコマンド
    ports:
      - "8080:3000"                  # host側の8080ポートをコンテナの3000ポートに対してフォワード
  back:                              # Rails用コンテナ
    build:
      context: ./suwasystems-backend/
    ports:
      - 3000:3000
    volumes:
      - ./suwasystems-backend:/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:

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

フロント用Dockerfile

FROM node:18

RUN /bin/bash &&\
    apt-get -y update &&\
    apt-get -y upgrade &&\
    npm install -g npm

WORKDIR /app

CMD /bin/bash

バック用Dcokerfile

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"]

Gemfileの更新

# Use sqlite3 as the database for Active Record
# gem "sqlite3", "~> 1.4"

# Use mysql as the database for Active Record
gem "mysql2"

今回はmysqlを使うので、sqliteをコメントアウトしてmysql2を追加します

database.ymlの更新

/config/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"] %>
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  <<: *local
  database: project_test

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>
  socket: /tmp/mysql.sock

.gitignoreの更新

nextとrailsの初期設定にプラスして、以下を入れるといいかもしれません(ここはお好みで)

# vscode
.vscode

# docker
/docker/db

起動

ここまできたら起動してみましょう

> docker-compose up -d --build

確認

Next.jsの確認

でNext.jsの初期画面が確認できたらフロントの確認は完了です。

スクリーンショット 2023-09-18 0.58.01.png

Railsの確認

スクリーンショット 2023-09-18 1.13.57.png

railsの画面も表示されたら完成です!! お疲れ様でした!!!!!!!!!!!!!!

エラー対処備忘録

エラー:error Couldn't find a package.json file in "/app”

docker-compose.ymlのマウントするボリューム(volumes:)の指定はフレームワークの設定を含むディレクトリを指定しないとエラーになります。

services: 
  front:                             # Next.js用コンテナ
    build:
      context: ./suwasystems-app/
    volumes:
      - ./suwasystems-app/app:/app  
    command: 'yarn dev'              
    ports:
      - "8080:3000"                 

上記は/suwasystems/appディレクトリにpackage.jsonが無いためエラーが出ます。

volumes:
    - ./suwasystems-app/:/app

解決方法は簡単。こうするだけですね。

エラー:Rack app ("GET /" - (172.25.0.1)): #<Psych::AnchorNotDefined:"Cannot load database configuration:\nAn alias referenced an unknown anchor: local">

config/database.ymlの設定ミスをするとこうなります。

対処法は簡単。&localと続くアンカーを以下のようにしっかり定義してあげるだけ(俺は&defaultになってた)

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

development:
  <<: *local
  database: <%= ENV["MYSQL_DATABASE"] %>
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *local
  database: project_test

production:
  <<: *local
  url: <%= ENV['DATABASE_URL'] %>
  socket: /tmp/mysql.sock

参考