Merge pull request #329 from qinfendebingshuo/copilot/setup-agent-auto-flow
feat: Awen domain reverse proxy — nginx config, deploy workflow, registry updates
This commit is contained in:
commit
59072c7bc7
|
|
@ -0,0 +1,473 @@
|
|||
name: '🌐 Awen域名反向代理 · 部署与监控'
|
||||
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
# Awen 域名反向代理部署工作流
|
||||
# 编号: ZY-WF-AWEN-PROXY
|
||||
# 守护: 铸渊 · ICE-GL-ZY001
|
||||
# 版权: 国作登字-2026-A-00037559
|
||||
#
|
||||
# 架构:
|
||||
# 用户 → Awen域名(DNS→新加坡) → ZY-SVR-002 Nginx → Awen广州后端
|
||||
#
|
||||
# 功能:
|
||||
# 1. deploy — 部署/更新 Nginx 反向代理配置到 ZY-SVR-002
|
||||
# 2. setup-ssl — 为 Awen 域名申请 Let's Encrypt SSL 证书
|
||||
# 3. health — 检查代理链路健康状态(代理→后端→SSL)
|
||||
# 4. rollback — 回滚到上一份 Nginx 配置
|
||||
#
|
||||
# 所需 GitHub Secrets:
|
||||
# ZY_SERVER_HOST — ZY-SVR-002 新加坡服务器 IP
|
||||
# ZY_SERVER_KEY — ZY-SVR-002 SSH 私钥
|
||||
# ZY_SERVER_USER — ZY-SVR-002 SSH 用户名
|
||||
# AWEN_DOMAIN — Awen 的域名 (如: example.com)
|
||||
# AWEN_BACKEND_HOST — Awen 广州服务器 IP
|
||||
# AWEN_BACKEND_PORT — Awen 后端服务端口 (默认 80)
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'server/nginx/awen-domain-proxy.conf'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
action:
|
||||
description: '执行动作'
|
||||
required: true
|
||||
default: 'deploy'
|
||||
type: choice
|
||||
options:
|
||||
- deploy
|
||||
- setup-ssl
|
||||
- health
|
||||
- rollback
|
||||
|
||||
concurrency:
|
||||
group: awen-domain-proxy
|
||||
cancel-in-progress: false
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
# ═══ §1 部署 Nginx 反向代理配置 ═══
|
||||
deploy:
|
||||
name: '🚀 部署反向代理'
|
||||
if: >
|
||||
github.event.inputs.action == 'deploy' ||
|
||||
github.event.inputs.action == '' ||
|
||||
github.event_name == 'push'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🔍 检查必要 Secrets'
|
||||
env:
|
||||
AWEN_DOMAIN: ${{ secrets.AWEN_DOMAIN }}
|
||||
AWEN_BACKEND_HOST: ${{ secrets.AWEN_BACKEND_HOST }}
|
||||
ZY_SERVER_HOST: ${{ secrets.ZY_SERVER_HOST }}
|
||||
run: |
|
||||
MISSING=""
|
||||
[ -z "$AWEN_DOMAIN" ] && MISSING="${MISSING}AWEN_DOMAIN "
|
||||
[ -z "$AWEN_BACKEND_HOST" ] && MISSING="${MISSING}AWEN_BACKEND_HOST "
|
||||
[ -z "$ZY_SERVER_HOST" ] && MISSING="${MISSING}ZY_SERVER_HOST "
|
||||
if [ -n "$MISSING" ]; then
|
||||
echo "❌ 缺少必要的 GitHub Secrets: $MISSING"
|
||||
echo ""
|
||||
echo "═══ 配置指南 ═══"
|
||||
echo "请在仓库 Settings → Secrets → Actions 中添加:"
|
||||
echo " AWEN_DOMAIN — Awen的域名 (如: example.com)"
|
||||
echo " AWEN_BACKEND_HOST — Awen广州服务器IP"
|
||||
echo " AWEN_BACKEND_PORT — 后端端口 (默认80,可选)"
|
||||
echo " ZY_SERVER_HOST — 新加坡服务器IP (ZY-SVR-002)"
|
||||
echo " ZY_SERVER_KEY — 新加坡服务器SSH私钥"
|
||||
echo " ZY_SERVER_USER — 新加坡服务器SSH用户名"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ 所有必要 Secrets 已配置"
|
||||
|
||||
- name: '🔐 配置SSH'
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_KEY" > ~/.ssh/zy_key
|
||||
chmod 600 ~/.ssh/zy_key
|
||||
if head -1 ~/.ssh/zy_key | grep -q "BEGIN" && tail -1 ~/.ssh/zy_key | grep -q "END"; then
|
||||
echo "✅ SSH私钥格式正确"
|
||||
else
|
||||
echo "❌ SSH私钥格式异常"
|
||||
exit 1
|
||||
fi
|
||||
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
- name: '🔍 SSH连接测试'
|
||||
run: |
|
||||
ssh -i ~/.ssh/zy_key -o BatchMode=yes -o ConnectTimeout=10 \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||
'echo "✅ SSH连接成功 · $(hostname) · $(date)"'
|
||||
|
||||
- name: '📦 生成并部署 Nginx 配置'
|
||||
env:
|
||||
AWEN_DOMAIN: ${{ secrets.AWEN_DOMAIN }}
|
||||
AWEN_BACKEND_HOST: ${{ secrets.AWEN_BACKEND_HOST }}
|
||||
AWEN_BACKEND_PORT: ${{ secrets.AWEN_BACKEND_PORT }}
|
||||
run: |
|
||||
BACKEND_PORT="${AWEN_BACKEND_PORT:-80}"
|
||||
|
||||
echo "═══ Awen 域名反向代理部署 ═══"
|
||||
echo "域名: ${AWEN_DOMAIN}"
|
||||
echo "后端: ${AWEN_BACKEND_HOST}:${BACKEND_PORT}"
|
||||
echo "代理服务器: ZY-SVR-002 (新加坡)"
|
||||
echo ""
|
||||
|
||||
# 复制模板并注入实际值
|
||||
cp server/nginx/awen-domain-proxy.conf /tmp/awen-domain-proxy.conf
|
||||
sed -i "s/AWEN_DOMAIN_PLACEHOLDER/${AWEN_DOMAIN}/g" /tmp/awen-domain-proxy.conf
|
||||
sed -i "s/AWEN_BACKEND_HOST_PLACEHOLDER/${AWEN_BACKEND_HOST}/g" /tmp/awen-domain-proxy.conf
|
||||
sed -i "s/AWEN_BACKEND_PORT_PLACEHOLDER/${BACKEND_PORT}/g" /tmp/awen-domain-proxy.conf
|
||||
|
||||
echo "📋 生成的配置:"
|
||||
cat /tmp/awen-domain-proxy.conf
|
||||
echo ""
|
||||
|
||||
# 检查主配置是否已有 connection_upgrade map
|
||||
# 如果有则移除本配置中的 map 块避免冲突
|
||||
HAS_MAP=$(ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||
"grep -l 'map.*http_upgrade.*connection_upgrade' /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf /etc/nginx/sites-available/*.conf 2>/dev/null | head -1" || true)
|
||||
|
||||
if [ -n "$HAS_MAP" ]; then
|
||||
echo "ℹ️ 主配置已包含 connection_upgrade map,移除本配置中的重复定义"
|
||||
sed -i '/^# ─── WebSocket 升级映射/,/^}$/d' /tmp/awen-domain-proxy.conf
|
||||
sed -i '/^map \$http_upgrade/,/^}$/d' /tmp/awen-domain-proxy.conf
|
||||
fi
|
||||
|
||||
# 备份现有配置(如果存在)
|
||||
ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||
"if [ -f /etc/nginx/sites-available/awen-proxy.conf ]; then
|
||||
sudo cp /etc/nginx/sites-available/awen-proxy.conf \
|
||||
/etc/nginx/sites-available/awen-proxy.conf.bak.\$(date +%Y%m%d%H%M%S)
|
||||
echo '✅ 已备份现有配置'
|
||||
fi
|
||||
sudo mkdir -p /opt/zhuyuan/data/logs /var/www/certbot"
|
||||
|
||||
# 上传配置
|
||||
scp -i ~/.ssh/zy_key \
|
||||
/tmp/awen-domain-proxy.conf \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/tmp/awen-domain-proxy.conf
|
||||
|
||||
# 安装并启用配置
|
||||
ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << 'DEPLOY_CMD'
|
||||
|
||||
set -e
|
||||
|
||||
# 安装配置
|
||||
sudo cp /tmp/awen-domain-proxy.conf /etc/nginx/sites-available/awen-proxy.conf
|
||||
sudo ln -sf /etc/nginx/sites-available/awen-proxy.conf /etc/nginx/sites-enabled/awen-proxy.conf
|
||||
|
||||
# 验证 Nginx 配置
|
||||
echo "🔍 验证 Nginx 配置..."
|
||||
if sudo nginx -t 2>&1; then
|
||||
echo "✅ Nginx 配置验证通过"
|
||||
sudo systemctl reload nginx
|
||||
echo "✅ Nginx 已重载"
|
||||
else
|
||||
echo "❌ Nginx 配置验证失败"
|
||||
# 回滚
|
||||
sudo rm -f /etc/nginx/sites-enabled/awen-proxy.conf
|
||||
LATEST_BAK=$(ls -t /etc/nginx/sites-available/awen-proxy.conf.bak.* 2>/dev/null | head -1)
|
||||
if [ -n "$LATEST_BAK" ]; then
|
||||
sudo cp "$LATEST_BAK" /etc/nginx/sites-available/awen-proxy.conf
|
||||
sudo ln -sf /etc/nginx/sites-available/awen-proxy.conf /etc/nginx/sites-enabled/awen-proxy.conf
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
echo "↩️ 已回滚到上一份配置"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DEPLOY_CMD
|
||||
|
||||
- name: '💚 部署后健康检查'
|
||||
env:
|
||||
AWEN_DOMAIN: ${{ secrets.AWEN_DOMAIN }}
|
||||
AWEN_BACKEND_HOST: ${{ secrets.AWEN_BACKEND_HOST }}
|
||||
AWEN_BACKEND_PORT: ${{ secrets.AWEN_BACKEND_PORT }}
|
||||
run: |
|
||||
BACKEND_PORT="${AWEN_BACKEND_PORT:-80}"
|
||||
echo "═══ 部署后健康检查 ═══"
|
||||
echo ""
|
||||
|
||||
# 检查 Nginx 是否正常
|
||||
ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||
"systemctl is-active nginx && echo '✅ Nginx运行中' || echo '❌ Nginx未运行'"
|
||||
|
||||
# 检查域名 HTTP 响应
|
||||
sleep 2
|
||||
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||
--resolve "${AWEN_DOMAIN}:80:${{ secrets.ZY_SERVER_HOST }}" \
|
||||
"http://${AWEN_DOMAIN}/" 2>/dev/null || echo "000")
|
||||
echo "HTTP 状态码 (通过代理): ${HTTP_CODE}"
|
||||
|
||||
if [ "$HTTP_CODE" = "000" ] || [ "$HTTP_CODE" = "502" ]; then
|
||||
echo "⚠️ 后端暂时不可达 (广州服务器可能未就绪)"
|
||||
echo " 代理配置已部署成功,待后端上线后自动生效"
|
||||
elif [ "$HTTP_CODE" -ge 200 ] && [ "$HTTP_CODE" -lt 400 ]; then
|
||||
echo "✅ 代理链路正常"
|
||||
else
|
||||
echo "⚠️ 状态码 ${HTTP_CODE} — 请检查后端服务"
|
||||
fi
|
||||
|
||||
# ═══ §2 SSL证书申请 ═══
|
||||
setup-ssl:
|
||||
name: '🔒 SSL证书配置'
|
||||
if: github.event.inputs.action == 'setup-ssl'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🔐 配置SSH'
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_KEY" > ~/.ssh/zy_key
|
||||
chmod 600 ~/.ssh/zy_key
|
||||
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
- name: '🔒 申请 Let''s Encrypt SSL 证书'
|
||||
env:
|
||||
AWEN_DOMAIN: ${{ secrets.AWEN_DOMAIN }}
|
||||
run: |
|
||||
if [ -z "$AWEN_DOMAIN" ]; then
|
||||
echo "❌ AWEN_DOMAIN 未配置"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🔒 为 ${AWEN_DOMAIN} 申请SSL证书"
|
||||
echo ""
|
||||
|
||||
ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << SSLCMD
|
||||
|
||||
set -e
|
||||
|
||||
# 安装 certbot(如未安装)
|
||||
if ! command -v certbot &> /dev/null; then
|
||||
echo "📦 安装 certbot..."
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y -qq certbot python3-certbot-nginx
|
||||
fi
|
||||
|
||||
# 确保 webroot 目录存在
|
||||
sudo mkdir -p /var/www/certbot
|
||||
|
||||
# 申请证书(使用 webroot 模式,不中断 Nginx)
|
||||
sudo certbot certonly \
|
||||
--webroot -w /var/www/certbot \
|
||||
-d ${AWEN_DOMAIN} \
|
||||
--non-interactive \
|
||||
--agree-tos \
|
||||
--email admin@${AWEN_DOMAIN} \
|
||||
--no-eff-email \
|
||||
|| {
|
||||
echo "⚠️ Webroot 模式失败,尝试 standalone 模式..."
|
||||
sudo certbot certonly \
|
||||
--nginx \
|
||||
-d ${AWEN_DOMAIN} \
|
||||
--non-interactive \
|
||||
--agree-tos \
|
||||
--email admin@${AWEN_DOMAIN} \
|
||||
--no-eff-email
|
||||
}
|
||||
|
||||
echo "✅ SSL证书申请成功"
|
||||
|
||||
# 更新 Nginx 配置添加 SSL
|
||||
CONF="/etc/nginx/sites-available/awen-proxy.conf"
|
||||
if [ -f "\$CONF" ] && ! grep -q "listen 443 ssl" "\$CONF"; then
|
||||
echo "📝 使用 certbot 自动配置 SSL..."
|
||||
sudo certbot --nginx -d ${AWEN_DOMAIN} --non-interactive --redirect 2>&1 || {
|
||||
echo "❌ certbot --nginx 配置失败,SSL未启用"
|
||||
exit 1
|
||||
}
|
||||
echo "✅ SSL 已通过 certbot --nginx 启用"
|
||||
else
|
||||
echo "ℹ️ SSL 配置已存在或配置文件不存在"
|
||||
fi
|
||||
|
||||
# 设置自动续期 cron
|
||||
if ! crontab -l 2>/dev/null | grep -q "certbot renew"; then
|
||||
(crontab -l 2>/dev/null; echo "0 3 1 * * certbot renew --quiet --post-hook 'systemctl reload nginx'") | crontab -
|
||||
echo "✅ SSL 自动续期 cron 已配置 (每月1日 03:00)"
|
||||
fi
|
||||
|
||||
SSLCMD
|
||||
|
||||
- name: '💚 SSL验证'
|
||||
env:
|
||||
AWEN_DOMAIN: ${{ secrets.AWEN_DOMAIN }}
|
||||
run: |
|
||||
echo "🔍 验证 HTTPS: https://${AWEN_DOMAIN}"
|
||||
sleep 3
|
||||
HTTP_CODE=$(curl -sf -o /dev/null -w "%{http_code}" "https://${AWEN_DOMAIN}/" 2>/dev/null || echo "000")
|
||||
echo "HTTPS状态码: ${HTTP_CODE}"
|
||||
if [ "$HTTP_CODE" != "000" ]; then
|
||||
echo "✅ HTTPS可访问"
|
||||
else
|
||||
echo "⚠️ HTTPS暂时不可访问 (可能需要等待DNS传播)"
|
||||
fi
|
||||
|
||||
# ═══ §3 健康检查 (代理+后端+SSL) ═══
|
||||
health:
|
||||
name: '💚 代理链路健康检查'
|
||||
if: github.event.inputs.action == 'health'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🔐 配置SSH'
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_KEY" > ~/.ssh/zy_key
|
||||
chmod 600 ~/.ssh/zy_key
|
||||
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
- name: '💚 全链路健康检查'
|
||||
env:
|
||||
AWEN_DOMAIN: ${{ secrets.AWEN_DOMAIN }}
|
||||
AWEN_BACKEND_HOST: ${{ secrets.AWEN_BACKEND_HOST }}
|
||||
AWEN_BACKEND_PORT: ${{ secrets.AWEN_BACKEND_PORT }}
|
||||
run: |
|
||||
BACKEND_PORT="${AWEN_BACKEND_PORT:-80}"
|
||||
echo "═══ Awen 域名代理 · 健康检查报告 ═══"
|
||||
echo "时间: $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
|
||||
echo ""
|
||||
|
||||
ISSUES=""
|
||||
|
||||
# §1 代理服务器 Nginx 状态
|
||||
echo "§1 代理服务器 (ZY-SVR-002 · 新加坡)"
|
||||
ssh -i ~/.ssh/zy_key -o ConnectTimeout=10 \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << 'HEALTH' || {
|
||||
echo "❌ 无法连接到代理服务器"
|
||||
ISSUES="${ISSUES}proxy_ssh_fail "
|
||||
}
|
||||
|
||||
echo " Nginx: $(systemctl is-active nginx 2>/dev/null || echo 'unknown')"
|
||||
echo " 配置: $([ -f /etc/nginx/sites-enabled/awen-proxy.conf ] && echo '✅ 已启用' || echo '❌ 未启用')"
|
||||
echo " 日志行数: $(wc -l < /opt/zhuyuan/data/logs/nginx-awen-proxy.log 2>/dev/null || echo 'N/A')"
|
||||
|
||||
# 检查 SSL 证书有效期
|
||||
if [ -f /etc/letsencrypt/live/${AWEN_DOMAIN}/fullchain.pem ]; then
|
||||
EXPIRY=$(openssl x509 -enddate -noout -in /etc/letsencrypt/live/${AWEN_DOMAIN}/fullchain.pem 2>/dev/null | cut -d= -f2)
|
||||
echo " SSL证书到期: ${EXPIRY:-unknown}"
|
||||
else
|
||||
echo " SSL证书: 未配置"
|
||||
fi
|
||||
|
||||
HEALTH
|
||||
|
||||
echo ""
|
||||
|
||||
# §2 后端可达性 (从代理服务器测试)
|
||||
echo "§2 后端服务器 (Awen · 广州)"
|
||||
if [ -n "$AWEN_BACKEND_HOST" ]; then
|
||||
BACKEND_CODE=$(ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||
"curl -sf -o /dev/null -w '%{http_code}' --connect-timeout 10 \
|
||||
http://${AWEN_BACKEND_HOST}:${BACKEND_PORT}/health 2>/dev/null || echo '000'" || echo "000")
|
||||
echo " 健康端点: ${BACKEND_CODE}"
|
||||
if [ "$BACKEND_CODE" = "000" ]; then
|
||||
echo " ❌ 后端不可达"
|
||||
ISSUES="${ISSUES}backend_unreachable "
|
||||
elif [ "$BACKEND_CODE" -ge 200 ] && [ "$BACKEND_CODE" -lt 400 ]; then
|
||||
echo " ✅ 后端正常"
|
||||
else
|
||||
echo " ⚠️ 后端异常 (${BACKEND_CODE})"
|
||||
ISSUES="${ISSUES}backend_error "
|
||||
fi
|
||||
else
|
||||
echo " ⏳ AWEN_BACKEND_HOST 未配置"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# §3 端到端测试 (通过域名访问)
|
||||
echo "§3 端到端测试 (通过域名)"
|
||||
if [ -n "$AWEN_DOMAIN" ]; then
|
||||
# HTTP
|
||||
E2E_HTTP=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||
--resolve "${AWEN_DOMAIN}:80:${{ secrets.ZY_SERVER_HOST }}" \
|
||||
"http://${AWEN_DOMAIN}/" 2>/dev/null || echo "000")
|
||||
echo " HTTP: ${E2E_HTTP}"
|
||||
|
||||
# HTTPS
|
||||
E2E_HTTPS=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||
"https://${AWEN_DOMAIN}/" 2>/dev/null || echo "000")
|
||||
echo " HTTPS: ${E2E_HTTPS}"
|
||||
else
|
||||
echo " ⏳ AWEN_DOMAIN 未配置"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "═══ 检查完成 ═══"
|
||||
|
||||
# 如果有严重问题,退出非0(可触发通知)
|
||||
if echo "$ISSUES" | grep -q "proxy_ssh_fail\|backend_unreachable"; then
|
||||
echo ""
|
||||
echo "⚠️ 发现问题: $ISSUES"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ═══ §4 回滚 ═══
|
||||
rollback:
|
||||
name: '↩️ 回滚配置'
|
||||
if: github.event.inputs.action == 'rollback'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: '🔐 配置SSH'
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_KEY" > ~/.ssh/zy_key
|
||||
chmod 600 ~/.ssh/zy_key
|
||||
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
- name: '↩️ 回滚到上一份配置'
|
||||
run: |
|
||||
ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} << 'ROLLBACK'
|
||||
|
||||
LATEST_BAK=$(ls -t /etc/nginx/sites-available/awen-proxy.conf.bak.* 2>/dev/null | head -1)
|
||||
if [ -n "$LATEST_BAK" ]; then
|
||||
echo "↩️ 回滚到: $LATEST_BAK"
|
||||
sudo cp "$LATEST_BAK" /etc/nginx/sites-available/awen-proxy.conf
|
||||
if sudo nginx -t 2>&1; then
|
||||
sudo systemctl reload nginx
|
||||
echo "✅ 回滚成功"
|
||||
else
|
||||
echo "❌ 回滚后配置仍无效"
|
||||
sudo rm -f /etc/nginx/sites-enabled/awen-proxy.conf
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
echo "⚠️ 已禁用 Awen 代理配置"
|
||||
fi
|
||||
else
|
||||
echo "❌ 没有可回滚的备份"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROLLBACK
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
# ═══════════════════════════════════════════════════════════
|
||||
# Awen 域名反向代理配置 · 新加坡中转
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
#
|
||||
# 编号: ZY-SVR-NGX-AWEN
|
||||
# 中转服务器: ZY-SVR-002 (43.134.16.246 · 新加坡)
|
||||
# 后端服务器: ZY-SVR-AWEN (广州 · Awen实际服务)
|
||||
# 守护: 铸渊 · ICE-GL-ZY001
|
||||
# 版权: 国作登字-2026-A-00037559
|
||||
#
|
||||
# 架构:
|
||||
# 用户浏览器 → Awen域名(DNS→新加坡IP)
|
||||
# → ZY-SVR-002 Nginx(本配置·反向代理)
|
||||
# → Awen广州服务器(实际服务)
|
||||
#
|
||||
# 域名未备案解决方案:
|
||||
# 域名DNS A记录指向新加坡IP → 无需中国大陆ICP备案
|
||||
# 新加坡Nginx将请求反向代理到广州后端
|
||||
# 延迟约30-50ms · 对Web应用可接受
|
||||
#
|
||||
# 占位符由 deploy workflow 自动替换:
|
||||
# AWEN_DOMAIN_PLACEHOLDER ← GitHub Secret: AWEN_DOMAIN
|
||||
# AWEN_BACKEND_HOST_PLACEHOLDER ← GitHub Secret: AWEN_BACKEND_HOST
|
||||
# AWEN_BACKEND_PORT_PLACEHOLDER ← GitHub Secret: AWEN_BACKEND_PORT
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
# ─── Awen 域名 · 反向代理到广州后端 ───
|
||||
server {
|
||||
listen 80;
|
||||
server_name AWEN_DOMAIN_PLACEHOLDER;
|
||||
|
||||
# ─── 安全头 ───
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header X-Server-Identity "ZY-SVR-002" always;
|
||||
add_header X-Proxy-Mode "awen-reverse-proxy" always;
|
||||
|
||||
# ─── 请求体大小限制 (允许文件上传) ───
|
||||
client_max_body_size 50m;
|
||||
|
||||
# ─── 主路由 · 反向代理到广州后端 ───
|
||||
location / {
|
||||
proxy_pass http://AWEN_BACKEND_HOST_PLACEHOLDER:AWEN_BACKEND_PORT_PLACEHOLDER;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
# ─── 请求头透传 ───
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
|
||||
# ─── WebSocket 支持 ───
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
|
||||
# ─── 超时设置 (跨境延迟考虑 · 新加坡↔广州) ───
|
||||
proxy_connect_timeout 15s;
|
||||
proxy_read_timeout 120s;
|
||||
proxy_send_timeout 60s;
|
||||
|
||||
# ─── 缓冲设置 ───
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 16k;
|
||||
proxy_buffers 4 32k;
|
||||
proxy_busy_buffers_size 64k;
|
||||
|
||||
# ─── 错误处理 · 后端不可达时返回友好页面 ───
|
||||
proxy_intercept_errors on;
|
||||
error_page 502 503 504 /awen_backend_unavailable.html;
|
||||
}
|
||||
|
||||
# ─── 健康检查端点 (不记录日志 · 减少噪音) ───
|
||||
location = /health {
|
||||
proxy_pass http://AWEN_BACKEND_HOST_PLACEHOLDER:AWEN_BACKEND_PORT_PLACEHOLDER/health;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_connect_timeout 5s;
|
||||
proxy_read_timeout 10s;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# ─── Let's Encrypt 证书验证路径 ───
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
allow all;
|
||||
}
|
||||
|
||||
# ─── 后端不可达时的友好错误页 ───
|
||||
location = /awen_backend_unavailable.html {
|
||||
internal;
|
||||
default_type text/html;
|
||||
return 502 '<!DOCTYPE html><html><head><meta charset="utf-8"><title>Service Temporarily Unavailable</title><style>body{font-family:sans-serif;text-align:center;padding:80px 20px;background:#f7f7f7}h1{color:#333}p{color:#666}</style></head><body><h1>503 Service Temporarily Unavailable</h1><p>The backend server is currently unreachable. Please try again later.</p><p style="font-size:12px;color:#999">Proxy: ZY-SVR-002 (Singapore) → Backend: Guangzhou</p></body></html>';
|
||||
}
|
||||
|
||||
# ─── 访问日志 · 独立文件便于监控 ───
|
||||
access_log /opt/zhuyuan/data/logs/nginx-awen-proxy.log;
|
||||
error_log /opt/zhuyuan/data/logs/nginx-awen-proxy-error.log;
|
||||
}
|
||||
|
||||
# ─── WebSocket 升级映射 ───
|
||||
# 注意: 此 map 块必须位于 http {} 上下文 (不在 server {} 内)
|
||||
# 如果 nginx.conf 或其他配置文件已定义 $connection_upgrade,
|
||||
# 部署 workflow 会自动检测并移除本段避免冲突
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
'' close;
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
"_sovereign": "TCS-0002∞ | SYS-GLW-0001",
|
||||
"_copyright": "国作登字-2026-A-00037559",
|
||||
"_description": "光湖语言世界 · 四台服务器注册表",
|
||||
"version": "1.0",
|
||||
"updated_at": "2026-04-07",
|
||||
"version": "1.1",
|
||||
"updated_at": "2026-04-10",
|
||||
"servers": [
|
||||
{
|
||||
"id": "ZY-SVR-002",
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
"status": "active",
|
||||
"services": [
|
||||
"nginx (静态文件·主站+预览站)",
|
||||
"nginx (Awen域名反向代理·新加坡→广州)",
|
||||
"xray (VLESS+Reality VPN)",
|
||||
"api (端口3800·主站)",
|
||||
"api-preview (端口3801·预览站)",
|
||||
|
|
@ -88,6 +89,20 @@
|
|||
"notes": "Awen下载完整仓库后部署·铸渊主控自动唤醒"
|
||||
}
|
||||
],
|
||||
"domain_proxy": {
|
||||
"description": "域名未备案反向代理 · 新加坡中转架构",
|
||||
"architecture": "用户 → 域名(DNS→SG) → ZY-SVR-002 Nginx → 广州后端",
|
||||
"proxy_server": "ZY-SVR-002",
|
||||
"domains": [
|
||||
{
|
||||
"owner": "Awen",
|
||||
"config_file": "server/nginx/awen-domain-proxy.conf",
|
||||
"workflow": ".github/workflows/deploy-awen-domain-proxy.yml",
|
||||
"secrets_required": ["AWEN_DOMAIN", "AWEN_BACKEND_HOST", "AWEN_BACKEND_PORT"],
|
||||
"status": "pending"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bandwidth_strategy": {
|
||||
"description": "四台服务器按用途分流·带宽最大化",
|
||||
"routing": {
|
||||
|
|
@ -98,7 +113,8 @@
|
|||
"claude_api_relay": "ZY-SVR-SV",
|
||||
"international_api": "ZY-SVR-SV",
|
||||
"awen_team": "ZY-SVR-AWEN",
|
||||
"zhiqiu_persona": "ZY-SVR-AWEN"
|
||||
"zhiqiu_persona": "ZY-SVR-AWEN",
|
||||
"awen_domain_proxy": "ZY-SVR-002 → ZY-SVR-AWEN"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,24 @@
|
|||
"server_code": null,
|
||||
"dns_provider": null,
|
||||
"architecture_role": "技术主控台·待配置",
|
||||
"status": "pending"
|
||||
"status": "pending",
|
||||
"reverse_proxy": {
|
||||
"enabled": true,
|
||||
"proxy_server": "ZY-SVR-002 (新加坡)",
|
||||
"backend_server": "ZY-SVR-AWEN (广州)",
|
||||
"reason": "域名未备案·通过新加坡服务器反向代理·免备案",
|
||||
"config_file": "server/nginx/awen-domain-proxy.conf",
|
||||
"deploy_workflow": ".github/workflows/deploy-awen-domain-proxy.yml",
|
||||
"setup_steps": [
|
||||
"1. 配置 GitHub Secret: AWEN_DOMAIN (Awen的域名)",
|
||||
"2. 配置 GitHub Secret: AWEN_BACKEND_HOST (广州服务器IP)",
|
||||
"3. 配置 GitHub Secret: AWEN_BACKEND_PORT (后端端口·默认80)",
|
||||
"4. Awen将域名DNS A记录指向新加坡服务器IP (ZY-SVR-002)",
|
||||
"5. 运行 workflow: deploy-awen-domain-proxy → deploy",
|
||||
"6. 运行 workflow: deploy-awen-domain-proxy → setup-ssl",
|
||||
"7. 广州服务器防火墙白名单添加新加坡IP"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue