logo

Next x Nest x Docker 環境をモノレポで構築する

2022-11-29
2 years ago

開発環境

  • NextJS
  • NestJS
  • Docker

前提

DockerDesktopを導入されていることを前提に構築していきます。

また、Mac(M2)でのみ動作確認を行なっていますのでご了承ください。

サーバーサイドはNestJS

クライアントサイドはNextJS

DBは何でも良かったのですが一応、Postgres

という構成になっています。

本題

① Dockerの設定

  1. プロジェクトルートにdocker-compose.ymlを作成

[Point] DRYに書きたかったのでExtension fieldsを利用

version: '3.8'

x-common: &common
  platform: linux/amd64
  tty: true
  environment:
    NODE_ENV: development
    DATABASE_URL: postgresql://docker:secret@db:5432/monorepo_sample?schema=public
    TZ: Asia/Tokyo
  volumes:
    - .:/app

services:
  db:
    container_name: db
    image: postgres:14.2-alpine
    restart: always
    environment:
      POSTGRES_USER: docker
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: monorepo_sample
      TZ: Asia/Tokyo
    volumes:
      - ./db/postgres/init.d:/docker-entrypoint-initdb.d
      - ./db/postgres/pgdata:/var/lib/postgresql/data
    ports:
      - 5432:5432

  server:
    << : *common
    build:
      context: .
      dockerfile: ./dockerfiles/server/Dockerfile
    container_name: server
    command: yarn start:dev
    depends_on:
      - db
    ports:
      - 3300:3300
      - 5555:5555

  client:
    << : *common
    build:
      context: .
      dockerfile: ./dockerfiles/client/Dockerfile
    container_name: client
    command: yarn dev
    depends_on:
      - server
    ports:
      - 3000:3000
      - 8080:8080
./docker-compose.yml
  1. サーバー(Nest)/ クライアント(Next)用のDockerfileを作成

[Point] ビルドに時間がかかるなどデメリットが大きいので軽量なベースイメージを利用

FROM node:18.12.0-slim

WORKDIR /app/server

RUN apt-get update && \
    apt-get -y install procps

RUN yarn global add @nestjs/cli

RUN yarn install

COPY . .
./dockerfiles/server/Dockerfile
FROM node:18.12.0-slim

WORKDIR /app/client

RUN yarn install

COPY . .
./dockerfiles/client/Dockerfile
  1. ビルド実行
$ docker-compose build

② Serverの設定

  1. Nestプロジェクトを立ち上げる
$ docker-compose run --rm server nest new . --strict
  1. ポート3000はクライアント側で利用するので、3300に変更する
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
- await app.listen(3000);
+ await app.listen(3300);
}
bootstrap();
./server/src/main.ts

③ Clientの設定

  1. Nextプロジェクトを立ち上げる

[Point] create next-appだとデフォルトでsrcフォルダが作られないので、ついでにファイルを整理

$ docker-compose run --rm client yarn create next-app . --ts\
  && mkdir client/src && mv client/pages client/styles client/src/

④ 共通の設定(おまけ)

上記までで環境はできますが、今回はyarn workspacesを利用してNest, Nextそれぞれで管理しているパッケージの中から開発時に利用するパッケージを共通化してみます。

  • yarn workspacesをプロジェクトルートに導入する
$ docker-compose up -d
$ docker exec -it server sh
$ cd ..
$ yarn init
{
  "name": "app",
  "version": "1.0.0",
- "main": "index.js",
- "license": "MIT",
  "private": true,
+ "workspaces": ["server", "client"],
+ "scripts": {
+   "server": "yarn workspace server",
+   "client": "yarn workspace client"
+ }
}
./package.json
  • Prettier / ESLint / TypeScript をルートで管理する
$ yarn install
$ yarn add -D -W prettier eslint typescript
$ mv server/.prettierrc ./
$ yarn server remove prettier eslint typescript
$ yarn client remove eslint typescript

.prettierrcはルートで管理、.eslintrcはそれぞれのルートで管理することを想定しています。

⑤ 起動

$ docker-compose up

最後に

Dockerfileの最適化、node_modulesの管理、今回初めて触ってみたyarn workspacesなど課題はありますが、この環境で個人開発しながら改良していきたいです。(知見溜まったら更新します)

参照