[Next.js] Next.js 도커 이미지 생성 + Nginx를 리버스 프록시로 사용

728x90

최근 진행하고 있던 프로젝트의 개발이 끝나 배포에 대한 방법을 고민하던 중 이전에 데모 어플리케이션으로 사용해본 도커와 github action을 사용한 배포 자동화를 적용해보기로 하였다. 사실 데모가 아닌 프로젝트에 CI/CD 전체의 자동화를 적용해보려는 것은 처음이라 많이 헷갈렸다.. (회사에서 근무할 당시에는 사용자가 없는 시간에 수동 배포를 했던 기억이 난다..)

먼저 이번 글에서는 Next.js와 Nginx를 도커 이미지로 만들어 컨테이너로 실행시키는 과정까지 진행한다.

728x90

❗️참고 내용

요약

  • Next.js 서버를 메인으로, Nginx를 리버스 프록시 서버로 구성
  • dockerfile 설정 및 docker image 생성
  • 로컬에서 정상 작동 확인 - Nginx 리버스 프록시 확인
  • 서버 측 렌더링(SSR) 방식을 위주로 설명

프로젝트 설정

    • Next.js 15 app 라우팅 방식입니다.
    • 도커 설치와 프로젝트 생성에 대한 방법은 해당 과정에 없습니다. 

 

Next.js Dockerfile 생성

해당 Dockerfile은 두 단계로 나뉘어 있어 멀티스테이지 빌드 방식을 활용하고 있습니다. 프로젝트 최상단 경로에 파일명을 dockerfile로 지정하고 아래 코드를 넣어 정의합니다.

  1. 첫 번째 단계는 빌드 단계로, Next.js 애플리케이션을 빌드하여 .next 디렉토리와 public 디렉토리 등을 준비한다.
  2. 두 번째 단계는 실행 단계로, 실제로 프로덕션 환경에서 애플리케이션을 실행하는 설정이다. 여기서 불필요한 빌드 파일들을 제외하고, 최종 실행에 필요한 파일만을 포함하여 이미지 크기를 최소화한다.
# 1단계: 빌드 환경 설정
FROM node:18-alpine AS builder

WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build

# 2단계: 실행 환경 설정
FROM node:18-alpine AS runner

WORKDIR /app
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json

RUN npm install --production

ENV NODE_ENV production
ENV PORT 3000

EXPOSE 3000

CMD ["npm", "start"]

 

Nginx 설정

프로젝트 최상단에서 nginx/default.conf 파일을 생성 후 아래 코드를 넣어 사용합니다.

 

server {
    listen 80;

    location / {
        proxy_pass http://app:3000;  # 'app'은 Docker Compose에서 정의된 서비스 이름
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

 

docker-compose.yml 설정

NginxNext.js를 하나의 서비스로 관리하기 위해 도커 컴포스를 만들어 줍니다.

version: '3.8'

services:
  app:
    image: junghyeonkim/studyhub-next-nginx:latest
    ports:
      - '3000:3000'
    environment:
      NODE_ENV: production

  nginx:
    image: nginx:alpine
    ports:
      - '80:80'
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app

 

실행 및 테스트

도커 컴포스를 실행하여 이미지를 만들고 컨테이너 실행하면 아래 처럼 보일 것이다. (아래 이미지는 도커 데스크탑으로 본 이미지와 컨테이너이다.)

도커 이미지
도커 컨테이너

 

실행된 컨테이너를 통해 localhost:80으로 접속한다면 프로젝트가 정상적으로 실행된 것을 확인할 수 있다.

728x90