# PM2 手动部署工作流 # 手动触发 → 构建前后端 → rsync 同步 → 服务器执行 PM2 重载 # # 前置准备: # 1. 服务器需安装 PM2: npm i -g pm2 # 2. 服务器需预先启动 MySQL # 3. 在 Gitea 仓库 Settings → Secrets 中配置以下密钥: # - SSH_PRIVATE_KEY : 部署用 SSH 私钥 # - SSH_HOST : 服务器地址 # - SSH_USER : SSH 用户名 # - SSH_PORT : SSH 端口(默认 22,可选) # - REMOTE_DIR : 服务器上的项目目录,如 /opt/gongxue name: PM2 部署 on: workflow_dispatch: inputs: skip_build: description: '跳过构建(仅同步 + PM2 重载)' required: false type: boolean default: false jobs: deploy: runs-on: ubuntu-latest steps: - name: 检出代码 uses: actions/checkout@v4 - name: 安装 Node.js uses: actions/setup-node@v4 with: node-version: '22' - name: 安装依赖 & 构建 if: ${{ !inputs.skip_build }} run: | npm ci npm run build -w @gongxue/server npm run build -w @gongxue/admin - name: 配置 SSH run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key chmod 600 ~/.ssh/deploy_key cat >> ~/.ssh/config <<'EOF' Host deploy-server HostName ${{ secrets.SSH_HOST }} User ${{ secrets.SSH_USER }} Port ${{ secrets.SSH_PORT || '22' }} IdentityFile ~/.ssh/deploy_key StrictHostKeyChecking accept-new EOF - name: 同步代码到服务器 run: | rsync -avz --delete \ --exclude='node_modules' \ --exclude='.git' \ --exclude='*.db' \ --exclude='.DS_Store' \ --exclude='logs/' \ --exclude='.turbo/' \ --exclude='.claude/' \ --exclude='.codegraph/' \ ./ deploy-server:${{ secrets.REMOTE_DIR }}/ - name: 安装依赖 & 数据库迁移 run: | ssh deploy-server " cd ${{ secrets.REMOTE_DIR }} mkdir -p logs if [ ! -d node_modules ]; then echo '首次部署,安装生产依赖...' npm ci --omit=dev fi echo '执行数据库迁移...' npm run migration:run -w @gongxue/server || echo '迁移跳过(无变更或已是最新)' " - name: PM2 重载 run: | ssh deploy-server " cd ${{ secrets.REMOTE_DIR }} pm2 startOrReload ecosystem.config.cjs --update-env pm2 save echo '=== PM2 进程状态 ===' pm2 status "