前言
按照目前的进度,相信很多同学已经完成基础篇的内容,也有部分同学完成了用户或者物料系统的开发,所以应广大同学的要求,将应用部署这章提前写出来,方便大家完成项目开发流程中关键的最后一步。
与开发环境不同,在生产环境中服务端的项目都需要后台启动,如果是前端启动的话,当你关闭 ssh 连接或者控制台的时候,程序也就自动退出了,这显然不是我们希望的结果。
本章将介绍 NestJS 两种方式的发布类型: PM2 与 Docker Compose 部署。
PM2
PM2 是一款使用于生产环境的 NodeJS 的进程管理工具,操作非常简便,内置了进程管理、监控、日志以及负载均衡的能力。
首先需要安装 PM2 的依赖,一般会安装在全局依赖:
$ yarn global add pm2普通的前端项目启动的话,直接使用以下命令就行了:
pm2 start app.js但毕竟是这一个实战的项目而且也有不同的环境变量存在,直接这么启动并不合适,可以借助 Ecosystem File 来完成我们的需求。
- 项目根目录新建
ecosystem.config.js:
module.exports = {
apps: [
{
name: "gateway",
script: "dist/src/main.js",
env_production: {
RUNNING_ENV: "prod"
},
env_development: {
RUNNING_ENV: "dev"
}
}
]
}- 添加
package.json中的scripts构建命令:
+ "build": "nest build",
+ "build:webpack": "nest build --webpack",对比一下两种构建命令的不同点:
nest build:将NestJS项目的源码从TS编译成JS之后再使用node main.js来运行项目,这样有个好处是还能看到大概的工程路径,也可以使用TypeOrm动态注册实体类的功能。nest build --webpack会将NestJS项目打包成一个独立的main.js,从文件类型的角度来说,做了一次混淆跟合并,原理跟之前提到过的热更新启动是一样的,按照这种模式的话来使用的话,就不能使用动态注册实体类的功能,只能手动引入实体类。
两种构建产物的方式都可以完成要求,按照自己的喜好选择就行,但无论是 webpack 打包成单文件的模式还是使用 TSC 模式生成 JS 项目代码,都需要在发布工程里面添加 node_modules,否则是没办法正常启动。
因为这两种模式并没有将依赖直接打包进产物内,虽然可以曲线修改 webpack.config 可以使得在 webpack 模式下,能将所有的依赖都打入单文件,但是由于环境依赖的问题,这种模式的产物大概率只能在相同的环境运行依赖,例如 windows 下打包的产物是无法部署在 linux 环境下。
- 在
package.json的scripts中添加启动脚本:
+ "start:prod": "nest build && pm2 start ecosystem.config.js --env production"添加完毕之后,执行 yarn start:prod 出现如下界面既完成了项目生产环境的部署,如果不能正常访问接口的话,可以使用 pm2 log gateway 查看启动日志,如果按照我给的方案走一般不会出现问题,有问题的话,大概率是配置文件找不到,调整配置文件即可。
切记,如果使用 webpack 模式部署生产环境,一定要手动注册实体类!!!!不然会报错的!!!!
更多的 PM2 的 API 使用与黑科技,用兴趣的同学可以自己进行摸索,这里就不过多介绍了。
Docker Compose
Docker Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排日常开发工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。
比如我们的网关服务体系就由 3 个不同的服务组成,其中还不包括 Redis、Mysql 这种中间件的服务,所以每个服务都使用直接 Docker 来部署的话,效率低下而且维护麻烦,而借助 Docker Compose 可以将我们的服务统一一次性部署完成。
第一步:要把项目工程打包成 image,根路径创建文件 Dockerfile:
FROM node:16-alpine3.15
RUN mkdir -p /home/app/
WORKDIR /home/app/
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
ENTRYPOINT ["npm", "run"]
CMD ["start"]第二步:根目录运行以下脚本来就行构建:
$ docker build -f ./Dockerfile -t gateway:0.0.1 .第三步:运行以下命令既可以启动容器运行:
docker run -d -e RUNNING_ENV=prod -p 3000:3000 gateway:0.0.1使用 docker logs [容器id] 既可以看到我们的项目已经正常启动了:
以上是直接使用 Docker 来部署项目,换成 Docker Compose 的话,则需要额外新建文件 docker-compose.gateway-service-dev.yml:
version: "3"
services:
gateway-service-dev:
container_name: gateway-service-dev
build:
context: ./
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
RUNNING_ENV: 'dev'
networks:
- servicebus
networks:
servicebus:
name: servicebus启动命令为:
docker-compose -f docker-compose.gateway-service-dev.yml up -d --build其中 build 参数代表构建过程,所以我们在使用 docker-compose 构建的时候可以省去第二步构建镜像的步骤,配合 docker file 中的前置安装依赖步骤,可以在每次更新代码后需要重新构建时,项目依赖不更新的情况下,使用缓存构建,大幅度减少构建时间。
写在最后
部署篇的章节为了方便大家快速使用,目前较为简单,等待所有的项目都完成之后,会在 docker compose 部分扩充内容,给大家展示容器编排的优势。
另外如果有机会或者想尝试 K8S 部署的话,可以参考 Devops 的小册,里面有 Rancher 章节是关于集群部署的
如果你有什么疑问,欢迎在评论区提出或者加群沟通。 👏
