diff --git a/.github/workflows/deploy-cn-landing.yml b/.github/workflows/deploy-cn-landing.yml new file mode 100644 index 00000000..19b85f47 --- /dev/null +++ b/.github/workflows/deploy-cn-landing.yml @@ -0,0 +1,313 @@ +name: 🇨🇳 国内域名落地页 · 部署 + +# ═══════════════════════════════════════════════════════════ +# 国内域名ICP备案落地页部署工作流 +# 编号: ZY-WF-CN-LANDING +# 服务器: ZY-SVR-004 · 43.139.217.141 · 广州七区 +# 守护: 铸渊 · ICE-GL-ZY001 +# 版权: 国作登字-2026-A-00037559 +# ═══════════════════════════════════════════════════════════ +# +# 部署内容: +# 1. 国内落地页 (server/sites/cn-landing/) → /opt/zhuyuan-cn/sites/cn-landing/ +# 2. Nginx 配置 (server/nginx/cn-domain.conf) → Nginx sites-enabled +# 3. LLM API 密钥注入 (四大国内模型) +# +# 架构: GitHub Actions(美国) → SG(新加坡·跳板) → CN(广州·目标) + +on: + push: + branches: [main] + paths: + - 'server/sites/cn-landing/**' + - 'server/nginx/cn-domain.conf' + workflow_dispatch: + inputs: + action: + description: '部署动作' + required: true + default: 'deploy' + type: choice + options: + - deploy + - health-check + +concurrency: + group: cn-landing-deploy + cancel-in-progress: false + +permissions: + contents: read + +jobs: + deploy: + name: 🚀 部署国内落地页 + if: github.event.inputs.action == 'deploy' || github.event.inputs.action == '' || github.event_name == 'push' + 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}" + echo "🔧 SSH跳板: GitHub Actions → SG → CN (端口 ${CN_PORT})" + + 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 + + for key_file in id_sg id_cn; do + if ! head -1 ~/.ssh/${key_file} | grep -q "BEGIN"; then + echo "❌ SSH密钥格式异常: ${key_file}" + exit 1 + fi + done + echo "✅ SG + 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: 🔍 SSH连接测试 + run: | + echo "🔍 测试SSH跳板连接到广州服务器..." + ssh cn-target 'echo "✅ SSH连接成功 · $(hostname) · $(date)"' || { + echo "❌ SSH跳板连接失败" + exit 1 + } + + - name: 📂 准备目标目录 + run: | + ssh cn-target << 'PREP_CMD' + set -e + mkdir -p /opt/zhuyuan-cn/sites/cn-landing + mkdir -p /opt/zhuyuan-cn/data/logs + mkdir -p /opt/zhuyuan-cn/config/nginx + echo "✅ 目录结构就绪" + PREP_CMD + + - name: 📦 同步落地页文件 + run: | + rsync -avz --delete \ + -e "ssh -F ~/.ssh/config" \ + server/sites/cn-landing/ \ + cn-target:/opt/zhuyuan-cn/sites/cn-landing/ + echo "✅ 落地页已同步到 /opt/zhuyuan-cn/sites/cn-landing/" + + - name: 📦 同步Nginx配置 + env: + ZY_CN_DOMAIN: ${{ secrets.ZY_CN_DOMAIN }} + run: | + 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}" + else + echo "⚠️ ZY_CN_DOMAIN 未配置,使用IP直接访问" + sed -i "s/ZY_CN_DOMAIN_PLACEHOLDER/_/g" /tmp/cn-domain.conf + fi + + scp -F ~/.ssh/config \ + /tmp/cn-domain.conf \ + cn-target:/opt/zhuyuan-cn/config/nginx/cn-domain.conf + echo "✅ Nginx配置已上传" + + - name: 🔑 注入LLM API密钥 + env: + ZY_DEEPSEEK_API_KEY: ${{ secrets.ZY_DEEPSEEK_API_KEY }} + ZY_QIANWEN_API_KEY: ${{ secrets.ZY_QIANWEN_API_KEY }} + ZY_KIMI_API_KEY: ${{ secrets.ZY_KIMI_API_KEY }} + ZY_QINGYAN_API_KEY: ${{ secrets.ZY_QINGYAN_API_KEY }} + run: | + # 在本地生成密钥文件(变量在此展开) + cat > /tmp/.env.llm << ENVEOF + ZY_DEEPSEEK_API_KEY=${ZY_DEEPSEEK_API_KEY} + ZY_QIANWEN_API_KEY=${ZY_QIANWEN_API_KEY} + ZY_KIMI_API_KEY=${ZY_KIMI_API_KEY} + ZY_QINGYAN_API_KEY=${ZY_QINGYAN_API_KEY} + ENVEOF + + # 上传到目标服务器 + scp -F ~/.ssh/config /tmp/.env.llm cn-target:/opt/zhuyuan-cn/config/.env.llm + ssh cn-target 'chmod 600 /opt/zhuyuan-cn/config/.env.llm' + rm -f /tmp/.env.llm + echo "✅ 四大国内模型API密钥已注入" + + - name: 🔧 启用Nginx配置 & 重载 + run: | + ssh cn-target << 'NGINX_CMD' + set -e + + # 复制配置到Nginx目录 + 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 + + # 移除默认配置,避免 default_server 冲突 + sudo rm -f /etc/nginx/sites-enabled/default + + # 测试并重载Nginx + sudo nginx -t && sudo systemctl reload nginx + echo "✅ Nginx配置已生效" + NGINX_CMD + + - name: 💚 健康检查 + run: | + ssh cn-target << 'HEALTH_CMD' + set -e + + echo "═══ 国内落地页部署验证 ═══" + + # 检查Nginx + if systemctl is-active --quiet nginx; then + echo "✅ Nginx: 运行中" + else + echo "❌ Nginx: 已停止" + exit 1 + fi + + # 检查页面可访问 + HTTP_CODE=$(curl -sf -o /dev/null -w '%{http_code}' http://localhost/ 2>/dev/null || echo "000") + if [ "$HTTP_CODE" = "200" ]; then + echo "✅ 落地页: HTTP 200 OK" + else + echo "❌ 落地页: HTTP ${HTTP_CODE}" + exit 1 + fi + + # 检查ICP备案号 + if curl -sf http://localhost/ | grep -q "陕ICP备2025071211号"; then + echo "✅ ICP备案号: 已显示" + else + echo "⚠️ ICP备案号: 未找到(请检查页面内容)" + fi + + # 检查备案链接 + if curl -sf http://localhost/ | grep -q "beian.miit.gov.cn"; then + echo "✅ 工信部链接: 已配置" + else + echo "⚠️ 工信部链接: 未找到" + fi + + # 健康端点 + HEALTH=$(curl -sf http://localhost/health 2>/dev/null || echo '{}') + echo "✅ 健康探针: ${HEALTH}" + + echo "" + echo "═══ 部署完成 ═══" + HEALTH_CMD + + - name: 🧹 清理SSH密钥 + if: always() + run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config + + health-check: + name: 💚 国内落地页健康检查 + if: github.event.inputs.action == 'health-check' + 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: 💚 执行健康检查 + run: | + ssh cn-target << 'HEALTH_CMD' + + echo "═══ 国内落地页健康报告 ═══" + echo "" + + echo "§1 系统状态:" + uptime + echo "" + + echo "§2 Nginx 状态:" + systemctl is-active nginx && echo "Nginx: 运行中" || echo "Nginx: 已停止" + echo "" + + echo "§3 落地页文件:" + ls -la /opt/zhuyuan-cn/sites/cn-landing/ 2>/dev/null || echo "目录不存在" + echo "" + + echo "§4 页面访问测试:" + HTTP_CODE=$(curl -sf -o /dev/null -w '%{http_code}' http://localhost/ 2>/dev/null || echo "000") + echo "HTTP状态码: ${HTTP_CODE}" + echo "" + + echo "§5 ICP备案号检查:" + if curl -sf http://localhost/ | grep -q "陕ICP备2025071211号"; then + echo "✅ ICP备案号已显示" + else + echo "❌ ICP备案号未找到" + fi + + echo "" + echo "§6 LLM API密钥状态:" + if [ -f /opt/zhuyuan-cn/config/.env.llm ]; then + KEY_COUNT=$(grep -c "API_KEY" /opt/zhuyuan-cn/config/.env.llm 2>/dev/null || echo "0") + echo "已配置密钥数: ${KEY_COUNT}" + else + echo "⚠️ LLM密钥文件不存在" + fi + + HEALTH_CMD + + - name: 🧹 清理SSH密钥 + if: always() + run: rm -f ~/.ssh/id_sg ~/.ssh/id_cn ~/.ssh/config diff --git a/server/nginx/cn-domain.conf b/server/nginx/cn-domain.conf new file mode 100644 index 00000000..b22bb41b --- /dev/null +++ b/server/nginx/cn-domain.conf @@ -0,0 +1,59 @@ +# ═══════════════════════════════════════════════════════════ +# 国内域名 · ICP备案落地页 Nginx 配置 +# ═══════════════════════════════════════════════════════════ +# +# 编号: ZY-SVR-NGX-CN-LANDING +# 服务器: ZY-SVR-004 · 43.139.217.141 · 广州七区 +# 守护: 铸渊 · ICE-GL-ZY001 +# 版权: 国作登字-2026-A-00037559 +# +# 架构: +# ZY_CN_DOMAIN (www.guanghulab.com) → 国内用户首页 +# 前端: /opt/zhuyuan-cn/sites/cn-landing/ (静态HTML) +# 用途: ICP备案合规 + 未来国内语言操作系统入口 +# +# 域名变量由 GitHub Secrets 注入: +# ZY_CN_DOMAIN — 国内备案域名 +# ═══════════════════════════════════════════════════════════ + +server { + listen 80 default_server; + server_name ZY_CN_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-004" always; + add_header X-Site-Mode "cn-landing" always; + + # ─── 静态文件根目录 · 国内落地页 ─── + root /opt/zhuyuan-cn/sites/cn-landing; + index index.html; + + # ─── 前端静态文件 ─── + location / { + try_files $uri $uri/ /index.html; + } + + # ─── 健康探针 ─── + location = /health { + access_log off; + return 200 '{"status":"ok","server":"ZY-SVR-004","role":"cn-landing"}'; + add_header Content-Type application/json; + } + + # ─── 静态资源缓存 ─── + location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { + expires 7d; + add_header Cache-Control "public, immutable"; + } + + # ─── 错误页面 ─── + error_page 404 /index.html; + error_page 500 502 503 504 /index.html; + + # ─── 访问日志 ─── + access_log /opt/zhuyuan-cn/data/logs/nginx-cn-landing.log; + error_log /opt/zhuyuan-cn/data/logs/nginx-cn-landing-error.log; +} diff --git a/server/proxy/config/server-registry.json b/server/proxy/config/server-registry.json index 4252ff63..5d3425f4 100644 --- a/server/proxy/config/server-registry.json +++ b/server/proxy/config/server-registry.json @@ -89,6 +89,18 @@ "notes": "Awen下载完整仓库后部署·铸渊主控自动唤醒" } ], + "cn_domain": { + "description": "国内ICP备案域名 · 广州落地页", + "domain_secret": "ZY_CN_DOMAIN", + "server": "ZY-SVR-004", + "icp_number": "陕ICP备2025071211号", + "nginx_config": "server/nginx/cn-domain.conf", + "landing_page": "server/sites/cn-landing/index.html", + "workflow": ".github/workflows/deploy-cn-landing.yml", + "deploy_path": "/opt/zhuyuan-cn/sites/cn-landing/", + "status": "deploying", + "notes": "未来将替代guanghulab.online成为国内用户首页入口" + }, "domain_proxy": { "description": "域名未备案反向代理 · 新加坡中转架构", "architecture": "用户 → 域名(DNS→SG) → ZY-SVR-002 Nginx → 广州后端", diff --git a/server/sites/cn-landing/index.html b/server/sites/cn-landing/index.html new file mode 100644 index 00000000..c8ee8428 --- /dev/null +++ b/server/sites/cn-landing/index.html @@ -0,0 +1,347 @@ + + + + + +光湖实验室 · GuanghuLab + + + + + + + + + + +
+
+
+ + +
+
+
+ + +
+
🌊
+

光湖实验室

+

GuanghuLab

+
+

+ 语言驱动的智能创作平台
+ 探索人类与AI共生的数字世界 +

+
+ + 系统运行中 · Language-Driven OS +
+
+ + + + + + +