logo

NestJS x React(Vite) x GraphQLをDockerで環境構築する

2023-03-01
a year ago

開発環境

  • MacOS 13.2.1

前提

事前にDocker Desktopのインストールが必要です。

また、DBはPostgres、ORMにはPrismaを採用しています。

本題

STEP① dockerファイルの配置

  1. プロジェクトルートにdocker-compose.ymlを作成(※environmentは適宜書き換えてください)
version: '3.8'

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

services:
  db:
    container_name: db
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_USER: docker
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: grndb
      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:5173
      - 8080:8080
./docker-compose.yml
  1. サーバーのDockerfileを作成
FROM node:18.14.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
  1. クライアントのDockerfileを作成
FROM node:18.14.0-slim

WORKDIR /app/client

RUN yarn install

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

STEP② サーバーの設定

  1. Nestプロジェクト作成
$ docker-compose run --rm server nest new . --strict
  1. クライアント側と衝突しないようにポートの設定を変更する
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
  1. GraphQLの設定
$ docker-compose run --rm server yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express
+ import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
+ import { GraphQLModule } from '@nestjs/graphql';
+ import { join } from 'path';

@Module({
+   imports: [
+     GraphQLModule.forRoot<ApolloDriverConfig>({
+       driver: ApolloDriver,
+       playground: true, // MEMO: GUIを利用するなら追加
+       autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
+       cors: {
+         origin: '*',
+       },
+     }),
+   ],
})
export class AppModule {}

MEMO:GraphQL playgroundはこちらにアクセスして確認します→http://localhost:3300/graphql

  1. ORMの設定
$ docker exec -it server sh
$ yarn add -D prisma
$ npx prisma init
$ npx prisma migrate dev --name init

// MEMO: prisma studioを起動できる確認する→http://localhost:8080
$ npx prisma studio

$ nest g module prisma
$ nest g service prisma --no-spec

STEP③ クライアントの設定

  1. Reactプロジェクトの作成
$ docker-compose run --rm client yarn create vite .
$ docker-compose run --rm client yarn install
{
  "name": "client",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
-    "dev": "vite",
+    "dev": "vite --host",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.27",
    "@types/react-dom": "^18.0.10",
    "@vitejs/plugin-react": "^3.1.0",
    "typescript": "^4.9.3",
    "vite": "^4.1.0"
  }
}
./client/package.json

MEMO:dockerを利用する場合、—-hostオプションを加えて開発環境を立ち上げる

  1. Pathエイリアスを利用する設定(必須ではない)
$ docker-compose run --rm client yarn add -D vite-tsconfig-paths
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
+ import tsconfigPaths from 'vite-tsconfig-paths';

// https://vitejs.dev/config/
export default defineConfig({
-  plugins: [react()],
+  plugins: [react(), tsconfigPaths()],
});
./client/vite.config.ts
{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
+    "baseUrl": ".",
+    "paths": {
+      "@/*": ["src/*"]
+    }
  },
  "include": ["src"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
./client/tsconfig.json
  1. 開発環境立ち上げ
$ docker-compose up

さいごに

モノレポでサクッと手元で動かす構築が欲しい時はぜひ参考しにてください!