# PM2 本地 runner 手动部署工作流 # 手动触发 → 服务器本地 git pull → 构建 → 依赖安装 → 数据库迁移 → PM2 重载 # # 适用场景:Gitea runner 与生产服务器同机(本机直跑,不需要 SSH/Secrets)。 # # 前置准备: # 1. Gitea Actions 已开启,且已注册 self-hosted runner(runs-on 标签与下面一致) # 2. 服务器已 clone 仓库到部署目录(默认 /opt/gongxue,可用仓库 Variable REMOTE_DIR 覆盖) # 3. 服务器已安装 Node 22 + PM2(npm i -g pm2),MySQL 已运行 # 4. runner 运行账户对部署目录有写权限、可执行 npm/pm2 # # 关于 .env:不需要配置在 Gitea 界面。.env 只放在服务器部署目录下, # git pull 不会覆盖它,PM2/Nest 启动时直接读取服务器上的 .env。 # # 关于“在 docker 里构建/迁移”: # - 如果 runner 以“宿主机进程”方式运行(推荐,最省事):本 workflow 的 # npm ci / build / migration 直接在宿主机执行,pm2 直接操作宿主 pm2。 # - 如果 runner 跑在 docker 容器里:需要把部署目录挂载进容器 # (如 -v /opt/gongxue:/opt/gongxue),构建/迁移在容器内完成; # PM2 重载则必须打到宿主机(挂载 docker.sock 后 docker exec 到宿主, # 或在宿主机单独跑 pm2 服务端)——容器里的 pm2 管理不了宿主进程。 name: PM2 本地部署 on: workflow_dispatch: inputs: seed_roles: description: '强制播种 RBAC 权限码(首次部署或新增权限码时勾选,跑完会自动去掉)' required: false default: false type: boolean concurrency: group: deploy-local cancel-in-progress: false jobs: deploy: runs-on: self-hosted # 改为你注册 runner 时使用的 label(如 ubuntu-latest) steps: - name: 拉取最新代码 run: | cd ${{ vars.REMOTE_DIR || '/opt/gongxue' }} git fetch origin git checkout main git pull origin main - name: 安装依赖 & 构建 run: | cd ${{ vars.REMOTE_DIR || '/opt/gongxue' }} npm ci npm run build -w @gongxue/server npm run build -w @gongxue/admin - name: 执行数据库迁移 run: | cd ${{ vars.REMOTE_DIR || '/opt/gongxue' }} npm run migration:run -w @gongxue/server - name: PM2 重载 run: | cd ${{ vars.REMOTE_DIR || '/opt/gongxue' }} if [ "${{ github.event.inputs.seed_roles }}" = "true" ]; then echo '>>> 强制播种 RBAC 权限码(本次进程带 SEED_ROLES=true)' SEED_ROLES=true pm2 startOrReload ecosystem.config.cjs --only gongxue-backend --update-env pm2 restart gongxue-backend --update-env # 去掉 SEED_ROLES 正常重启 else pm2 startOrReload ecosystem.config.cjs --update-env fi pm2 save pm2 status - name: 健康检查 run: | cd ${{ vars.REMOTE_DIR || '/opt/gongxue' }} sleep 3 code="$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:3000/api/dashboard/stats || true)" echo "后端 HTTP 状态: ${code}(401=正常,接口需登录)" if [ "${code}" != "401" ] && [ "${code}" != "200" ]; then echo "健康检查失败:后端未按预期响应" >&2 exit 1 fi