2025-02-19 00:42:14
Node: 22
next.js: 15.1.4
가장 먼저 고려해야할 요소는 컨테이너 이미지이다.
기반이 되는 배포판의 이미지가 가벼운 것을 사용하는 것이 좋다. 무난하게 alpine 리눅스를 흔히 사용한다.
node:22-alpine
이미지를 사용하고 있다.
node:22
이미지는 717.72 MiB
node:22-alpine
이미지는 387.45 MiB
가 나왔다.
330.27 MiB
라는 차이가 발생하였으며 거의 절반에 가까운 감소를 보였다.
next 서버 구동을 위해서 불필요한 것을 빼고 필수요소만 정리하여 배포할 수 있다.
공식 문서는 아래 경로를 참고한다.
https://nextjs.org/docs/pages/api-reference/config/next-config-js/output
next.config.ts
파일을 연 다음 다음과 같이 수정한다.
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "standalone",
};
export default nextConfig;
이후 npm run build
명령어로 빌드를 수행하면 .next/standalone
경로에 빌드가 된다.
standalone 경로에는 프론트에 필요한 정적 파일이 존재하지 않는데.
이들은 수동으로 복사해주어야 한다. 대상하는 파일은 public
, .next/static
이다.
GitLab을 통한 배포를 수행하고 있으므로 다음과 같이 빌드를 수정해주었다.
(GitLab + GitLab Runner + GitLab Registry)
stages:
- build-next
- release-docker
Build Next App:
stage: build-next
image: node:22-alpine
before_script:
- npm ci --cache .npm --prefer-offline
script:
- npm i
- npm run build
- cp -r ./public ./.next/standalone
- cp -r ./.next/static ./.next/standalone/.next
cache:
key:
files:
- package-lock.json
paths:
- .npm/
artifacts:
expire_in: 3days
paths:
- .next/standalone
tags:
- docker
Release docker image:
stage: release-docker
image: docker:20.10.16
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script:
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:latest
resource_group: registry
cache:
key:
files:
- package-lock.json
paths:
- .npm/
policy: pull
dependencies:
- Build Next App
tags:
- docker-host
앞서 말한 것 처럼 정적파일들은 별도로 복사해주었다.
cp -r ./public ./.next/standalone
cp -r ./.next/static ./.next/standalone/.next
컨테이너 빌드를 위한 Dockerfile
도 수정해주었다.
FROM node:22-alpine
RUN apk add curl
COPY ./.next/standalone /app/server
HEALTHCHECK --interval=10s --timeout=3s CMD curl -f http://localhost:3000 || exit 1
WORKDIR /app/server
CMD ["node", "/app/server/server.js"]
결과적으로 387.45 MiB
에서 78.16 MiB
로 줄어들었다.
약 309.29 MiB
줄어들었다.
위 과정을 수행하여서 639.56 MiB
용량을 줄일 수 있었다.
717.72 MiB
- 78.16 MiB
= 639.56 MiB