프로덕션용 NestJS Docker 이미지를 빌드하는 방법
그래서 저는 NestJs 프로젝트를 위한 Docker 이미지를 설정하는 방법을 단계별로 안내하는 이 가이드를 작성했습니다!
준비가 된? 다이빙하자.
추신 프로덕션 준비가 된 Dockerfile을 복사하여 붙여넣으려면 여기section로 건너뛰십시오.
Dockerfile 작성
컨테이너 이미지는 코드를 실행하는 데 필요한 모든 것을 포함하는 격리된 소프트웨어 패키지입니다. 이미지 빌드 방법에 대한 지침을 제공하는
Dockerfile
를 작성하여 컨테이너 이미지를 정의할 수 있습니다.이제 Dockerfile을 추가해 보겠습니다.
touch Dockerfile
그런 다음 Dockerfile에 지침을 추가해 보겠습니다. 각 단계를 설명하는 주석을 참조하십시오.
# Base image
FROM node:18
# Create app directory
WORKDIR /usr/src/app
# A wildcard is used to ensure both package.json AND package-lock.json are copied
COPY package*.json ./
# Install app dependencies
RUN npm install
# Bundle app source
COPY . .
# Creates a "dist" folder with the production build
RUN npm run build
# Start the server using the production build
CMD [ "node", "dist/main.js" ]
.gitignore
파일과 유사하게 특정 파일이 이미지 빌드에 포함되지 않도록 하는 .dockerignore
파일을 추가할 수 있습니다.touch .dockerignore
그런 다음 이미지 빌드에서 다음 파일을 제외합니다.
Dockerfile
.dockerignore
node_modules
npm-debug.log
로컬에서 컨테이너 테스트
이제 로컬에서 몇 가지 테스트를 수행하여 Dockerfile이 예상대로 작동하는지 확인하겠습니다.
먼저 프로젝트 루트에 있는 터미널의 명령을 사용하여 이미지를 빌드해 보겠습니다(프로젝트 이름으로
nest-cloud-run
를 바꿀 수 있음). .
를 잊지 마세요!docker build -t nest-cloud-run .
로컬 컴퓨터에 있는 Docker 이미지 목록을 출력하는
docker images
를 실행하여 이미지가 생성되었는지 확인할 수 있습니다.docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nest-cloud-run latest 004f7f222139 31 seconds ago 1.24GB
이제 컨테이너를 시작하고 다음 명령으로 이미지를 실행해 보겠습니다(위에서 사용한 이미지 이름이 동일해야 함).
docker run -p80:3000 nest-cloud-run
이제 브라우저에서
https://localhost
를 방문하여 NestJS 앱에 액세스할 수 있습니다(포트 번호 없이 https://localhost
만).컨테이너를 실행할 때 주로 내가 실행한 다른 컨테이너의 포트와의 충돌로 인해 내 컴퓨터에서 몇 가지 문제가 발생했습니다.
비슷한 문제가 발생하면 실행 중인 모든 컨테이너를 중지하고 제거하는 명령
docker rm -f $(docker ps -aq)
을 실행할 수 있습니다.프로덕션을 위한 Dockerfile 최적화
이제 이미지가 로컬에서 작동하는 것을 확인했으므로 이미지 크기를 줄여 보겠습니다.
Cloud Run과 같은 배포 도구는 청구 금액을 계산할 때 이미지 크기를 고려하므로 이미지 크기를 가능한 한 작게 유지하는 것이 좋습니다.
명령
docker images
을 실행하면 이미지 크기가 표시됩니다.docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nest-cloud-run latest 004f7f222139 31 seconds ago 1.24GB
1.24GB는 꽤 큽니다!
Dockerfile
로 돌아가서 몇 가지 최적화를 수행해 보겠습니다.Alpine 노드 이미지 사용
이미지 크기를 최적화하려고 할 때 Alpine 노드 이미지를 사용하는 것입니다recommended.
node:18-alpine
대신 node:18
를 사용하면 이미지 크기가 1.24GB에서 466MB로 줄어듭니다!다단계 빌드 사용
Dockerfile에서 여러 이미지를 빌드하여 가장 최적화된 이미지를 순차적으로 빌드하는 방법인 정의multistage builds를 할 수 있습니다.
실제로 Dockerfile에서 다단계 빌드를 사용하는 방법은 다음과 같습니다.
# Base image
FROM node:18-alpine As development
# Create app directory
WORKDIR /usr/src/app
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./
# Install app dependencies
RUN npm install
# Bundle app source
COPY . .
# Creates a "dist" folder with the production build
RUN npm run build
# Base image for production
FROM node:18-alpine As production
# Create app directory
WORKDIR /usr/src/app
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./
# Install production dependencies.
# If you have a package-lock.json, speedier builds with 'npm ci', otherwise use 'npm install --only=production'
RUN npm ci --only=production
# Bundle app source
COPY . .
# Copy the bundled code
COPY --from=development /usr/src/app/dist ./dist
# Start the server using the production build
CMD [ "node", "dist/main.js" ]
Dockerfile
를 업데이트한 후에는 명령을 다시 실행하여 이미지를 빌드해야 합니다.docker build -t nest-cloud-run .
그런 다음 컨테이너를 가동하는 명령:
docker run -p80:3000 nest-cloud-run
이미지 크기를 확인하기 위해
docker images
를 다시 실행하면 크기가 상당히 작아진 것을 볼 수 있습니다.docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nest-cloud-run latest 004f7f222139 31 seconds ago 189MB
문제 해결
다음과 같은 오류가 발생할 수 있습니다.
오류: 'webpack' 모듈을 찾을 수 없습니다.
다음과 같은 오류가 발생하는 경우 기본 이미지에서 잘못된 노드 버전을 사용하고 있을 수 있습니다.
Error: Cannot find module 'webpack'
ERROR [development 6/6] RUN npm run build
npm ERR! [email protected] build: nest build
이 문제를 해결하려면
FROM node:14-alpine
대신 FROM node:18-alpine
를 사용하십시오.결론
요약하면 NestJS 프로젝트에 최적화된 프로덕션 Docker 이미지는 다음과 같습니다.
# Base image
FROM node:18-alpine As development
# Create app directory
WORKDIR /usr/src/app
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./
# Install app dependencies
RUN npm install
# Bundle app source
COPY . .
# Creates a "dist" folder with the production build
RUN npm run build
# Base image for production
FROM node:18-alpine As production
# Create app directory
WORKDIR /usr/src/app
# Copy application dependency manifests to the container image.
# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).
# Copying this first prevents re-running npm install on every code change.
COPY package*.json ./
# Install production dependencies.
# If you have a package-lock.json, speedier builds with 'npm ci', otherwise use 'npm install --only=production'
RUN npm ci --only=production
# Bundle app source
COPY . .
# Copy the bundled code
COPY --from=development /usr/src/app/dist ./dist
# Start the server using the production build
CMD [ "node", "dist/main.js" ]
위의 이미지에 대해 추가로 최적화할 수 있는 것이 있습니까? 아래 댓글에 남겨주세요!
Reference
이 문제에 관하여(프로덕션용 NestJS Docker 이미지를 빌드하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bytomray/how-to-build-a-nestjs-docker-image-for-production-3cmm텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)