Next.js Docker 컨테이너 배포하는 방법 (Using Docker with Next.js)
최근 회사에서 AWS Elastic Beanstalk 기반에서 AWS ECS + Fargate 조합으로 배포 방식을 변경함으로써 도커를 활용하게 되었습니다. 단순히 도커 이미지를 빌드하고, 컨테이너 배포하는 과정은 굉장히 간단하지만, AWS ECS, ECR 그리고 파게이트(Fargate)를 활용해서 웹서비스를 구성하는 과정은 생각보다 까다롭고 부차적으로 공부해야 될 부분이 굉장히 많습니다.
도커를 활용해서 이미지를 빌드하고 배포하는 간단한 과정부터 시작해서 AWS ECS + Fargate를 활용해서 웹서비스를 생성해보고, Github Actions와 AWS Codedeploy를 활용한 무중단 배포(Blue/Green) 자동화 과정까지 다뤄보도록 하겠습니다.
Next.js + Docker 세팅
Next.js 환경을 도커 컨테이너 배포 테스트를 진행하기 위해 Next.js와 도커를 설치합니다.
# Next.js 설치
npx create-next-app my-app --typescript
Dockerfile
도커 이미지를 만들기 위해 Dockerfile을 작성합니다. Dockerfile은 프로젝트 루트 디렉토리에 위치시키면 됩니다. 테스트 당시 next.js 개발환경 버전은 아래와 같습니다.
- next@12.1.5
- node@16.13.2
node.js 버전 뒤에 alpine을 적었는데 이는 리눅스 경량 버전인 "알파인 리눅스" 이미지 설치를 명시한 것으로, 가볍고 간단한, 보안성을 목적으로 개발한 리눅스입니다. 각 단계별 설명은 아래 주석을 작성해 놨습니다.
FROM node:16.13.2-alpine
# 디렉토리 지정
WORKDIR /usr/src/app
# 의존성 설치를 위해 package.json, yarn.lock 복사
COPY package.json ./
COPY yarn.lock ./
# 의존성 설치
RUN yarn
# 필요한 모든 파일을 복사
COPY . .
# next.js 앱 빌드
RUN yarn build
# 컨테이너 포트 3000 설정
EXPOSE 3000
# 애플리케이션 실행
CMD [ "yarn", "start" ]
.dockerignore
node_modules는 이미지를 생성할 때 의존성 설치 명령어로 설치하기 때문에 .dockerignore에 추가합니다.
node_modules
.next
이미지 빌드 & 컨테이너 배포
컨테이너 배포를 위해 우선 이미지를 생성합니다. 이미지를 만들기 위해서 아래 명령어를 입력해 주세요.
# 이미지 빌드
docker build -t {이미지명} .
# ex) docker build -t myapp .
# 컨테이너 배포
docker run -d -p 3000:3000 test-app
docker build 명령어를 입력하면, 아래 과정을 거치면서 이미지 빌드를 진행합니다.
# 이미지 빌드 예시
➜ my-app git:(main) ✗ docker build -t myapp .
[+] Building 89.8s (12/12) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 204B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 59B 0.0s
=> [internal] load metadata for docker.io/library/node:16.13.2-alpine 2.8s
=> [1/7] FROM docker.io/library/node:16.13.2-alpine@sha256:2f50f4a428f8b5280817c9 0.0s
=> [internal] load build context 0.3s
=> => transferring context: 160.46kB 0.2s
=> CACHED [2/7] WORKDIR /usr/src/app 0.0s
=> [3/7] COPY package.json ./ 0.1s
=> [4/7] COPY yarn.lock ./ 0.0s
=> [5/7] RUN yarn 47.4s
=> [6/7] COPY . . 0.1s
=> [7/7] RUN yarn build 29.9s
=> exporting to image 9.0s
=> => exporting layers 9.0s
=> => writing image sha256:a602b45938cca3b8e4819dcc593a36d93e689eaab73b16ba29aa62 0.0s
=> => naming to docker.io/library/myapp 0.0s
컨테이너 배포를 명령어로 진행할 수 있지만, 개인적으로 도커 데스크탑을 활용하면 굉장히 편리하게 도커를 사용할 수 있기 때문에 도커 데스크탑을 설치해서 사용하는 것을 추천합니다. 아래 images 메뉴에 우리가 좀전에 설치한 이미지 파일이 올라가 있는 것을 확인할 수 있습니다.
이미지를 컨테이너 배포에 사용하고 싶다면, 원하는 이미지를 누르고 컨테이너 이름을 입력, 접근할 로컬 호스트 포트번호를 입력하면 컨테이너를 생성됩니다.
생성한 컨테이너를 웹 브라우저로 접근하면, 아래와 같이 우리가 배포한 Next.js 애플리케이션을 확인할 수 있습니다.