はじめに
- エンジニア歴半年の備忘録
- いろんな記事を参考に作ってます(マジで感謝)
やりたいこと
- 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の初期画面が確認できたらフロントの確認は完了です。
Railsの確認
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
参考