영원히 흘러가는 강

Next.js app router + docker 본문

NEXT.js

Next.js app router + docker

double_R_one_G 2025. 6. 16. 18:25
728x90

🐳 도커를 도입한 이유


최근 개발자 면접에서 빠지지 않고 등장하는 질문이 있다.
바로 "Docker 경험이 있나요?" 혹은 "CI/CD 구축해본 적 있나요?"

 

사실 프론트엔드 개발자 입장에서는 Docker가 백엔드나 인프라 쪽 이야기 일수 있겠지만 
독립적인 환경의 필요성과 표준화된 환경의 필요하여 많이 사용하는거 같다

이번 글에서는 Next.js 프로젝트에 Docker를 적용해보고,
Next.js에서 제공한 경량화가 얼마나 차이나는지 볼까한다.


🐳  Docker란?


 

공식홈페이지를 참고하자면 아래와 같다.

Docker는 애플리케이션 개발, 배포 및 실행을 위한 개방형 플랫폼입니다. Docker를 사용하면 애플리케이션과 인프라를 분리하여 소프트웨어를 신속하게 배포할 수 있습니다. Docker를 사용하면 애플리케이션을 관리하는 것과 같은 방식으로 인프라를 관리할 수 있습니다. Docker의 코드 배포, 테스트 및 배포 방법론을 활용하면 코드 작성과 프로덕션 실행 간의 지연 시간을 크게 줄일 수 있습니다.

간단히 내가 이해한 바로 작성을 해보자면
docker는 개발 및 배포 환경을 동일하게 만들어주는 도구이며, 프로젝트를 빌드해 생성된 이미지를 클라우드 플랫폼에 올려 실행하는 것을 도와준다.

즉 vercel / aws 와 같이 직접 배포하는 플랫폼이 아니다.

 

 

🐳 Docker desktop 설치 및 세팅


 

Docker desktop은 내 컴퓨터에서 Docker 환경을 쉽게 설치하고 관리할 수 있게 해주는 프로그램이다.

 

https://docs.docker.com/get-started/get-docker/

위는 Docker desktop 설치 링크

 

본인에 맞는 환경을 선택후 설치를 진행하자

별 어려움이 없으니 이 부분은 패스!

 

 

🐳 Dockerfile + .dockerignore 작성


 

맨 처음 접했을때 Next.js 공식 홈페이지에 작성되어있는지 모르고 이 어려운걸 어떻게 작성해야하나 싶었지만,

아주아주 친절하게 모든 코드를 다 올려주신다. 


아래는 Next.js 에서 작성한 깃허브 url이다.

https://github.com/vercel/next.js/blob/canary/examples/with-docker-multi-env/docker/development/Dockerfile

 

+ 위치는 프로젝트 root 디렉토리다.

아래는 내 폴더 구조다

 

# Step 1. 디펜던시를 설치한다.
FROM node:18-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

# Step 2. App 폴더에 디펜던시를 옮기고 빌드한다.
FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED 1

RUN npm run build

# Step 3. 빌드한 코드를 app 폴더로 옮기고 3000포트로 실행한다.
FROM node:18-alpine AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

COPY --from=builder --chown=nextjs:nodejs /app/public ./public

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


USER nextjs

EXPOSE 3000

ENV PORT 3000

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

 

나의 경우 npm을 사용중이라 npm 으로 작성을 하였다.

 

위의 코드는 Multi-stage build 방식이다.

간단히 단일 빌드와 멀티 스테이지 빌드를 비교해보자면 아래와 같다.

 

단일 빌드

- 하나의 베이스 이미지를 사용하여 모든 빌드 과정을 수행하는 docker 빌드 방식

 

특징 : 

  • 하나의 Dockerfile에 모든 명령어 포함
  • 간단한 애플리케이션에 적합

단점 : 

  • 최종 이미지 크기가 불필요하게 커짐
  • 빌드 도구나 개발 의존성이 프로덕션 환경에도 포함

 

Multi-stage 빌드

- 17.05 버전 부터 도입된 기능으로, 여러 단계를 통해 빌드 과정과 최종 실행 이미지를 분리

 

특징:

  • 하나의 Dockerfile 내에 여러 FROM 명령어를 사용하여 다양한 단계를 정의
  • 빌드 단계에서 필요한 도구와 의존성을 사용하고, 최종 이미지에는 실행에 필요한 결과물만 복사
  • COPY --from 명령어를 사용하여 이전 단계의 결과물을 다음 단계로 전달

장점 :

  • 최종 이미지 크기가 크게 감소
  • 보안 취약점이 줄어들어 보안성 향상
  • 빌드 환경과 실행 환경 명확히 분리 가능

+ 추가로 불필요한 파일이 Docker 빌드에 포함되지 않도록 .dockerignore 파일을 추가하자

Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
docker
.git

 

 

 

🐳 Docker 이미지 생성 및 최적화


 

Dockerfile을 위와같이 작성한 후에 빌드를 해보자

 

그전에 앞서서 next.config.js에 standalone을 추가해줘야한다.

module.exports = {
  output: 'standalone',
}

 

Next.js에서 최적화를 위해 제공하는 기능으로
실행에 필요한 최소한의 파일만 모아서 경량화된 이미지를 만들 수 있게 해준다.

 

이후 아래와 같이 빌드 코드를 작성!!

docker build -t <프로젝트 이름> .

//아래는 나의 경우
docker build -t life-plan .

 

성공적으로 될수도 있지만 코드 문제나 여러 문제가 있다면 해결을 해야한다.

성공했다는 가정하에 Docker desktop images를 확인해본다면 정상적으로 프로젝트 이름으로 작성한 파일이 올라가있을꺼다.

 

참고로 빌드시에 같은 프로젝트 이름으로 빌드를 한다면 이전의 값을 덮어쓴다.

 

 

 

🤔 회고


초기 우려했던거보다는 할만했던거 같다
물론 전체적인 클라우드 플랫폼 배포까지는 해본적 없지만
Dockerfile도 다 제공해주고 이미지만 잘 만들어서 배포만 잘하면 될듯하다.
아래는 내 실수 작성해보았다..ㅎ

 

 

결과만 얘기해보자면 사이즈가 1.44GB가 나왔다...

 

변명을 해보자면 Dockerfile을 위와 같이 작성을 안했었다..

 

공식 홈페이지에서는 pages router 기준이다 보니 app router와는 설정이 다를거라 판단하여 구글링을 하엿고

 

app router로 작성하셨다는 어떤분의 글을 읽고 해당 Dockerfile을 그분의 것으로 작성했지만...

해당 코드에서는 Next.js에서 제공해준 standalone 코드가 없었고 결과는 위와같이 1.44GB였다..ㅎㅎ

 

그리하여 부랴부랴 검색하고 공식홈페이지의 코드와 비교하여 추가하였더니

 

 

289.97MB 로 이전에 비하면 엄청난 경량화가 되었다..

역시 공식 홈페이지 찾아봐야한다 😂 😂 😂 

728x90

'NEXT.js' 카테고리의 다른 글

next-pwa 적용해보기  (1) 2025.03.04
Nextjs useEffect 2번 호출  (0) 2024.05.14
NEXT.js 14  (0) 2023.10.31
Comments