프로덕션용 NestJS Docker 이미지를 빌드하는 방법

7751 단어 dockernestjs
NestJS 프로젝트를 배포할 때 컨테이너화된 배포에 필요한 Docker 이미지를 빌드하기 위해 Dockerfile을 작성하는 방법에 대한 로드가 온라인에 없다는 것을 알았습니다.

그래서 저는 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" ]
    
    


    위의 이미지에 대해 추가로 최적화할 수 있는 것이 있습니까? 아래 댓글에 남겨주세요!

    좋은 웹페이지 즐겨찾기