今更ながらフロントエンドを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ファイルに記述し、そこから取得するようにしています。
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の方の値が優先される(はず)ので注意。
MYSQL_ROOT_PASSWORD=password
MYSQL_DATABASE=testdb
MYSQL_PASSWORD=password
MYSQL_USER=root
MYSQL_HOST=db
front/Dockerfile
こちらはnode.jsのドキュメントを参考にしました。
package.jsonはまだない状態なので、元のimageそのままです。
FROM node:18.16-alpine
WORKDIR /usr/src/app
back/Dockerfile
こちらはdockerのドキュメントを参考にしました。
今回dbはmysqlのためdefault-mysql-clientをapt-get installしています。
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のバージョンを指定しておきます
source "https://rubygems.org"
gem "rails", "~> 7.0.5"
back/Gemfile.lock
こちらは空ファイルを準備しておけばOK
イメージのビルド
必要なファイルが揃ったらまずは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"] %> の形式でコンテナに設定した環境変数を取得します。
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
http://localhost:3000
おわり
docker-composeを使う際のディレクトリ構成だったり、
docker-composeの書き方のベストプラクティス的なものに沿っているかは微妙。。
この辺は、人それぞれだったりプロジェクトによりけりなのかなぁ(独り言)