Skip to content

feat(deploy): 添加服务器端直接构建部署脚本 #4

feat(deploy): 添加服务器端直接构建部署脚本

feat(deploy): 添加服务器端直接构建部署脚本 #4

# ============================================================
# GitHub Actions - 网站部署 (Website)
# ============================================================
name: Deploy Website
on:
push:
branches: [main, develop]
paths:
- 'website/**'
- '.github/workflows/deploy-website.yml'
workflow_dispatch:
env:
NODE_VERSION: '22'
DEPLOY_DIR: /var/www/qzt/website
PM2_APP_NAME: qzt-website
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: |
cd website
pnpm install --frozen-lockfile
- name: Build Website
run: |
cd website
pnpm run build
env:
NEXT_PUBLIC_API_BASE_URL: https://admin.devlovecode.com/api
- name: Create deployment package
run: |
# 检查 standalone 目录是否存在
if [ -d "website/.next/standalone" ]; then
tar -czf website-dist.tar.gz -C website/.next/standalone .
else
echo "警告: standalone 目录不存在,使用默认构建产物"
tar -czf website-dist.tar.gz -C website/.next .
fi
tar -czf website-public.tar.gz -C website/public .
- name: Setup SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to server
run: |
# 上传部署包
scp -o StrictHostKeyChecking=no website-dist.tar.gz \
root@${{ secrets.SERVER_HOST }}:/tmp/
scp -o StrictHostKeyChecking=no website-public.tar.gz \
root@${{ secrets.SERVER_HOST }}:/tmp/
ssh -o StrictHostKeyChecking=no root@${{ secrets.SERVER_HOST }} << 'ENDSSH'
set -e
DEPLOY_DIR="${{ env.DEPLOY_DIR }}"
BACKUP_DIR="/var/www/qzt/backups"
# 创建目录
mkdir -p $DEPLOY_DIR $BACKUP_DIR
# 备份
if [ -d "$DEPLOY_DIR/.next" ]; then
tar -czf $BACKUP_DIR/website-backup-$(date +%Y%m%d_%H%M%S).tar.gz -C $DEPLOY_DIR . 2>/dev/null || true
echo "备份已创建"
fi
# 解压新版本
rm -rf $DEPLOY_DIR/.next
rm -rf $DEPLOY_DIR/public
mkdir -p $DEPLOY_DIR
tar -xzf /tmp/website-dist.tar.gz -C $DEPLOY_DIR/
tar -xzf /tmp/website-public.tar.gz -C $DEPLOY_DIR/
rm /tmp/website-dist.tar.gz
rm /tmp/website-public.tar.gz
# 创建 server.js(如果不存在)
if [ ! -f "$DEPLOY_DIR/server.js" ]; then
cat > $DEPLOY_DIR/server.js << 'EOF'
const { createServer } = require('http')

Check failure on line 119 in .github/workflows/deploy-website.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/deploy-website.yml

Invalid workflow file

You have an error in your yaml syntax on line 119
const { parse } = require('url')
const next = require('./next/dist/bin/next')
const dev = false
const hostname = '0.0.0.0'
const port = 5180
const app = next({ dev, hostname, port })
const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer(async (req, res) => {
try {
const parsedUrl = parse(req.url, true)
await handle(req, res, parsedUrl)
} catch (err) {
console.error('Error occurred handling', req.url, err)
res.statusCode = 500
res.end('internal server error')
}
})
.once('error', (err) => {
console.error(err)
process.exit(1)
})
.listen(port, () => {
console.log(`> Ready on http://${hostname}:${port}`)
})
})
EOF
fi
# 重启 PM2 服务
pm2 restart ${{ env.PM2_APP_NAME }} || \
pm2 start $DEPLOY_DIR/server.js --name ${{ env.PM2_APP_NAME }}
# 保存 PM2 配置
pm2 save
echo "网站部署成功!"
ENDSSH
- name: Health check
run: |
sleep 10
curl -f https://devlovecode.com/health || exit 1
echo "健康检查通过!"