프로젝트

[배포 준비] next js docker로 실행해보기

Jenner 2024. 4. 5. 12:34

 

docker file 구성

 

FROM node:18-alpine AS base

FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN \
  if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
  else echo "Lockfile not found." && exit 1; \
  fi 
RUN rm -rf ./.next/cache


FROM base AS builder
WORKDIR /usr/src/app
ENV NODE_ENV=production

COPY --from=deps /usr/src/app/node_modules ./node_modules
COPY . .
RUN \
  if [ -f yarn.lock ]; then yarn run build; \
  else echo "Lockfile not found." && exit 1; \
  fi
RUN yarn cache clean

FROM base AS runner
WORKDIR /usr/src/app

ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /usr/src/app/public ./public

RUN mkdir .next
RUN chown nextjs:nodejs .next

COPY --from=builder --chown=nextjs:nodejs /usr/src/app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /usr/src/app/.next/static ./.next/static

USER nextjs

EXPOSE 80

ENV PORT 80

CMD ["node", "server.js"]

 

 

Dockerfile은 4가지 스테이지로 구성되어있다. 

base image, dependency 설치, 빌드, 런타임 

 

멀티 스테이지 빌드방식 

이렇게 스테이지별로 나눠놓는 방식을 멀티 스테이지 빌드 방식이라고 한다. 

필요한 결과물들만  COPY해서 가져오는 방식이기 때문에 

도커의 이미지 용량을 최소화 할 수 있다.

 

 

Base image

 

이미지를 위한 기초와 구성을 제공한다. 

alpine은 NodeJS를 포함하고 있는 작지만 파워풀한 이미지다

alpine Linux는 대부분의 베이스 이미지들보다 5MB정도 작다고 한다 (https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine)

 

Dependency Installation

alpine이 너무 작기 때문에 우리가 사용해야할 NodeJS 패키지들이 필요한 몇가지 라이브러리들을 제공한다. 

alpine은 glibc와 그 친구들 대신  musl libc라는걸 쓰는데 이건 조금 이슈가 될 수 있다고 한다.

alpine을 쓰는데있어서 좀 논란이 될 수 있는 공통된 이슈중 하나는 process.dlopen이라는 라이브러리를 쓰는 것인데 

그걸 해결하기 위해 필요한 것이 libc6-compat를 추가하는 것이라고 한다. 

 

RUN apk add --no-cache libc6-compat

 

 

워킹 디렉토리를 설정후 yarn을 설치한다.

그리고 나의 경우 cache를 삭제해 주었다. 

 

 

Build

 

deps 스테이지에서 설치한 node_modules를 가져오고 

build를 수행한다. 

 

Runtime

 

환경변수를 production으로 설정해 nextjs에게 알리고

group과 user를 설정해주어 보안성을 강화해준다.

public folder로 모든 정적 에셋을 복사해준다 

이것은 nextjs config에 output모드일때만 작동될 것이다. 

 

마지막으로 실제 node server.js와 함께 실행해 주면 된다.