如何 Docker 化 NestJS 应用以用于生产环境
众所周知,Docker 不仅仅是一个流行词,更是软件工程师最好的容器化工具之一。Docker 能够不受环境要求的限制,轻松交付任何应用程序,解决了开发和生产阶段的各种问题,例如运行应用程序时出现的不一致问题,俗话说“呃……但它在我的电脑上可以正常工作!”
本教程介绍如何使用 Nestjs CLI 和 Docker 构建 Nestjs 应用程序并进行 Docker 化。
要求
- Docker 安装
- NestJs 应用
1. Docker 安装
a)有关 Windows 上的安装指南,请访问https://docs.docker.com/docker-for-windows/install/
b)有关 Linux 上的安装指南,请访问
https://docs.docker.com/install/linux/docker-ce/ubuntu/
c) 有关 macOs 上的安装指南,请访问https://docs.docker.com/docker-for-mac/
2. NestJs 应用程序
创建并开发您的 NestJs 应用程序或使用下面提供的示例项目进行演示:
https://github.com/abbasogaji/dockerized-nestjs-production-app
您的 nestJs 应用程序项目结构通常如下所示:
并且,用于运行、测试和构建 nestJs 项目的相关 npm 命令可以在 package.json 的 scripts 对象(属性)中找到;
当我们将应用程序docker化时,将会用到其中一些命令。
现在我们编写 Dockerfile
FROM node:10 AS builder
WORKDIR /app
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:10-alpine
WORKDIR /app
COPY --from=builder /app ./
CMD ["npm", "run", "start:prod"]
分解
-
构建过程分为两步(多步构建);
- 第一步使用 node:10 作为基础镜像,安装依赖项并将 Typescript 文件转译为 JavaScript。此过程使用完整的 node 镜像,因为它包含原生构建所需的所有必要构建工具(node-gyp、python、gcc、g++、make)。
- 第二步使用 node:10-alpine(轻量级版本),从第一步(中间)容器复制文件系统,并设置运行应用程序的命令。我们设置了一个多步骤的构建过程,以便在第一步高效地安装依赖项,并在最后一步从镜像中运行一个轻量级容器。
-
第一步;
- 我们将应用程序目录设置为“/app”,因此我们的应用程序将捆绑到 Docker 镜像文件系统中的“/app”中
- 在复制剩余的项目文件之前,我们将复制我们的“package.json”,然后运行“npm install”,因为这将防止我们重新构建图像并使用缓存安装时进行不必要的安装。
- 我们将运行“npm run build”以在“dist/main”目录中生成生产文件,这是我们在生产环境中的“运行”命令所必需的,即(npm run start:prod)
-
最后一步;
- 我们将应用程序目录设置为“/app”,因此我们的应用程序将捆绑到 Docker 镜像文件系统中的“/app”中
- 我们将复制上一步的文件系统。
- 我们将设置运行应用程序的命令
- 创建 .dockerignore 以避免复制 node_modules;因此在您的.dockerignore中输入“node_modules”,现在您的Dockerfile和.dockerignore文件位于项目的基本目录中,如下所示;
- 现在我们构建我们的镜像,分配一个格式为“docker-username/project-name”的标签,然后通过运行以下命令推送到docker hub:
docker build -t exampleuser/dockerized-nest-project .
docker push exampleuser/dockerized-nest-project
问:现在我们完成了;但是等一下?EXPOSE port 命令被省略了?
答:因为某些 Paas(平台即服务)提供商(例如 Heroku)不尊重 EXPOSE 命令。
但是如果你将你的docker镜像部署到需要EXPOSE命令的云提供商,该命令将你的docker网络端口映射到你的主机端口。那么你应该在最后一个CMD命令之前在Dockerfile中添加“EXPOSE 3000”;
# Using Node:10 Image Since it contains all
# the necessary build tools required for dependencies with native build (node-gyp, python, gcc, g++, make)
# First Stage : to install and build dependences
FROM node:10 AS builder
WORKDIR /app
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
# Second Stage : Setup command to run your app using lightweight node image
FROM node:10-alpine
WORKDIR /app
COPY --from=builder /app ./
EXPOSE 3000
CMD ["npm", "run", "start:prod"]
注意:使用多步骤构建过程来 dockerize 我们的 nestjs 应用程序并不是必需的,只是因为我们希望我们的图像轻量级。对于单步构建过程,我们将编写以下内容;
# Using Node:10 Image Since it contains all
# the necessary build tools required for dependencies with native build (node-gyp, python, gcc, g++, make)
FROM node:10
WORKDIR /app
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build
# EXPOSE 3000
CMD ["npm", "run", "start:prod"]
最后,我们必须重建、部署并运行图像
鏂囩珷鏉ユ簮锛�https://dev.to/abbasogaji/how-to-dockerize-your-nestjs-app-for-production-2lmf