fix: guanghulab.com无法打开 + guanghulab.online API不通
根因修复: 1. cn-domain.conf: server_name支持裸域名+www双变体 2. deploy-cn-landing.yml: 域名双变体处理 + setup-ssl动作(certbot) + SSL自动注入 3. deploy-to-zhuyuan-server.yml: push事件部署前端到production(guanghulab.online=主域名=production) 4. zhuyuan-sovereign.conf: /api/chat添加CORS头+X-Forwarded-Proto Agent-Logs-Url: https://github.com/qinfendebingshuo/guanghulab/sessions/80e337de-dabe-4e86-a711-62d4c47762ec Co-authored-by: qinfendebingshuo <207279273+qinfendebingshuo@users.noreply.github.com>
This commit is contained in:
parent
bf3dee555b
commit
6de783ad4f
|
|
@ -31,6 +31,7 @@ on:
|
|||
options:
|
||||
- deploy
|
||||
- health-check
|
||||
- setup-ssl
|
||||
|
||||
concurrency:
|
||||
group: cn-landing-deploy
|
||||
|
|
@ -123,11 +124,13 @@ jobs:
|
|||
cp server/nginx/cn-domain.conf /tmp/cn-domain.conf
|
||||
|
||||
if [ -n "$ZY_CN_DOMAIN" ]; then
|
||||
sed -i "s/ZY_CN_DOMAIN_PLACEHOLDER/${ZY_CN_DOMAIN}/g" /tmp/cn-domain.conf
|
||||
echo "✅ 国内域名已注入: ${ZY_CN_DOMAIN}"
|
||||
# 去除可能的 www. 前缀,获取裸域名
|
||||
BARE_DOMAIN="${ZY_CN_DOMAIN#www.}"
|
||||
sed -i "s/ZY_CN_BARE_DOMAIN_PLACEHOLDER/${BARE_DOMAIN}/g" /tmp/cn-domain.conf
|
||||
echo "✅ 国内域名已注入: ${BARE_DOMAIN} + www.${BARE_DOMAIN}"
|
||||
else
|
||||
echo "⚠️ ZY_CN_DOMAIN 未配置,使用IP直接访问"
|
||||
sed -i "s/ZY_CN_DOMAIN_PLACEHOLDER/_/g" /tmp/cn-domain.conf
|
||||
sed -i "s/ZY_CN_BARE_DOMAIN_PLACEHOLDER www.ZY_CN_BARE_DOMAIN_PLACEHOLDER/_/g" /tmp/cn-domain.conf
|
||||
fi
|
||||
|
||||
scp -F ~/.ssh/config \
|
||||
|
|
@ -157,8 +160,11 @@ jobs:
|
|||
echo "✅ 四大国内模型API密钥已注入"
|
||||
|
||||
- name: 🔧 启用Nginx配置 & 重载
|
||||
env:
|
||||
ZY_CN_DOMAIN: ${{ secrets.ZY_CN_DOMAIN }}
|
||||
run: |
|
||||
ssh cn-target << 'NGINX_CMD'
|
||||
BARE_DOMAIN="${ZY_CN_DOMAIN#www.}"
|
||||
ssh cn-target << NGINX_CMD
|
||||
set -e
|
||||
|
||||
echo "═══ Nginx 配置诊断 ═══"
|
||||
|
|
@ -178,9 +184,9 @@ jobs:
|
|||
|
||||
# 清理 sites-enabled 中的冲突
|
||||
for conf in /etc/nginx/sites-enabled/*; do
|
||||
if [ -f "$conf" ] && [ "$(basename "$conf")" != "cn-domain.conf" ]; then
|
||||
echo " 🗑️ 移除sites-enabled冲突: $(basename "$conf")"
|
||||
sudo rm -f "$conf"
|
||||
if [ -f "\$conf" ] && [ "\$(basename "\$conf")" != "cn-domain.conf" ]; then
|
||||
echo " 🗑️ 移除sites-enabled冲突: \$(basename "\$conf")"
|
||||
sudo rm -f "\$conf"
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
@ -188,9 +194,9 @@ jobs:
|
|||
# 保留 conf.d 中的全局配置(如 gzip, ssl_params 等)
|
||||
# 只移除包含 server { 或 proxy_pass 的自定义站点配置
|
||||
for conf in /etc/nginx/conf.d/*.conf; do
|
||||
if [ -f "$conf" ] && grep -qE "server[[:space:]]*\{" "$conf" 2>/dev/null; then
|
||||
echo " 🗑️ 移除conf.d冲突站点配置: $(basename "$conf")"
|
||||
sudo rm -f "$conf"
|
||||
if [ -f "\$conf" ] && grep -qE "server[[:space:]]*\{" "\$conf" 2>/dev/null; then
|
||||
echo " 🗑️ 移除conf.d冲突站点配置: \$(basename "\$conf")"
|
||||
sudo rm -f "\$conf"
|
||||
fi
|
||||
done
|
||||
|
||||
|
|
@ -198,6 +204,23 @@ jobs:
|
|||
sudo cp /opt/zhuyuan-cn/config/nginx/cn-domain.conf /etc/nginx/sites-available/cn-domain.conf
|
||||
sudo ln -sf /etc/nginx/sites-available/cn-domain.conf /etc/nginx/sites-enabled/cn-domain.conf
|
||||
|
||||
# ─── SSL自动注入: 检测已有Let's Encrypt证书 ───
|
||||
# 如果之前运行过 setup-ssl,证书文件会存在
|
||||
# 每次deploy都重新注入SSL配置,避免模板覆盖导致SSL丢失
|
||||
BARE="${BARE_DOMAIN}"
|
||||
if [ -d "/etc/letsencrypt/live/\${BARE}" ] && [ -f "/etc/letsencrypt/live/\${BARE}/fullchain.pem" ]; then
|
||||
echo ""
|
||||
echo "§2.5 🔐 检测到SSL证书,注入HTTPS配置..."
|
||||
# 在 listen 80 后添加 listen 443 ssl 和证书配置
|
||||
sudo sed -i '/listen 80 default_server;/a\\n listen 443 ssl default_server;\n ssl_certificate /etc/letsencrypt/live/'"\${BARE}"'/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/'"\${BARE}"'/privkey.pem;\n include /etc/letsencrypt/options-ssl-nginx.conf;\n ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;' \
|
||||
/etc/nginx/sites-available/cn-domain.conf
|
||||
echo "✅ SSL配置已注入 · HTTPS已启用"
|
||||
else
|
||||
echo ""
|
||||
echo "§2.5 ℹ️ 未检测到SSL证书 · 仅HTTP模式"
|
||||
echo " 运行 setup-ssl 动作安装Let's Encrypt证书"
|
||||
fi
|
||||
|
||||
# 确认最终状态
|
||||
echo ""
|
||||
echo "§3 清理后sites-enabled目录:"
|
||||
|
|
@ -384,8 +407,125 @@ jobs:
|
|||
echo "§9 端口80监听进程:"
|
||||
sudo ss -tlnp | grep ':80 ' 2>/dev/null || echo " (无)"
|
||||
|
||||
# SSL状态检查
|
||||
echo ""
|
||||
echo "§10 SSL证书状态:"
|
||||
sudo certbot certificates 2>/dev/null || echo " certbot未安装 · 运行setup-ssl动作安装"
|
||||
|
||||
echo ""
|
||||
echo "§11 HTTPS访问测试:"
|
||||
HTTPS_CODE=$(curl -sf -o /dev/null -w '%{http_code}' https://localhost/ -k 2>/dev/null || echo "000")
|
||||
echo "HTTPS状态码: ${HTTPS_CODE}"
|
||||
|
||||
HEALTH_CMD
|
||||
|
||||
- name: 🧹 清理SSH密钥
|
||||
if: always()
|
||||
run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config
|
||||
|
||||
setup-ssl:
|
||||
name: 🔐 安装SSL证书 (Let's Encrypt)
|
||||
if: github.event.inputs.action == 'setup-ssl'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: 🔐 配置SSH跳板 (SG→CN)
|
||||
env:
|
||||
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
|
||||
CN_SSH_KEY: ${{ secrets.ZY_CN_SERVER_KEY }}
|
||||
CN_SSH_PORT: ${{ secrets.ZY_CN_SSH_PORT }}
|
||||
run: |
|
||||
CN_PORT="${CN_SSH_PORT:-22}"
|
||||
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
|
||||
echo "$CN_SSH_KEY" > ~/.ssh/id_cn
|
||||
chmod 600 ~/.ssh/id_sg ~/.ssh/id_cn
|
||||
|
||||
ssh-keyscan -H ${{ secrets.ZY_SERVER_HOST }} >> ~/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
cat > ~/.ssh/config << EOF
|
||||
Host sg-jump
|
||||
HostName ${{ secrets.ZY_SERVER_HOST }}
|
||||
User ${{ secrets.ZY_SERVER_USER }}
|
||||
IdentityFile ~/.ssh/id_sg
|
||||
StrictHostKeyChecking accept-new
|
||||
BatchMode yes
|
||||
|
||||
Host cn-target
|
||||
HostName ${{ secrets.ZY_CN_SERVER_HOST }}
|
||||
User ${{ secrets.ZY_CN_SERVER_USER }}
|
||||
Port ${CN_PORT}
|
||||
IdentityFile ~/.ssh/id_cn
|
||||
ProxyJump sg-jump
|
||||
StrictHostKeyChecking accept-new
|
||||
BatchMode yes
|
||||
ConnectTimeout 30
|
||||
EOF
|
||||
chmod 600 ~/.ssh/config
|
||||
|
||||
- name: 🔐 安装certbot并申请证书
|
||||
env:
|
||||
ZY_CN_DOMAIN: ${{ secrets.ZY_CN_DOMAIN }}
|
||||
run: |
|
||||
BARE_DOMAIN="${ZY_CN_DOMAIN#www.}"
|
||||
echo "🔐 为 ${BARE_DOMAIN} + www.${BARE_DOMAIN} 申请SSL证书..."
|
||||
|
||||
ssh cn-target << SSLCMD
|
||||
set -e
|
||||
|
||||
echo "═══ SSL证书安装 ═══"
|
||||
|
||||
# 安装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
|
||||
else
|
||||
echo "✅ certbot已安装: \$(certbot --version 2>&1)"
|
||||
fi
|
||||
|
||||
# 确认Nginx正在运行
|
||||
if ! systemctl is-active --quiet nginx; then
|
||||
echo "❌ Nginx未运行,先启动Nginx"
|
||||
sudo systemctl start nginx
|
||||
fi
|
||||
|
||||
# 申请证书 (--nginx模式会自动修改Nginx配置)
|
||||
echo ""
|
||||
echo "§1 申请Let's Encrypt证书..."
|
||||
sudo certbot --nginx \
|
||||
-d ${BARE_DOMAIN} \
|
||||
-d www.${BARE_DOMAIN} \
|
||||
--non-interactive \
|
||||
--agree-tos \
|
||||
--email admin@${BARE_DOMAIN} \
|
||||
--redirect \
|
||||
--no-eff-email
|
||||
|
||||
# 验证证书
|
||||
echo ""
|
||||
echo "§2 验证证书..."
|
||||
sudo certbot certificates
|
||||
|
||||
# 验证HTTPS可访问
|
||||
echo ""
|
||||
echo "§3 HTTPS访问测试..."
|
||||
HTTP_CODE=\$(curl -sf -o /dev/null -w '%{http_code}' https://localhost/ -k 2>/dev/null || echo "000")
|
||||
echo "HTTPS状态码: \${HTTP_CODE}"
|
||||
|
||||
# 验证HTTP→HTTPS重定向
|
||||
echo ""
|
||||
echo "§4 HTTP→HTTPS重定向测试..."
|
||||
REDIR_CODE=\$(curl -sf -o /dev/null -w '%{http_code}' http://localhost/ 2>/dev/null || echo "000")
|
||||
echo "HTTP重定向码: \${REDIR_CODE} (301=正确重定向)"
|
||||
|
||||
echo ""
|
||||
echo "═══ SSL安装完成 ═══"
|
||||
echo "🌐 现在可以通过 https://${BARE_DOMAIN} 访问"
|
||||
SSLCMD
|
||||
|
||||
- name: 🧹 清理SSH密钥
|
||||
if: always()
|
||||
run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config
|
||||
|
|
@ -183,14 +183,20 @@ jobs:
|
|||
|
||||
- name: 🌐 同步前端内容到站点
|
||||
run: |
|
||||
TARGET="${{ github.event.inputs.deploy_target || 'preview' }}"
|
||||
# Push事件: 直接部署到 production (guanghulab.online = ZY_DOMAIN_MAIN = production)
|
||||
# 手动触发: 使用选定的目标 (默认 preview)
|
||||
if [ "${{ github.event_name }}" = "push" ]; then
|
||||
TARGET="production"
|
||||
else
|
||||
TARGET="${{ github.event.inputs.deploy_target || 'preview' }}"
|
||||
fi
|
||||
TARGET_DIR="/opt/zhuyuan/sites/${TARGET}"
|
||||
echo "🌐 同步前端 → ${TARGET_DIR}"
|
||||
|
||||
# 确保零点原核频道目录存在
|
||||
ssh -i ~/.ssh/zy_key \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }} \
|
||||
"mkdir -p /opt/zhuyuan/sites/yaoming"
|
||||
"mkdir -p /opt/zhuyuan/sites/yaoming /opt/zhuyuan/sites/production /opt/zhuyuan/sites/preview"
|
||||
|
||||
# 同步主站门户 (server/sites/portal/) 到目标站点目录
|
||||
if [ -d "server/sites/portal" ]; then
|
||||
|
|
@ -199,6 +205,15 @@ jobs:
|
|||
server/sites/portal/ \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:${TARGET_DIR}/
|
||||
echo "✅ 主站门户已部署到 ${TARGET_DIR}"
|
||||
|
||||
# Push事件额外同步到 preview 保持两站一致
|
||||
if [ "${{ github.event_name }}" = "push" ]; then
|
||||
rsync -avz --delete \
|
||||
-e "ssh -i ~/.ssh/zy_key" \
|
||||
server/sites/portal/ \
|
||||
${{ secrets.ZY_SERVER_USER }}@${{ secrets.ZY_SERVER_HOST }}:/opt/zhuyuan/sites/preview/
|
||||
echo "✅ 主站门户已同步到 preview (保持一致)"
|
||||
fi
|
||||
else
|
||||
# 降级: 使用 docs/ 目录
|
||||
rsync -avz --delete \
|
||||
|
|
|
|||
|
|
@ -8,17 +8,22 @@
|
|||
# 版权: 国作登字-2026-A-00037559
|
||||
#
|
||||
# 架构:
|
||||
# ZY_CN_DOMAIN (www.guanghulab.com) → 国内用户首页
|
||||
# ZY_CN_DOMAIN (guanghulab.com / www.guanghulab.com) → 国内用户首页
|
||||
# 前端: /opt/zhuyuan-cn/sites/cn-landing/ (静态HTML)
|
||||
# 用途: ICP备案合规 + 未来国内语言操作系统入口
|
||||
#
|
||||
# 域名变量由 GitHub Secrets 注入:
|
||||
# ZY_CN_DOMAIN — 国内备案域名
|
||||
# ZY_CN_DOMAIN — 国内备案域名 (裸域名,如 guanghulab.com)
|
||||
# 部署时自动展开为: guanghulab.com + www.guanghulab.com
|
||||
#
|
||||
# SSL: 首次部署后运行 setup-ssl 动作安装Let's Encrypt证书
|
||||
# certbot会自动添加443监听 + HTTP→HTTPS重定向
|
||||
# 后续deploy会检测已有证书并重新注入SSL配置
|
||||
# ═══════════════════════════════════════════════════════════
|
||||
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name ZY_CN_DOMAIN_PLACEHOLDER;
|
||||
server_name ZY_CN_BARE_DOMAIN_PLACEHOLDER www.ZY_CN_BARE_DOMAIN_PLACEHOLDER;
|
||||
|
||||
# ─── 安全头 ───
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
|
|
|
|||
|
|
@ -85,11 +85,18 @@ server {
|
|||
# 聊天请求由主应用的 domestic-llm-gateway 智能路由处理
|
||||
# 支持 DeepSeek/千问/Moonshot/智谱 四路自动降级
|
||||
location /api/chat {
|
||||
# CORS · 允许前端跨域调用
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
|
||||
if ($request_method = OPTIONS) { return 204; }
|
||||
|
||||
proxy_pass http://127.0.0.1:3800/api/chat;
|
||||
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 Connection "";
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
|
|
@ -247,9 +254,18 @@ server {
|
|||
|
||||
# ─── AI 聊天 API (端口 3801) · 预览站共享主应用聊天引擎 ───
|
||||
location /api/chat {
|
||||
# CORS · 允许前端跨域调用
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
|
||||
if ($request_method = OPTIONS) { return 204; }
|
||||
|
||||
proxy_pass http://127.0.0.1:3801/api/chat;
|
||||
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 Connection "";
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
|
|
|
|||
Loading…
Reference in New Issue