Cute Hello Kitty 3
본문 바로가기
Backend/NestJS

NestJS 백엔드 프로젝트에 Swagger와 Docker 적용하기

by 민 채 2025. 5. 12.
 
 
 

 

지난 포스팅에서는 NestJS와 PostgreSQL을 기반으로 백엔드 프로젝트를 시작하는 방법을 다뤘습니다.

이번 시간에는 API 문서 자동화 도구인 Swagger를 설정하고, Docker + Docker Compose로 개발/운영 환경을 분리하여 NestJS 애플리케이션을 실행하는 방법에 대해 적어보겠습니다.

Docker는 처음 다뤄보는 거라 다른 분들 글을 많이 참고해가면서 진행했습니다. 먼저, Swagger 설정부터 알아보겠습니다.

 


1. Swagger 설치 및 설정

NestJS는 @nestjs/swagger 패키지를 통해 API 문서를 자동으로 생성할 수 있습니다.

npm install --save @nestjs/swagger swagger-ui-express

 

main.ts에 Swagger 설정 추가

// src/main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  // 유효성 검사 적용
  app.useGlobalPipes(new ValidationPipe());

  // Swagger 문서 설정
  const config = new DocumentBuilder()
    .setTitle('Board API')
    .setDescription('게시판 API 문서입니다')
    .setVersion('1.0')
    .addTag('user')
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document); // http://localhost:3000/api

  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

이제 서버를 실행하고 브라우저에서 http://localhost:3000/api 로 접속하면 Swagger UI를 확인할 수 있습니다.

 

이렇게 간편하게 API 문서를 생성할 수 있습니다.


2. Swagger 데코레이터 활용

DTO와 컨트롤러에 Swagger 데코레이터를 추가하면 문서화가 더욱 풍부해집니다.

Dto 예시

import { IsEmail, IsNotEmpty, MinLength } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class CreateUserDto {
  @ApiProperty({ example: 'test@example.com', description: '이메일' })
  @IsEmail()
  email: string;

  @ApiProperty({ example: 'Password123', description: '비밀번호' })
  @MinLength(6)
  password: string;

  @ApiProperty({ example: '홍길동', description: '이름' })
  @IsNotEmpty()
  name: string;

  @ApiProperty({ example: '길동이', description: '닉네임' })
  @IsNotEmpty()
  nickname: string;
}

 

컨트롤러 예시

@UseGuards(AuthGuard('jwt'))
@Get(':id')
@ApiBearerAuth()
@ApiOperation({
  summary: '유저 정보 조회',
  description: '특정 유저의 정보를 조회합니다. 본인일 경우 이메일이 포함됩니다.',
})
@ApiParam({ name: 'id', type: 'number', description: '조회할 유저의 ID' })
@ApiResponse({
  status: 200,
  description: '조회 성공',
  schema: {
    example: {
      user_id: 1,
      name: '홍길동',
      nickname: '길동이',
      email: 'test@example.com',
    },
  },
})
async getUserById(
  @Param('id') id: string,
  @Req() req: Request & { user?: JwtPayload },
) {
  const targetUser = await this.userService.findById(+id);
  if (!targetUser) throw new NotFoundException('사용자를 찾을 수 없습니다.');

  const isOwner = req.user?.user_id === targetUser.user_id;

  return {
    user_id: targetUser.user_id,
    name: targetUser.name,
    nickname: targetUser.nickname,
    ...(isOwner && { email: targetUser.email }),
  };
}

 

정말 간편하게 API 문서가 만들어진 것을 볼 수 있습니다. 

 

3. Docker로 NestJS 애플리케이션 컨테이너화

준비사항 (window)

  • docker desktop
  • docker compose
  • docker desktop 을 실행중인 상태에서 진행해야합니다.

 

Dockerfile 생성

# Dockerfile
FROM node:18

RUN mkdir -p /var/app
WORKDIR /var/app

COPY . .
RUN npm install
RUN npm run build

EXPOSE 3000
CMD ["node", "dist/main.js"]

 

docker-compose 구성

1. 개발 환경

// 개발 환경 (docker-compose.dev.yml)
version: '3.8'

services:
  db:
    image: postgres:16
    restart: always
    env_file:
      - .env.development
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pgdata:/var/lib/postgresql/data

  app:
    build: .
    environment:
      NODE_ENV: development
    env_file:
      - .env.development
    ports:
      - '3000:3000'
    depends_on:
      - db

volumes:
  pgdata:



2. 운영환경

// 운영 환경 (docker-compose.prod.yml)

version: '3.8'

services:
  db:
    image: postgres:16
    restart: always
    env_file:
      - .env.production
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - pgdata:/var/lib/postgresql/data

  app:
    build: .
    environment:
      NODE_ENV: production
    env_file:
      - .env.production
    ports:
      - '3000:3000'
    depends_on:
      - db

volumes:
  pgdata:

 

실행해보기

1. 개발 환경 실행

docker compose -f docker-compose.dev.yml up --build\

2. 운영 환경 실행

docker compose -f docker-compose.prod.yml up --build\

 

참고로 도커를 통해 실행할 경우에는 .env 파일의 호스트를 PG_HOST=host.docker.internal 로 바꿔주셔야 합니다.