한우의 개발일기

[Next.js]next 프로젝트 도커 빌드하기(2) 본문

NextJS

[Next.js]next 프로젝트 도커 빌드하기(2)

한우코딩 2024. 11. 11. 15:29

MSW 서버도 함께 빌드하기

현재 프로젝트는 벡엔드 서버가 아직 배포가 되지않아서 명세서에 맞게 msw를 이용하여 mock 서버를 통해서 작업을 하고있다.

이때 도커에 빌드시 msw 서버를 같이 빌드해서 추후 벡엔드 서버가 나오면 msw 서버 부분만 지우고 사용하고자 했다

MSW 서버와 같이 빌드를 하게 된 이유

처음에는 docker로 빌드하고 yarn mock 을 통해 로컬에서 mock 서버를 열어주고 빌드된 프로젝트를 확인하는 작업을 하려했으나 도커와 mock 서버간에 충돌과 서버사이드렌더링 관련한 오류로 인하여 같이 배포를 하려고 하였다.

빌드방법

방법은 여러가지가 있었다. Docker.mock 이란 msw서버전용 파일을 새로 만들어도 되고 하나의 Dockerfile에서 같이 빌드를 시켜도 된다.
나는 하나의 Dockerfile에서 실행을 하였다

#dockerfile

FROM node:18-alpine AS base

# Dependencies
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

# Builder
FROM base AS builder
WORKDIR /app

# ARG 정의
ARG NEXT_PUBLIC_API_MOCKING
ARG NEXT_PUBLIC_BASE_URL
ARG NEXT_PUBLIC_KAKAOMAP_KEY

# ENV 설정
ENV NEXT_PUBLIC_API_MOCKING="${NEXT_PUBLIC_API_MOCKING}"
ENV NEXT_PUBLIC_BASE_URL="${NEXT_PUBLIC_BASE_URL}"
ENV NEXT_PUBLIC_KAKAOMAP_KEY="${NEXT_PUBLIC_KAKAOMAP_KEY}"

COPY --from=deps /app/node_modules ./node_modules
COPY . .

RUN yarn build

# Runner
FROM base AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

# ARG 정의
ARG NEXT_PUBLIC_API_MOCKING
ARG NEXT_PUBLIC_BASE_URL
ARG NEXT_PUBLIC_KAKAOMAP_KEY


ENV NEXT_PUBLIC_API_MOCKING="${NEXT_PUBLIC_API_MOCKING}"
ENV NEXT_PUBLIC_BASE_URL="${NEXT_PUBLIC_BASE_URL}"
ENV NEXT_PUBLIC_KAKAOMAP_KEY="${NEXT_PUBLIC_KAKAOMAP_KEY}"

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN mkdir -p .next/cache 
RUN chown -R nextjs:nodejs .next

COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]
#docker-compose.yml
services:
 # Mock 서버: MSW를 사용한 API 모킹 서버
 mock:
   image: node:18-alpine               # Node.js Alpine 리눅스 베이스 이미지
   working_dir: /app                   # 작업 디렉토리 설정
   volumes:
     - .:/app                          # 현재 디렉토리를 컨테이너의 /app에 마운트
     - mock_node_modules:/app/node_modules  # node_modules를 도커 볼륨으로 관리
   ports:
     - "9090:9090"                    # 호스트:컨테이너 포트 매핑
   networks:
     - app-network                     # app-network에 연결 (web 서비스와 통신용)
   command: sh -c "apk add --no-cache curl && yarn install && yarn mock"  # 컨테이너 실행 시 명령어
   environment:
     - NODE_ENV=development           # 개발 환경 설정
     - HOST=0.0.0.0                   # 모든 IP에서 접근 가능하도록 설정
   healthcheck:                        # 서비스 상태 체크 설정
     test: ["CMD", "curl", "-f", "http://localhost:9090/health"]
     interval: 30s                     # 30초마다 체크
     timeout: 10s                      # 10초 타임아웃
     retries: 5                        # 5번 재시도
     start_period: 60s                 # 초기 60초는 준비 시간

 # Next.js 웹 서버: 실제 프론트엔드 애플리케이션
 web:
   build:                              # Dockerfile 빌드 설정
     context: .
     dockerfile: Dockerfile
     args:                             # 빌드 시 사용할 환경변수
       NEXT_PUBLIC_API_MOCKING: ${NEXT_PUBLIC_API_MOCKING}
       NEXT_PUBLIC_BASE_URL: ${NEXT_PUBLIC_BASE_URL}
       NEXT_PUBLIC_KAKAOMAP_KEY: ${NEXT_PUBLIC_KAKAOMAP_KEY}
   ports:
     - "3000:3000"                    # 호스트:컨테이너 포트 매핑
   environment:                        # 컨테이너 실행 환경변수
     - NODE_ENV=production
     - NEXT_PUBLIC_API_MOCKING=${NEXT_PUBLIC_API_MOCKING}
     - NEXT_PUBLIC_BASE_URL=${NEXT_PUBLIC_BASE_URL}
     - NEXT_PUBLIC_KAKAOMAP_KEY=${NEXT_PUBLIC_KAKAOMAP_KEY}
   env_file:
     - .env                           # 환경변수 파일 로드
   depends_on:                        # mock 서비스 의존성
     mock:
       condition: service_healthy     # mock 서비스가 healthy 상태일 때 시작
   networks:
     - app-network                    # mock 서비스와 같은 네트워크 사용
   restart: always                    # 컨테이너 종료시 항상 재시작

# 도커 볼륨: node_modules 관리
volumes:
 mock_node_modules:                   # mock 서비스의 node_modules 볼륨

# 도커 네트워크: 서비스간 통신
networks:
 app-network:                         # mock과 web 서비스 간 통신을 위한 네트워크
   driver: bridge                     # 브릿지 네트워크 드라이버 사용

이런식으로 진행되고 있는데 여기서 실제 api 서버가 배포된다면 위에 목서바 관련된걸 지우고 depend on 부분과 볼륨 부분만 지워준다면 백엔드 api 서버와 바로 사용이 가능하다!

컨테이너 안에 목서버와 web 이 잘 들어있는것을 볼수있다.

추가

빌드된 곳에서

msw서버와 서비스워커까지 잘 동작하는것을 볼수 있다!!