70. Next.js project deploy to docker container
Next.js 프로젝트 도커 컨테이너에 배포하기
작성일
5/3/2025작성
팍팍수정일
5/3/2025Next.js 프로젝트 배포
docker-compose up -d --build
코드
# -- docker-compose.yaml -- #
services:
nextjs-frontend:
# 이미지 이름 지정 (원하는 대로 변경 가능)
image: vivakr-com:${TAG:-latest} # 태그 기본값은 latest, 환경 변수 TAG로 지정 가능
container_name: vivakr-com
build:
context: .
dockerfile: Dockerfile
# 빌드 시 사용할 환경 변수 (ARG) 전달
# .env 파일의 NEXT_PUBLIC_* 변수들을 여기에 추가
# docker compose build --build-arg NEXT_PUBLIC_API_URL=... 형태로도 전달 가능
args:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://api.vivakr.com} # 환경 변수 없으면 기본값 사용
NEXT_PUBLIC_IPINFO_URL: ${NEXT_PUBLIC_IPINFO_URL:-https://ipinfo.io}
NEXT_PUBLIC_IPINFO_URL2: ${NEXT_PUBLIC_IPINFO_URL2:-https://ns.vivakr.com}
NEXT_PUBLIC_CHAT_URL: ${NEXT_PUBLIC_CHAT_URL:-https://ns.kimbumjun.co.kr}
NEXT_PUBLIC_RUNNER_URL: ${NEXT_PUBLIC_RUNNER_URL:-https://runner.kimbumjun.com}
NEXT_PUBLIC_ENABLE_LOGIN_MENU: ${NEXT_PUBLIC_ENABLE_LOGIN_MENU:-true}
NEXT_PUBLIC_STORAGE_KEY: ${NEXT_PUBLIC_STORAGE_KEY:-user}
NEXT_PUBLIC_MYIP: ${NEXT_PUBLIC_MYIP:-} # 로컬 IP는 빌드 시점에 따라 달라질 수 있어 주의
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY: ${NEXT_PUBLIC_GOOGLE_MAPS_API_KEY:-}
NEXT_PUBLIC_GOOGLE_MAP_ID: ${NEXT_PUBLIC_GOOGLE_MAP_ID:-}
ports:
# Nginx가 연결할 호스트 포트 : 컨테이너 내부 포트
- '47960:3000'
# 런타임 시 필요한 환경 변수 주입
# .env.local 및 NextAuth에 필요한 .env 변수들을 여기에 추가
environment:
# NextAuth 필수 환경 변수
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} # 호스트 환경변수 또는 .env 파일에서 읽어옴
NEXTAUTH_URL: ${NEXTAUTH_URL:-https://vivakr.com} # 운영 환경 URL 또는 기본값
# Google Provider
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET}
# GitHub Provider
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID}
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET}
# Facebook Provider
FACEBOOK_CLIENT_ID: ${FACEBOOK_CLIENT_ID}
FACEBOOK_CLIENT_SECRET: ${FACEBOOK_CLIENT_SECRET}
# Twitter Provider
TWITTER_CLIENT_ID: ${TWITTER_CLIENT_ID}
TWITTER_CLIENT_SECRET: ${TWITTER_CLIENT_SECRET}
# Discord Provider
DISCORD_CLIENT_ID: ${DISCORD_CLIENT_ID}
DISCORD_CLIENT_SECRET: ${DISCORD_CLIENT_SECRET}
# Microsoft Provider
MICROSOFT_CLIENT_ID: ${MICROSOFT_CLIENT_ID}
MICROSOFT_CLIENT_SECRET: ${MICROSOFT_CLIENT_SECRET}
# Next.js 내부 포트 변경 필요 시 (Dockerfile의 CMD와 일치시켜야 함)
# PORT: 3000
# 호스트의 .env 파일 로드 (선택적, 보안 주의)
# 이렇게 하면 아래 environment 섹션에서 ${VAR_NAME} 형태로 사용 가능
env_file:
- .env # 빌드 args용 변수들 로드 (선택적)
- .env.local # 시크릿 값들 로드
# 재시작 정책
restart: unless-stopped
# healthcheck 추가 (선택적이지만 권장)
# healthcheck:
# test: [ 'CMD', 'curl', '-f', 'http://localhost:3000' ] # 앱이 응답하는지 간단히 확인
# interval: 30s
# timeout: 10s
# retries: 3
# start_period: 30s # 컨테이너 시작 후 healthcheck 시작까지 대기 시간
# 네트워크 설정 (선택 사항, 다른 서비스와 연결 시 유용)
# networks:
# default:
# name: viv_nextjs_network
연관코드
# -- Dockerfile -- #
FROM node:slim AS builder
# 작업 디렉토리 설정
WORKDIR /app
# pnpm 설치 (Node 이미지에 기본 포함 안됨)
RUN npm install -g pnpm
# +++ OpenSSL 설치 추가 +++
# node:slim (Debian 기반) 이미지에 OpenSSL 개발 라이브러리 설치
RUN apt-get update && apt-get install -y openssl libssl-dev && rm -rf /var/lib/apt/lists/*
# 의존성 파일 먼저 복사 (캐싱 활용)
COPY package.json pnpm-lock.yaml ./
# 프로덕션 의존성 포함 모든 의존성 설치
# pnpm fetch 만으로도 가능하지만, install 이 더 확실할 수 있음
RUN pnpm install --frozen-lockfile
# 나머지 소스 코드 복사
COPY . .
# 환경 변수 설정 (빌드 시 필요할 수 있음)
# ARG NEXT_PUBLIC_API_URL
# ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
# 프로덕션 빌드 실행 (standalone output 생성)
RUN pnpm build
# ---- Stage 2: Production Runner ----
# 동일한 Node.js Alpine 버전을 런타임 환경으로 사용
FROM node:slim AS runner
# +++ 런타임용 OpenSSL 라이브러리 설치 (필요한 경우) +++
# Prisma Client 런타임이 OpenSSL을 필요로 할 수 있음
RUN apt-get update && apt-get install -y libssl3 && rm -rf /var/lib/apt/lists/*
# Debian 12(Bookworm) 기반 slim은 libssl3, 이전 버전은 libssl1.1
# 작업 디렉토리 설정
WORKDIR /app
# 프로덕션 환경임을 명시 (Next.js 최적화)
ENV NODE_ENV=production
# 컨테이너 내부에서 실행될 포트 (기본값 3000)
# ENV PORT=3000
# 빌드 스테이지에서 필요한 파일만 복사
# standalone 빌드 결과물 복사
COPY --from=builder /app/.next/standalone ./
# public 폴더 내용 복사 (있다면)
COPY --from=builder /app/public ./public
# static 빌드 결과물 복사
COPY --from=builder /app/.next/static ./.next/static
# Prisma 스키마 파일 복사 (선택적이지만 권장)
COPY --from=builder /app/prisma ./prisma
# 어플리케이션이 사용할 포트 노출 (기본 3000)
EXPOSE 3000
# 컨테이너 시작 시 실행될 명령어 (standalone 서버 실행)
CMD ["node", "server.js"]
CONCLUSION
Next.js project create Docker container
server {
listen 10001;
server_name vivakr.com;
return 301 https://vivakr.com$request_uri;
}
server {
listen 443 ssl;
server_name vivakr.com;
ssl_certificate /etc/letsencrypt/live/vivakr.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/vivakr.com/privkey.pem;
include /private/etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /private/etc/letsencrypt/ssl-dhparams.pem;
ssl_stapling on;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
access_log "/opt/homebrew/var/log/nginx/vivakr.com.access.log";
error_log "/opt/homebrew/var/log/nginx/vivakr.com.error.log" warn;
# HMR용 WebSocket 설정
# location /_next/webpack-hmr {
# proxy_pass http://127.0.0.1:47960;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# 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;
# proxy_read_timeout 86400; # WebSocket 연결 유지
# proxy_send_timeout 86400;
# proxy_buffering off;
# }
location / {
proxy_pass http://localhost:47960; # Next.js 로컬 서버로 프록시
# proxy_pass http://192.168.0.8:3000; # Next.js 로컬 서버로 프록시
proxy_http_version 1.1; # WebSocket 지원을 위해 추가
proxy_set_header Upgrade $http_upgrade; # WebSocket 업그레이드 헤더
proxy_set_header Connection "upgrade"; # WebSocket 연결 유지
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;
}
}
삭제권한 확인 중...
수정 권한 확인 중...