本系列教程将教你使用 NestJS 构建一个生产级别的 REST API 风格的权限管理后台服务【代码仓库地址】。
【在线预览地址】账号:test,密码:d.12345
本章节内容: 1. 在云服务器上独立部署 Minio 服务;2. 添加生产环境相关配置; 3. 在云服务器上部署项目。
前言
- 云服务器厂商:腾讯云
- 云服务器系统:ubuntu 22.04 + docker
- 远程连接工具:Termius
1. 在云服务器上独立部署 Minio 服务
在云服务器中新建一个 /home/ubuntu/minio/docker-compose.yml
文件并添加以下内容:
yml
services:
minio:
image: bitnami/minio:latest
ports:
- "9000:9000"
- "9001:9001"
volumes:
- minio_data:/data
environment:
MINIO_ROOT_USER: xxx # 用户名
MINIO_ROOT_PASSWORD: xxx # 密码
MINIO_DEFAULT_BUCKETS: avatar
command: /opt/bitnami/scripts/minio/run.sh --console-address ":9001"
restart: unless-stopped
volumes:
minio_data:
然后在该目录下执行 sudo docker-compose up -d --build
命令,没有报错则成功构建了 Minio 服务。
最后还要在腾讯云的服务器控制台的防火墙中放开 9001
端口,然后在浏览器地址栏中输入地址,进入 Minio 后台设置相关内容(前面的章节有讲)。
注意:没有域名可能会访问不了 Minio 管理后台。因为现在好像都不支持直接通过IP地址访问网站了,所以你没有域名的话,可以跳过这个。
2. 添加生产环境相关配置
2.1 添加 Dockerfile 文件
在项目根目录下新建 Dockerfile
文件并添加以下内容:
yaml
###################
# BUILD
###################
FROM node:20-slim AS build
WORKDIR /usr/src/app
# 首先复制 package.json 文件,利用 Docker 缓存机制
COPY package*.json ./
# 安装依赖,并添加 --no-cache 参数 (如果在服务器上构建时间过久,可以指定使用淘宝源)
RUN npm install --no-cache
# 复制源代码
COPY . .
# 将构建与 Prisma 生成合并为一个 RUN 命令
RUN npm run prisma:generate && \
npm run build && \
npm prune --production
###################
# PRODUCTION
###################
FROM node:20-slim AS production
# 设置工作目录和环境变量
WORKDIR /usr/src/app
ENV NODE_ENV=production
# 安装运行时依赖(合并为单个 RUN 命令)
RUN apt-get update -y && \
apt-get install -y --no-install-recommends openssl ca-certificates && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
mkdir -p /usr/src/app/logs
# 复制应用文件(按照变更频率排序,不常变动的文件放前面)
COPY --chown=node:node --from=build /usr/src/app/node_modules ./node_modules
COPY --chown=node:node prisma ./prisma
COPY --chown=node:node --from=build /usr/src/app/package*.json ./
COPY --chown=node:node --from=build /usr/src/app/tsconfig.json ./
COPY --chown=node:node --from=build /usr/src/app/dist ./dist
COPY --chown=node:node .env.production.local ./
COPY --chown=node:node key ./key
# 全局安装 dotenv-cli 并重新生成 Prisma Client(合并为单个 RUN 命令)
RUN npm install -g dotenv-cli && \
npx prisma generate && \
chown -R node:node /usr/src/app
# 切换到非 root 用户
USER node
# 注意 build 后的目录结构
CMD ["node", "dist/src/main.js"]
openssl
等一些包,是 Prisma 需要用到的。
为什么要全局安装 dotenv-cli
?因为构建命令里使用到了该库,如 build 命令 dotenv -e .env.production.local -- nest build
。
2.2 添加生产 docker-compose 文件
在项目根目录下新建 docker-compose.prod.yml
文件并添加以下内容:
yaml
name: admin
services:
admin_services_prod:
container_name: admin-service-prod
restart: on-failure:6 # 失败后,自动重启 6 次
env_file: .env.production.local
build:
context: .
dockerfile: Dockerfile
target: production # 使用多阶段构建的目标阶段
ports:
- "${PORT:-3000}:3000"
depends_on:
- admin_postgres
- admin_redis
command: sh -c "npm run migrate:deploy && node dist/prisma/seed.js && node dist/src/main.js"
admin_postgres: # 将这个名字填入生产 env 文件中的 DB_HOST 变量中
image: postgres:15
restart: on-failure:6
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "${DB_PORT:-5432}:5432"
volumes:
- admin_postgres_data:/var/lib/postgresql/data
admin_redis: # 将这个名字填入生产 env 文件中的 REDIS_HOST 变量中
image: redis:6
restart: on-failure:6
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- admin_redis_data:/data
volumes:
admin_postgres_data:
admin_redis_data:
npm run migrate:deploy
执行数据库迁移命令。
node dist/prisma/seed.js
执行种子文件,向数据库里插入默认数据。
2.3 添加生产环境 env 文件
在项目根目录下新建一个 .env.production.local
文件,然后将开发环境的配置复制过去,最后修改数据库用户、密码等一些关键值。例如:
env
# redis
REDIS_PORT=6379
REDIS_HOST="admin_redis" # 对应容器名称
REDIS_URL="redis://${REDIS_HOST}:${REDIS_PORT}"
注意:记得将 Minio 服务的 MINIO_END_POINT 改成具体的 IP(服务器内网IP),不要使用 localhost。相关的 key 也要改成生产环境的。
因为我们的 NestJS 项目也是使用 Docker 部署的,而在 Docker 中无法通过 localhost 访问其他容器服务。
2.4 修改 package.json
向该文件里添加两个生产构建命令:
json
"build": "dotenv -e .env.production.local -- nest build",
"migrate:deploy": "dotenv -e .env.production.local -- npx prisma migrate deploy"
因为我们在 env
文件里使用了特殊的变量拼接语法,所以需要使用 dotenv
库来解析。
现在,我们可以先在本地机器上执行 docker-compose -f docker-compose.prod.yml --env-file .env.production.local up --build
命令构建容器服务。构建完成后,可以测试一下,如果没有问题,则可以开始部署到服务器了。
注意:要在项目根目录下执行以上命令构建服务。
3. 在云服务器上部署项目
将下图中的所有文件复制到云服务器中:
key 文件可以在服务器中生成,如何生成,前面章节也有讲。
然后进入该文件夹中,运行以下命令:
ts
sudo docker-compose --env-file ./.env.production.local up -d --build
注意:这里为什么没有使用
-f docker-compose.prod.yml
指定文件?因为我将云服务器中的docker-compose.prod.yml
文件重命名为docker-compose.yml
了,所以不需要使用 '-f' 指定文件。
等待构建完成后,进入腾讯云的云服务器控制台放开对应端口号即可。
在浏览器地址栏中输入你的服务器IP地址+验证码接口地址,如果能正确返回验证码数据,则表示服务部署成功了。
如果你想要前端项目访问这里获取,里面包含前端构建相关内容,如使用 Nginx 代理转发等。