一. 首先创建nestjs项目!!!
二. 创建dockerHob账号,创建好对应的仓库(一会用到),创建好对应的gitHob仓库,连接上新创建的nestjs项目!!!
三. 准备好各类的环境(docker、 docker-compose、node、pm2、pnpm! 本地和线上服务器都创建好,虽然有些时候可能不一定会用到,但是万一用到了呢!)
(不会上述三点的可以去查一下!!! )
四. 要开始实际操作了,第一步先去写github-action的自动化流程脚本
(1)、打开刚才创建好的nestjs项目,
(2)、在根目录中创建一个.githob的文件夹,在.githob文件夹中创建workflows文件夹(这个workflows也可以不创建),之后创建一个main.yml的脚本文件(这个脚本文件可以随便叫任何名字)创建好后目录是这个样子
(3)、现在开始写main.yml的脚本内容了
# 自动化流程项目的名字,你在提交代码没有任何备注,就会默认使用这个
name: gitHob action test
on:
push: # 当代码推送到远程仓库时触发
branches: ['main'] # 只有在 main 分支上推送时触发
tags: # 根据标签触发
- '*.*.*' # 匹配任意格式的标签
pull_request: # 当有 Pull Request 时触发
branches: ['main'] # 只有在 main 分支上发起 Pull Request 时触发
# 一个脚本工作的执行流程,可以有多个 jobs 流程
jobs:
build_test:
name: 创建 sky 项目镜像
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# 安装node.js
- name: 安装node.js
uses: actions/setup-node@v3
with:
node-version: '18.18.2'
# 下载依赖、打包项目
- name: 下载依赖、打包项目
run: |
npm install -g pnpm # 全局安装 pnpm
pnpm install # 安装依赖
pnpm run build:all # 打包项目
- name: 复制package.json文件
run: |
cp -r package*.json ./dist # 复制 package.json 文件到 ./dist 目录
- name: 复制docker-compose.yml文件
run: |
cp -r docker-compose.yml ./dist # 复制 docker-compose.yml 文件到 ./dist 目录
- name: 复制Dockerfile文件
run: |
cp -r Dockerfile ./dist # 复制 Dockerfile 文件到 ./dist 目录
- name: 复制ecosystem.config.js文件
run: |
cp -r ecosystem.config.js ./dist # 复制 ecosystem.config.js 文件到 ./dist 目录
# 部署到服务器
- name: SSH登录到腾讯云服务器
uses: appleboy/scp-action@master
with:
# 服务器域名
host: ${{ secrets.TENCENT_IP }}
# 服务器用户名
username: ${{ secrets.TENCENT_USERNAME }}
# 服务器密码
password: ${{ secrets.TENCENT_PASSWORD }}
# 服务器端口
port: 22
# 指定上传的文件目录(需要看gitHob上的文件目录,而不是本地目录)
source: './dist'
# 指定上传服务器目录
target: '/www/wwwroot/code/service/nestjs/test'
# 解压时覆盖现有文件
overwrite: true
# 删除指定数量的前导路径元素
strip_components: 1
# 这一步可能没有用,但是我不想删了,你们随意
- name: 登陆到 Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2 # 这个是官方提供的插件,网上可以查到用法
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Docker Build
uses: appleboy/ssh-action@master # 这个是官方提供的插件,网上可以查到用法
with:
host: ${{ secrets.TENCENT_IP }}
username: ${{ secrets.TENCENT_USERNAME }}
password: ${{ secrets.TENCENT_PASSWORD }}
port: 22
# 脚本命令
script: |
cd /www/wwwroot/code/service/nestjs/test/dist # 切换到项目目录
# 如果说你要打包 docker 镜像 就解开下面的注释
# echo "${{ secrets.DOCKER_TOKEN }}" | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
# docker build -t 换成你自己的dockerHob仓库的名字:tag -f ./Dockerfile .
# docker push 换成你自己的dockerHob仓库的名字:tag
# 在这里添加您要在服务器上执行的命令,比如:
docker-compose up -d # 启动容器
nvm use 16.20.2 # 使用 Node.js 版本 16.20.2
pnpm install # 安装依赖
pnpm run start:prod:pm2:all # 启动应用
(main.yml文件中使用的secrets.TENCENT_IP、secrets.TENCENT_USERNAME ... ! 这些都是在当前nestjs项目创建githob仓库中创建保存的, 打开对应的仓库代码 ---> Settings ---> Secrets and variables ---> Actions ---> Secrets, 去点击按钮创建对应的变量即可)
五、在根目录创建编写Dockerfile、docker-compose.yml文件
(1)、 先写Dockerfile
注意看哈,我这个Dockerfile是上传到服务器的,所以说里面的文件目录不是本地的文件目录结构(因为我不想把nestjs项目打包的docker镜像,我只是想用mysql等等, 所以我改了Dockerfile文件)
# 创建环境
FROM node:18-alpine
# 设置工作目录
RUN mkdir -p /sky
WORKDIR /sky
# 这里的apps是我打包后上传到服务器的dist/apps
COPY apps /sky
# 复制当前代码到/sky工作目录
COPY package*.json /sky
# 复制PM2配置文件
COPY ecosystem.config.js /sky
# 安装依赖加打包
RUN npm i -g pnpm
RUN pnpm i
RUN pnpm i pm2
# 启动服务
CMD pnpm run start:prod:pm2:all
(2)、现在写docker-compose.yml文件
这个文件中就要看你是否在Dockerfile文件中把你的nestjs项目打包Build成镜像?
services:
# 如果你已经在Dockerfile文件把项目打包成了镜像,并且也准备使用镜像项目,那你就把注释掉的解开,换成你自己的
# test:
# container_name: 'test' # 指定容器名
# image: 换成你自己的dockerHob仓库的名字:tag
# depends_on:
# - test-mysql # 依赖的MySQL服务
# - test-redis # 依赖的Redis服务
# ports:
# - '13000:13000' # 端口映射,宿主机端口:容器端口
# restart: on-failure # 失败时重启
# networks:
# - test-server # 连接的网络
test-mysql:
container_name: 'docker-nest-mysql' # 指定容器名
image: mysql:8.0.27 # MySQL镜像版本
ports:
- '15000:3306' # 端口映射,宿主机端口:容器端口
environment:
MYSQL_DATABASE: test-mysql # 指定数据库名称
MYSQL_ROOT_PASSWORD: **** # MySQL密码
volumes:
- /www/wwwroot/db/mysql:/var/lib/mysql # 挂载数据卷,宿主机路径:容器路径
networks:
- test-server # 连接的网络
test-redis:
container_name: 'docker-nest-redis' # 指定容器名
image: redis:6.2.6 # Redis镜像版本
ports:
- '15010:6379' # 端口映射,宿主机端口:容器端口
volumes:
- /www/wwwroot/db/redis/redis.conf:/etc/redis/redis.conf # 挂载数据卷,宿主机路径:容器路径
networks:
- test-server # 连接的网络
networks:
test-server:
driver: bridge # 网络驱动类型
六、修改package.json配置,在根目录创建pm2的配置文件ecosystem.config.js
(1)、 修改package.json配置,因为我创建的nestjs微服务的项目结构(微服务怎么创建可以去看这个NestJS的微服务实现_nestjs微服务实现网关服务转发请求-CSDN博客)、(当然你不想用微服务,package.json是可以不用修改的,前提是你配置好了, 开发环境与生产环境)
"scripts": {
"build:all": "pnpm run build:test && pnpm run build:m-ai && pnpm run build:m-imt && pnpm run build:m-tool",
"build:test": "cross-env NODE_ENV=prod nest build -- test-service", // 这个是微服务的主项目
"build:m-ai": "cross-env NODE_ENV=prod nest build -- m-ai", // 微服务子项目
"build:m-imt": "cross-env NODE_ENV=prod nest build -- m-imt", // 微服务子项目
"build:m-tool": "cross-env NODE_ENV=prod nest build -- m-tool", // 微服务子项目
"format": "prettier --write \"apps/**/*.ts\" \"libs/**/*.ts\"",
"start": "nest start",
"start:dev": "cross-env NODE_ENV=dev nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod:all": "concurrently \"pnpm run start:prod\" \"pnpm run start:prod:m-ai\" \"pnpm run start:prod:m-imt\" \"pnpm run start:prod:m-tool\"",
"start:prod": "cross-env NODE_ENV=prod node dist/apps/test-service/main", // 这个是微服务的主项目
"start:prod:m-imt": "cross-env NODE_ENV=prod node dist/apps/m-imt/main", // 微服务子项目
"start:prod:m-tool": "cross-env NODE_ENV=prod node dist/apps/m-tool/main", // 微服务子项目
"start:prod:m-ai": "cross-env NODE_ENV=prod node dist/apps/m-ai/main", // 微服务子项目
"start:prod:pm2:all": "pm2 start ecosystem.config.js", 这个是 pm2 集成的启动命令
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./apps/sky-service/test/jest-e2e.json"
},
修改package.json配置的
一键打包所有服务:pnpm run build:all
一键启动所有所有服务:pnpm run start:prod:all (这个是线上环境,我没有配置开发环境,想配置的,自己去研究一下。 另外这个一键启动用到了一个工具可以直接下载, 下载命令是 pnpm i concurrently, 我在pnpm run start:prod:all 这个命令处用到了)
pm2 集成的启动命令:pnpm run start:prod:pm2:all (这个集成依赖的是ecosystem.config.js文件,下面来创建这个文件)
(2)、创建编写ecosystem.config.js文件
ecosystem.config.js这个文件的配置信息有很多,想具体配置的去学习pm2官网(PM2 - Quick Start),我这里就只配置到把项目启动
module.exports = {
apps: [
{
// 应用程序名称
name: 'test',
// 执行文件
script: 'dist/apps/sky-service/main.js',
},
{
name: 'm-ai',
script: 'dist/apps/m-ai/main.js',
},
{
name: 'm-imt',
script: 'dist/apps/m-imt/main.js',
},
{
name: 'm-tool',
script: 'dist/apps/m-tool/main.js',
}
]
};