Node.js Express 서버 도커라이즈하기(multi-stage build)

공이·2024년 1월 23일
1

Node.js

목록 보기
1/2
post-thumbnail

프로젝트에서 줄곧 프론트엔드를 담당 해오다가 최근 프로젝트에서는 백엔드를 맡게 되었다. 비교적 익숙한 Node.js의 Express를 사용하여 백엔드를 구축하기로 하였다.

서버는 EC2에 Docker 컨테이너를 띄우는 식으로 하게 되었는데, 이 과정에서 Dockerfile을 만들어야했다.

아래는 처음 작성한 Dockerfile이다.

# 기본 이미지로 node의 최신 LTS 버전 사용
FROM node:lts

# 작업 디렉토리 설정
WORKDIR /usr/src/app

# package.json과 package-lock.json(있을 경우) 복사
COPY package*.json ./

# 프로젝트 의존성 설치
RUN npm install

# 앱 소스 추가
COPY . .

# 빌드 스크립트 실행 (TypeScript 프로젝트인 경우)
RUN npm run build

# 앱 시작
CMD ["node", "dist/index.js"]

이 이미지의 크기가 상당히 커서 빌드한 뒤에 Docker Desktop이 멈추고 느려지는 현상이 발생했다.

그래서 이를 해결할 수 있는 방법을 알아보니 아래의 3가지 방법이 있었다.

  1. 보다 가벼운 베이스 이미지 사용: node:alpine 같은 더 가벼운 버전을 사용해볼 수 있다. Alpine Linux는 작고 가볍다는 특징이 있다.
  2. 멀티-스테이지 빌드: 멀티-스테이지 빌드를 사용하여 빌드 단계에 필요한 도구들을 최종 이미지에 포함시키지 않을 수 있다.
  3. 불필요한 파일 제거: .dockerignore 파일을 사용해 불필요한 파일이나 디렉토리를 Docker 이미지에 포함시키지 않도록 할 수 있다.

가벼운 베이스 이미지를 이용한 Multi-stage build 방법을 써보기로 했다.

Multi-stage Build

# 빌드 스테이지
FROM node:lts AS builder # AS builder는 이 빌드 스테이지의 이름을 builder로 지정
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 실행 스테이지
FROM node:alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/dist ./dist # builder 스테이지에서 빌드한 결과물을 현재 스테이지로 복사
COPY package*.json ./
RUN npm install --only=production # --only=production 옵션으로 npm install을 실행하여 개발 의존성을 제외한 프로덕션 의존성만 설치
CMD ["node", "dist/index.js"]

아래와 같이 이미지 크기가 크게 줄어든 것을 볼 수 있다.

.dockerignore 파일도 추가해보았으나 아직 가벼운 프로젝트 크기라 그런지 이미지 크기에는 영향을 주지 않았다.

추가적으로 환경변수가 node 서버를 실행시키기 위해 환경변수가 필요했는데,
이럴 경우 이미지를 빌드한 다음 컨테이너를 실행시킬 때
docker run -p 5005:5005 -e PORT=5005 -e MONGO_URL=mongodb://yourMongoDBUri nft-backend

이런 긴 명령어를 또 넣어줘야하기 때문에 docker-compose up 명령어로 한 번에 이미지 빌드와 컨테이너 실행을 시키기 위해 도커 컴포즈 파일을 작성했다.

version: '3.8'
services:
  dgu-nft-backend:
    build: .
    ports:
      - '5005:5005'
    environment:
      MONGO_URL: ${MONGO_URL}
    volumes:
      - .:/usr/src/app
      - /usr/src/app/node_modules

이렇게 할 경우 현재 디렉토리 .env 파일의 환경 변수가 적용된다.


참고자료

https://sachithsiriwardana.medium.com/dockerizing-nodejs-application-with-multi-stage-build-e30477ca572

0개의 댓글