NestJS 项目实战-权限管理系统开发终章

本系列教程将教你使用 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 代理转发等。

相关推荐
老马啸西风4 小时前
Occlum 是一个内存安全的、支持多进程的 library OS,特别适用于 Intel SGX。
网络·后端·算法·阿里云·云原生·中间件·golang
冯浩(grow up)9 小时前
Spring Boot 连接 MySQL 配置参数详解
spring boot·后端·mysql
Asthenia04129 小时前
面试复盘:left join 底层算法(嵌套/哈希/分块) & 主从复制(异步/半同步/同步)
后端
秋野酱9 小时前
基于javaweb的SpringBoot雪具商城系统设计与实现(源码+文档+部署讲解)
java·spring boot·后端
还是鼠鼠9 小时前
认识 Express.js:Node.js 最流行的 Web 框架
开发语言·前端·javascript·vscode·node.js·json·express
计算机-秋大田9 小时前
基于Spring Boot的ONLY在线商城系统设计与实现的设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·课程设计
爱的叹息9 小时前
spring boot + thymeleaf整合完整例子
java·spring boot·后端
Asthenia041210 小时前
MySQL:意向锁与兼容性/MySQL中的锁加在什么上?/innodb中锁的底层是怎么实现的?
后端
程序猿DD_10 小时前
如何用Spring AI构建MCP Client-Server架构
java·人工智能·后端·spring·架构
小兵张健11 小时前
Cursor 嵌入产研 —— 从产品背景到后端代码实现
后端·ai编程·cursor