guanghulab/.github/workflows/.archive/deploy-ali-cn-landing.yml
Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

971 lines
40 KiB
YAML
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

name: 🇨🇳 阿里云落地页 · guanghulab.com 部署
# ═══════════════════════════════════════════════════════════
# 阿里云临时服务器 · 国内ICP备案落地页部署
# 编号: ALI-WF-CN-LANDING
# 服务器: ALI-SVR · 8.155.62.235 · 阿里云
# 守护: 铸渊 · ICE-GL-ZY001
# 版权: 国作登字-2026-A-00037559
# ═══════════════════════════════════════════════════════════
#
# 背景:
# 域名 guanghulab.com 在阿里云购买并备案。
# 备案迁移到腾讯云期间,域名解析回阿里云服务器。
# 此工作流将落地页部署到阿里云,确保备案期间网站正常显示。
#
# 部署内容:
# 1. 国内落地页 (server/sites/cn-landing/) → /opt/guanghulab-landing/sites/cn-landing/
# 2. Nginx 配置 (server/nginx/ali-cn-domain.conf) → Nginx sites-enabled
#
# 密钥:
# ALI_SERVER_HOST — 阿里云服务器IP (8.155.62.235)
# ALI_SERVER_USER — SSH用户名 (root)
# ALI_SERVER_PASSWORD — SSH密码
#
# 连接策略: 直连 → 如失败 → 通过SG跳板中转
# 路径A: GitHub Actions → ALI (直连)
# 路径B: GitHub Actions → SG(新加坡·跳板) → ALI (中转)
#
# 隔离: 所有文件部署在 /opt/guanghulab-landing/ 下
# 不干扰服务器上已有的服务和配置
on:
push:
branches: [main]
paths:
- 'server/sites/cn-landing/**'
- 'server/nginx/ali-cn-domain.conf'
workflow_dispatch:
inputs:
action:
description: '部署动作'
required: true
default: 'deploy'
type: choice
options:
- deploy
- health-check
- setup-ssl
concurrency:
group: ali-cn-landing-deploy
cancel-in-progress: false
permissions:
contents: read
env:
DEPLOY_PATH: /opt/guanghulab-landing
CN_DOMAIN: guanghulab.com
jobs:
# ═══════════════════════════════════════
# §1 部署落地页
# ═══════════════════════════════════════
deploy:
name: 🚀 部署 guanghulab.com 到阿里云
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工具
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq sshpass
echo "✅ sshpass 已安装"
- name: 🔐 配置SSH连接 (双路径)
env:
ALI_HOST: ${{ secrets.ALI_SERVER_HOST }}
ALI_USER: ${{ secrets.ALI_SERVER_USER }}
ALI_PASS: ${{ secrets.ALI_SERVER_PASSWORD }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
SG_HOST: ${{ secrets.ZY_SERVER_HOST }}
SG_USER: ${{ secrets.ZY_SERVER_USER }}
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# ─── 路径A: 直连 ───
echo "🔍 尝试直连阿里云服务器 ${ALI_HOST}..."
export SSHPASS="${ALI_PASS}"
DIRECT_OK=false
sshpass -e ssh -o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=15 \
-o BatchMode=no \
"${ALI_USER}@${ALI_HOST}" \
'echo "✅ 直连成功 · $(hostname) · $(date)"' 2>/dev/null && DIRECT_OK=true || true
if [ "$DIRECT_OK" = "true" ]; then
echo "SSH_MODE=direct" >> $GITHUB_ENV
echo "✅ 使用直连模式"
# 写入SSH config用于后续步骤
cat > ~/.ssh/config << EOF
Host ali-target
HostName ${ALI_HOST}
User ${ALI_USER}
StrictHostKeyChecking accept-new
ConnectTimeout 30
EOF
else
echo "⚠️ 直连失败尝试SG跳板中转..."
# ─── 路径B: SG跳板中转 ───
if [ -n "$SG_SSH_KEY" ] && [ -n "$SG_HOST" ]; then
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
chmod 600 ~/.ssh/id_sg
ssh-keyscan -H "${SG_HOST}" >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${SG_HOST}
User ${SG_USER}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host ali-target
HostName ${ALI_HOST}
User ${ALI_USER}
ProxyJump sg-jump
StrictHostKeyChecking accept-new
ConnectTimeout 30
EOF
# 测试SG跳板连接
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target \
'echo "✅ SG跳板连接成功 · $(hostname) · $(date)"' || {
echo "❌ SG跳板连接也失败"
exit 1
}
echo "SSH_MODE=proxy" >> $GITHUB_ENV
echo "✅ 使用SG跳板模式"
else
echo "❌ 直连失败且无SG跳板密钥可用"
exit 1
fi
fi
chmod 600 ~/.ssh/config
- name: 📂 初始化目标目录
env:
SSHPASS: ${{ secrets.ALI_SERVER_PASSWORD }}
run: |
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target << INIT_CMD
set -e
echo "═══ 初始化隔离部署目录 ═══"
# 创建隔离的部署目录结构
mkdir -p ${DEPLOY_PATH}/sites/cn-landing
mkdir -p ${DEPLOY_PATH}/logs
mkdir -p ${DEPLOY_PATH}/config/nginx
echo "✅ 目录结构就绪: ${DEPLOY_PATH}/"
ls -la ${DEPLOY_PATH}/
# ─── 检查并开放防火墙端口 (80/443) ───
echo ""
echo "═══ 防火墙端口检查 ═══"
if command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld; then
echo "🔥 检测到 firewalld 运行中"
# 开放HTTP/HTTPS端口
if ! firewall-cmd --query-port=80/tcp --quiet 2>/dev/null; then
firewall-cmd --permanent --add-port=80/tcp
echo " ✅ 已开放端口 80/tcp"
else
echo " ✅ 端口 80/tcp 已开放"
fi
if ! firewall-cmd --query-port=443/tcp --quiet 2>/dev/null; then
firewall-cmd --permanent --add-port=443/tcp
echo " ✅ 已开放端口 443/tcp"
else
echo " ✅ 端口 443/tcp 已开放"
fi
# 也尝试添加http/https服务
firewall-cmd --permanent --add-service=http 2>/dev/null || true
firewall-cmd --permanent --add-service=https 2>/dev/null || true
firewall-cmd --reload
echo " ✅ firewalld 规则已重载"
elif command -v iptables &> /dev/null; then
echo "🔥 检测到 iptables"
# 检查并添加ACCEPT规则先用-C检测是否已存在避免重复
if ! iptables -C INPUT -p tcp --dport 80 -j ACCEPT 2>/dev/null; then
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
echo " ✅ 已添加 iptables 规则: 允许端口 80"
else
echo " ✅ 端口 80 ACCEPT 规则已存在"
fi
if ! iptables -C INPUT -p tcp --dport 443 -j ACCEPT 2>/dev/null; then
iptables -I INPUT -p tcp --dport 443 -j ACCEPT
echo " ✅ 已添加 iptables 规则: 允许端口 443"
else
echo " ✅ 端口 443 ACCEPT 规则已存在"
fi
echo " ✅ iptables 检查完成"
else
echo " 未检测到活跃防火墙"
fi
INIT_CMD
- name: 📦 上传落地页文件
env:
SSHPASS: ${{ secrets.ALI_SERVER_PASSWORD }}
run: |
echo "📦 打包并上传落地页文件..."
# 使用tar打包上传兼容性最好
tar czf /tmp/cn-landing.tar.gz -C server/sites/cn-landing .
sshpass -e scp -F ~/.ssh/config -o BatchMode=no \
/tmp/cn-landing.tar.gz \
ali-target:/tmp/cn-landing.tar.gz
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target << 'EXTRACT_CMD'
set -e
DEPLOY_PATH=/opt/guanghulab-landing
# 备份旧文件(如果有)
if [ -f "${DEPLOY_PATH}/sites/cn-landing/index.html" ]; then
cp "${DEPLOY_PATH}/sites/cn-landing/index.html" "${DEPLOY_PATH}/sites/cn-landing/index.html.bak"
fi
# 解压新文件
tar xzf /tmp/cn-landing.tar.gz -C ${DEPLOY_PATH}/sites/cn-landing/
rm -f /tmp/cn-landing.tar.gz
echo "✅ 落地页文件已部署"
ls -la ${DEPLOY_PATH}/sites/cn-landing/
EXTRACT_CMD
rm -f /tmp/cn-landing.tar.gz
- name: 📦 上传并配置Nginx
env:
SSHPASS: ${{ secrets.ALI_SERVER_PASSWORD }}
ZY_CN_DOMAIN: ${{ secrets.ZY_CN_DOMAIN }}
run: |
# 处理域名占位符替换
BARE_DOMAIN="${ZY_CN_DOMAIN:-guanghulab.com}"
BARE_DOMAIN="${BARE_DOMAIN#www.}"
echo "🌐 配置域名: ${BARE_DOMAIN}"
# 替换域名占位符
cp server/nginx/ali-cn-domain.conf /tmp/ali-cn-domain.conf
sed -i "s/ALI_CN_DOMAIN_PLACEHOLDER/${BARE_DOMAIN}/g" /tmp/ali-cn-domain.conf
# 上传Nginx配置模板SSL占位符稍后在服务器上替换
sshpass -e scp -F ~/.ssh/config -o BatchMode=no \
/tmp/ali-cn-domain.conf \
ali-target:/tmp/ali-cn-domain.conf
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target << 'NGINX_CMD'
set -e
DEPLOY_PATH=/opt/guanghulab-landing
BARE_DOMAIN=$(grep server_name /tmp/ali-cn-domain.conf 2>/dev/null | grep -v '#' | head -1 | awk '{print $2}' | sed 's/;//' || echo "guanghulab.com")
echo "═══ Nginx 配置 · ${BARE_DOMAIN} 落地页 ═══"
# §1 检查Nginx是否已安装
if ! command -v nginx &> /dev/null; then
echo "📦 安装Nginx..."
if command -v apt-get &> /dev/null; then
apt-get update -qq
apt-get install -y -qq nginx
elif command -v yum &> /dev/null; then
yum install -y -q epel-release 2>/dev/null || true
yum install -y -q nginx
elif command -v dnf &> /dev/null; then
dnf install -y -q nginx
else
echo "❌ 无法安装Nginx未找到包管理器"
exit 1
fi
systemctl enable nginx
echo "✅ Nginx 已安装"
else
echo "✅ Nginx 已存在: $(nginx -v 2>&1)"
fi
# §2 智能选择配置目录
CONF_DIR=""
if grep -q "include.*sites-enabled" /etc/nginx/nginx.conf 2>/dev/null; then
CONF_DIR="/etc/nginx/sites-enabled"
mkdir -p /etc/nginx/sites-available 2>/dev/null || true
mkdir -p /etc/nginx/sites-enabled 2>/dev/null || true
echo "✅ 检测到 sites-enabled 模式"
elif grep -q "include.*conf\.d" /etc/nginx/nginx.conf 2>/dev/null; then
CONF_DIR="/etc/nginx/conf.d"
echo "✅ 检测到 conf.d 模式 (CentOS/RHEL)"
else
CONF_DIR="/etc/nginx/conf.d"
mkdir -p /etc/nginx/conf.d 2>/dev/null || true
echo "⚠️ 未检测到明确的配置目录,使用 conf.d"
fi
echo "📁 配置部署目录: ${CONF_DIR}"
# ═══════════════════════════════════════════════════
# §2.5 全面清理冲突配置
# 此服务器唯一用途: guanghulab.com 落地页
# 必须移除所有其他server块防止旧配置劫持流量
# ═══════════════════════════════════════════════════
echo ""
echo "§2.5 全面清理冲突配置..."
CONFLICT_FOUND=false
# ─── A. 清理 conf.d 中所有非我们的 .conf 文件 ───
for conf in /etc/nginx/conf.d/*.conf; do
[ -f "$conf" ] || continue
BASENAME=$(basename "$conf")
[ "$BASENAME" = "guanghulab-landing.conf" ] && continue
# 移除所有包含server块的配置保留纯全局配置如gzip等
if grep -vE '^\s*#' "$conf" 2>/dev/null | grep -qE "server\s*\{|listen\s|server_name\s"; then
echo " 🗑️ 移除conf.d冲突: $BASENAME"
mv "$conf" "${conf}.disabled.by-landing"
CONFLICT_FOUND=true
fi
done
# ─── B. 清理 sites-enabled 中所有非我们的配置 ───
if [ -d "/etc/nginx/sites-enabled" ]; then
for conf in /etc/nginx/sites-enabled/*; do
[ -f "$conf" ] || [ -L "$conf" ] || continue
BASENAME=$(basename "$conf")
[ "$BASENAME" = "guanghulab-landing.conf" ] && continue
echo " 🗑️ 移除sites-enabled冲突: $BASENAME"
rm -f "$conf"
CONFLICT_FOUND=true
done
fi
# ─── C. 中和 nginx.conf 内嵌的 default server 块 ───
# CentOS/RHEL 默认nginx.conf通常包含一个内嵌的server块
# 人类开发者手动部署可能使用了任意root路径
# 必须用通用正则替换所有root指令而非仅匹配已知路径
echo ""
echo "§C 诊断 nginx.conf 内嵌 server 块..."
# 先显示nginx.conf中所有非注释的server和root行用于诊断
echo " nginx.conf 中活跃的 server/root/listen 行:"
grep -nE '^\s*(server\s*\{|root\s|listen\s|ssl_certificate)' /etc/nginx/nginx.conf 2>/dev/null | grep -vE '^\s*#' | head -20 || echo " (无)"
echo ""
# 使用更宽松的匹配检测server块中的listen或root关键词不仅仅是 server {
HAS_EMBEDDED_SERVER=false
if grep -vE '^\s*#' /etc/nginx/nginx.conf 2>/dev/null | grep -qE '^\s*server\s*\{'; then
HAS_EMBEDDED_SERVER=true
fi
# 也检测root指令即使server块格式不匹配正则
if grep -vE '^\s*#' /etc/nginx/nginx.conf 2>/dev/null | grep -qE '^\s*root\s+'; then
HAS_EMBEDDED_SERVER=true
fi
if [ "$HAS_EMBEDDED_SERVER" = "true" ]; then
echo " ⚠️ 检测到 nginx.conf 内嵌 server 块或 root 指令"
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.by-landing
# 通用方案:替换 nginx.conf 中 ALL root 指令为落地页目录
# 使用通用正则匹配任意路径(不再硬编码特定目录)
sed -i 's|^\(\s*\)root\s\+[^;]*;|\1root /opt/guanghulab-landing/sites/cn-landing;|g' /etc/nginx/nginx.conf
echo " ✅ nginx.conf 中所有 root 指令已重定向到落地页目录"
CONFLICT_FOUND=true
# 显示替换后的结果
echo " 替换后的 root 行:"
grep -n 'root\s' /etc/nginx/nginx.conf 2>/dev/null | head -10 || echo " (无)"
else
echo " ✅ nginx.conf 中无内嵌 server 块"
fi
# ─── C2. 清理 /etc/nginx/default.d/ (CentOS/RHEL 特有) ───
# CentOS nginx.conf 的 server 块通常 include /etc/nginx/default.d/*.conf
# certbot 或手动部署可能在此目录添加了SSL/root配置
if [ -d "/etc/nginx/default.d" ]; then
for conf in /etc/nginx/default.d/*.conf; do
[ -f "$conf" ] || continue
echo " 🗑️ 移除 default.d 冲突: $(basename "$conf")"
mv "$conf" "${conf}.disabled.by-landing"
CONFLICT_FOUND=true
done
fi
# ─── D. 清理旧web目录中的内容防止被其他配置引用 ───
echo ""
echo "§2.6 清理旧网站内容..."
# 扩展搜索范围:包含人类开发者可能手动部署的目录
for old_dir in /var/www/guanghulab /var/www/html /usr/share/nginx/html /root/guanghulab /home/www /opt/guanghulab /var/www/hololake; do
if [ -d "$old_dir" ] && [ -f "$old_dir/index.html" ]; then
# 检查是否是旧的铸渊助手/HoloLake页面
if grep -iqE "铸渊助手|hololake|age.os|HoloLake" "$old_dir/index.html" 2>/dev/null; then
echo " 🗑️ 备份并清理旧内容: $old_dir/index.html"
mv "$old_dir/index.html" "$old_dir/index.html.old.by-landing"
# 放一个简单的重定向提示页
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta http-equiv="refresh" content="0;url=/"></head><body>Redirecting...</body></html>' > "$old_dir/index.html"
fi
fi
done
# 也用find搜索系统中可能的旧页面限制搜索深度和web相关目录
echo " 全局搜索旧内容..."
find /var/www /usr/share/nginx /opt -maxdepth 3 -name "index.html" -type f 2>/dev/null | while read f; do
if grep -iqE "铸渊助手|hololake|age\.os|HoloLake" "$f" 2>/dev/null; then
# 不重复处理已备份的文件(匹配 .old. .bak. .disabled. 等后缀)
echo "$f" | grep -qE '\.(old|bak|disabled)($|\.)' && continue
# 不处理我们自己的落地页
echo "$f" | grep -q 'guanghulab-landing' && continue
echo " 🗑️ 发现旧内容: $f"
mv "$f" "${f}.old.by-landing"
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><meta http-equiv="refresh" content="0;url=/"></head><body>Redirecting...</body></html>' > "$f"
fi
done
if [ "$CONFLICT_FOUND" = "true" ]; then
echo " ✅ 冲突配置已全面清理"
else
echo " ✅ 未发现冲突配置"
fi
# ═══════════════════════════════════════════════════
# §3 处理SSL并生成最终配置
# ═══════════════════════════════════════════════════
echo ""
echo "§3 处理SSL配置..."
if [ -n "$BARE_DOMAIN" ] && [ -d "/etc/letsencrypt/live/${BARE_DOMAIN}" ] && [ -f "/etc/letsencrypt/live/${BARE_DOMAIN}/fullchain.pem" ]; then
echo "🔐 检测到SSL证书生成HTTPS配置..."
# 构建SSL选项行
SSL_OPTS_LINE=""
if [ -f "/etc/letsencrypt/options-ssl-nginx.conf" ]; then
SSL_OPTS_LINE=" include /etc/letsencrypt/options-ssl-nginx.conf;"
fi
SSL_DH_LINE=""
if [ -f "/etc/letsencrypt/ssl-dhparams.pem" ]; then
SSL_DH_LINE=" ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;"
fi
# 直接生成完整的带SSL的Nginx配置避免fragile占位符替换
{
echo "# guanghulab.com 落地页 · SSL模式 · 由部署工作流自动生成"
echo "# 生成时间: $(date -u '+%Y-%m-%d %H:%M UTC')"
echo ""
echo "# HTTP → HTTPS 重定向"
echo "server {"
echo " listen 80;"
echo " listen [::]:80;"
echo " server_name ${BARE_DOMAIN} www.${BARE_DOMAIN};"
echo ' return 301 https://$host$request_uri;'
echo "}"
echo ""
echo "# HTTPS 主站点"
echo "server {"
echo " listen 443 ssl default_server;"
echo " listen [::]:443 ssl default_server;"
echo " server_name ${BARE_DOMAIN} www.${BARE_DOMAIN};"
echo ""
echo " ssl_certificate /etc/letsencrypt/live/${BARE_DOMAIN}/fullchain.pem;"
echo " ssl_certificate_key /etc/letsencrypt/live/${BARE_DOMAIN}/privkey.pem;"
[ -n "$SSL_OPTS_LINE" ] && echo "$SSL_OPTS_LINE"
[ -n "$SSL_DH_LINE" ] && echo "$SSL_DH_LINE"
echo ""
echo ' add_header X-Frame-Options "SAMEORIGIN" always;'
echo ' add_header X-Content-Type-Options "nosniff" always;'
echo ' add_header X-XSS-Protection "1; mode=block" always;'
echo ' add_header X-Server-Identity "ALI-SVR-CN-LANDING" always;'
echo ' add_header X-Site-Mode "cn-landing-ali" always;'
echo ""
echo " root /opt/guanghulab-landing/sites/cn-landing;"
echo " index index.html;"
echo ""
echo " location / {"
echo ' try_files $uri $uri/ /index.html;'
echo " }"
echo ""
echo " location = /health {"
echo " access_log off;"
echo " return 200 '{\"status\":\"ok\",\"server\":\"ali-cn\",\"role\":\"cn-landing\",\"domain\":\"${BARE_DOMAIN}\",\"ssl\":true}';"
echo " add_header Content-Type application/json;"
echo " }"
echo ""
echo ' location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {'
echo " expires 7d;"
echo ' add_header Cache-Control "public, immutable";'
echo " }"
echo ""
echo " error_page 404 /index.html;"
echo " error_page 500 502 503 504 /index.html;"
echo ""
echo " access_log /opt/guanghulab-landing/logs/nginx-access.log;"
echo " error_log /opt/guanghulab-landing/logs/nginx-error.log;"
echo "}"
} > /tmp/ali-cn-domain.conf
echo "✅ SSL配置已生成 · HTTPS + HTTP→HTTPS重定向"
else
echo " 未检测到SSL证书 · 仅HTTP模式"
echo " 运行 setup-ssl 动作安装Let's Encrypt证书"
# 无SSL清除占位符保留原始HTTP配置
sed -i '/__SSL_BLOCK_PLACEHOLDER__/d' /tmp/ali-cn-domain.conf
sed -i '/__HTTP_REDIRECT_BLOCK_PLACEHOLDER__/d' /tmp/ali-cn-domain.conf
fi
# §3.5 部署配置文件
CONF_FILE="${CONF_DIR}/guanghulab-landing.conf"
if [ "$CONF_DIR" = "/etc/nginx/sites-enabled" ]; then
cp /tmp/ali-cn-domain.conf /etc/nginx/sites-available/guanghulab-landing.conf
ln -sf /etc/nginx/sites-available/guanghulab-landing.conf "${CONF_FILE}"
else
cp /tmp/ali-cn-domain.conf "${CONF_FILE}"
fi
rm -f /tmp/ali-cn-domain.conf
echo "✅ 配置已部署: ${CONF_FILE}"
# §4 诊断:显示最终配置状态
echo ""
echo "§4 最终Nginx配置状态:"
echo "─── conf.d 目录 ───"
ls -la /etc/nginx/conf.d/*.conf 2>/dev/null || echo " (无.conf文件)"
if [ -d "/etc/nginx/sites-enabled" ]; then
echo "─── sites-enabled 目录 ───"
ls -la /etc/nginx/sites-enabled/ 2>/dev/null || echo " (空)"
fi
echo "─── 配置文件内容 ───"
cat "${CONF_FILE}"
# §4.5 最终冲突检查扫描所有可能的监听80/443的配置
echo ""
echo "§4.5 最终冲突检查:"
REMAINING=false
for dir in /etc/nginx/conf.d /etc/nginx/sites-enabled; do
[ -d "$dir" ] || continue
for conf in "$dir"/*.conf "$dir"/*; do
[ -f "$conf" ] || continue
BASENAME=$(basename "$conf")
[ "$BASENAME" = "guanghulab-landing.conf" ] && continue
# 排除非.conf和已disabled的文件
echo "$BASENAME" | grep -qE '\.(disabled|bak|old)|by-landing' && continue
if grep -vE '^\s*#' "$conf" 2>/dev/null | grep -qE "listen\s.*(80|443)"; then
echo " ⚠️ 残留冲突: $dir/$BASENAME"
echo " → 强制移除"
rm -f "$conf"
REMAINING=true
fi
done
done
[ "$REMAINING" = "false" ] && echo " ✅ 无残留冲突"
# §5 诊断导出完整nginx.conf去注释版帮助定位问题
echo ""
echo "§5 nginx.conf 生效的完整 server/root 行:"
nginx -T 2>/dev/null | grep -E '^\s*(server\s*\{|root\s|listen\s|server_name\s|ssl_certificate)' | head -30 || echo " (nginx -T 不可用)"
# §6 测试并重载Nginx
echo ""
nginx -t 2>&1
if [ $? -eq 0 ]; then
# 使用 restart 而非 reload确保完全加载新配置
systemctl restart nginx 2>/dev/null || systemctl start nginx
echo "✅ Nginx已重启 · guanghulab-landing.conf 为唯一站点"
else
echo "❌ Nginx配置测试失败尝试恢复..."
# 显示错误详情
nginx -t 2>&1 || true
# 恢复nginx.conf
if [ -f /etc/nginx/nginx.conf.bak.by-landing ]; then
cp /etc/nginx/nginx.conf.bak.by-landing /etc/nginx/nginx.conf
echo " ↩️ 已恢复 nginx.conf"
fi
rm -f "${CONF_FILE}"
if [ -f "/etc/nginx/sites-available/guanghulab-landing.conf" ]; then
rm -f /etc/nginx/sites-available/guanghulab-landing.conf
fi
# 恢复被禁用的冲突配置
for disabled in /etc/nginx/conf.d/*.disabled.by-landing; do
[ -f "$disabled" ] || continue
ORIGINAL="${disabled%.disabled.by-landing}"
mv "$disabled" "$ORIGINAL"
echo " ↩️ 已恢复: $(basename "$ORIGINAL")"
done
nginx -t && systemctl reload nginx
exit 1
fi
NGINX_CMD
rm -f /tmp/ali-cn-domain.conf
- name: 💚 健康检查
env:
SSHPASS: ${{ secrets.ALI_SERVER_PASSWORD }}
run: |
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target << 'HEALTH_CMD'
set -e
echo "═══ 阿里云落地页部署验证 ═══"
# §1 Nginx状态
if systemctl is-active --quiet nginx; then
echo "✅ Nginx: 运行中"
else
echo "❌ Nginx: 已停止"
systemctl start nginx
echo "⚠️ Nginx: 已重新启动"
fi
# §1.5 确认Nginx活跃配置
echo ""
echo "§ Nginx活跃配置:"
echo " conf.d:"
ls /etc/nginx/conf.d/*.conf 2>/dev/null || echo " (无)"
echo " sites-enabled:"
ls /etc/nginx/sites-enabled/ 2>/dev/null || echo " (无)"
# §2 页面访问测试
# 先尝试HTTPS可能配置了SSL再尝试HTTP
echo ""
HTTPS_CODE=$(curl -s -o /tmp/page_https.html -w '%{http_code}' -k https://localhost/ 2>/dev/null || echo "000")
HTTP_CODE=$(curl -s -o /tmp/page_http.html -w '%{http_code}' http://localhost/ 2>/dev/null || echo "000")
echo "§ 页面访问: HTTP=${HTTP_CODE} HTTPS=${HTTPS_CODE}"
# 确定最终使用的页面内容
PAGE_CONTENT=""
if [ "$HTTPS_CODE" = "200" ]; then
PAGE_CONTENT=$(cat /tmp/page_https.html 2>/dev/null || echo "")
echo " → 使用HTTPS响应内容"
elif [ "$HTTP_CODE" = "200" ]; then
PAGE_CONTENT=$(cat /tmp/page_http.html 2>/dev/null || echo "")
echo " → 使用HTTP响应内容"
elif [ "$HTTP_CODE" = "301" ] || [ "$HTTP_CODE" = "302" ]; then
# HTTP redirects to HTTPS, follow it
PAGE_CONTENT=$(curl -sLk http://localhost/ 2>/dev/null || echo "")
echo " → HTTP重定向到HTTPS跟随重定向"
else
echo " ❌ HTTP和HTTPS都无法访问"
PAGE_CONTENT=$(curl -sLk http://localhost/ 2>/dev/null || echo "")
fi
# §3 ICP备案号检查
if echo "$PAGE_CONTENT" | grep -q "陕ICP备2025071211号"; then
echo "✅ ICP备案号: 已显示"
else
echo "❌ ICP备案号: 未找到"
echo " 页面title:"
echo "$PAGE_CONTENT" | grep -o '<title>[^<]*</title>' | head -1 || echo " (无title)"
echo " 页面前300字符:"
echo "$PAGE_CONTENT" | head -c 300
echo ""
fi
# §4 正确内容验证 — 确认是新落地页而不是旧内容
if echo "$PAGE_CONTENT" | grep -q "光湖实验室"; then
echo "✅ 正确内容: 光湖实验室落地页"
elif echo "$PAGE_CONTENT" | grep -iqE "铸渊助手|hololake|age.os"; then
echo "❌ 错误内容: 仍显示旧的铸渊助手/AGE OS页面"
echo " ⚠️ 可能仍有Nginx配置冲突或旧文件被引用"
else
echo "⚠️ 未知内容 — 请手动检查"
fi
# §5 备案链接检查
if echo "$PAGE_CONTENT" | grep -q "beian.miit.gov.cn"; then
echo "✅ 工信部链接: 已配置"
else
echo "⚠️ 工信部链接: 未找到"
fi
# §6 健康端点
HEALTH=$(curl -sLk http://localhost/health 2>/dev/null || curl -sk https://localhost/health 2>/dev/null || echo '{}')
echo "✅ 健康探针: ${HEALTH}"
if echo "$HEALTH" | grep -q "cn-landing"; then
echo "✅ 健康端点来自 guanghulab-landing.conf正确"
elif echo "$HEALTH" | grep -qE "relay|proxy|mcp|hololake"; then
echo "❌ 健康端点来自其他服务 — 仍有Nginx配置冲突"
fi
# §7 文件验证
if [ -f "/opt/guanghulab-landing/sites/cn-landing/index.html" ]; then
echo "✅ 落地页文件: 存在"
ls -la /opt/guanghulab-landing/sites/cn-landing/
else
echo "❌ 落地页文件: 不存在"
fi
echo ""
echo "═══ 部署完成 · guanghulab.com ═══"
HEALTH_CMD
- name: 🧹 清理
if: always()
run: |
rm -f ~/.ssh/id_sg ~/.ssh/config
rm -f /tmp/cn-landing.tar.gz /tmp/ali-cn-domain.conf
# ═══════════════════════════════════════
# §2 健康检查
# ═══════════════════════════════════════
health-check:
name: 💚 阿里云落地页健康检查
if: github.event.inputs.action == 'health-check'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 📦 安装SSH工具
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq sshpass
- name: 🔐 配置SSH连接
env:
ALI_HOST: ${{ secrets.ALI_SERVER_HOST }}
ALI_USER: ${{ secrets.ALI_SERVER_USER }}
ALI_PASS: ${{ secrets.ALI_SERVER_PASSWORD }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
SG_HOST: ${{ secrets.ZY_SERVER_HOST }}
SG_USER: ${{ secrets.ZY_SERVER_USER }}
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
export SSHPASS="${ALI_PASS}"
# 尝试直连
DIRECT_OK=false
sshpass -e ssh -o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=15 -o BatchMode=no \
"${ALI_USER}@${ALI_HOST}" 'echo ok' 2>/dev/null && DIRECT_OK=true || true
if [ "$DIRECT_OK" = "true" ]; then
cat > ~/.ssh/config << EOF
Host ali-target
HostName ${ALI_HOST}
User ${ALI_USER}
StrictHostKeyChecking accept-new
ConnectTimeout 30
EOF
else
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
chmod 600 ~/.ssh/id_sg
ssh-keyscan -H "${SG_HOST}" >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${SG_HOST}
User ${SG_USER}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host ali-target
HostName ${ALI_HOST}
User ${ALI_USER}
ProxyJump sg-jump
StrictHostKeyChecking accept-new
ConnectTimeout 30
EOF
fi
chmod 600 ~/.ssh/config
- name: 💚 执行健康检查
env:
SSHPASS: ${{ secrets.ALI_SERVER_PASSWORD }}
run: |
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target << 'HEALTH_CMD'
echo "═══ 阿里云落地页健康报告 ═══"
echo ""
echo "§1 系统状态:"
uptime
echo ""
echo "§2 Nginx 状态:"
systemctl is-active nginx && echo "Nginx: 运行中" || echo "Nginx: 已停止"
echo ""
echo "§3 Nginx 站点配置:"
ls -la /etc/nginx/sites-enabled/ 2>/dev/null || echo " (目录不存在)"
echo ""
echo "§4 落地页文件:"
ls -la /opt/guanghulab-landing/sites/cn-landing/ 2>/dev/null || echo " 目录不存在"
echo ""
echo "§5 页面访问测试:"
HTTP_CODE=$(curl -sf -o /dev/null -w '%{http_code}' -H "Host: guanghulab.com" http://localhost/ 2>/dev/null || echo "000")
echo "HTTP状态码: ${HTTP_CODE}"
echo ""
echo "§6 ICP备案号检查:"
PAGE=$(curl -sf -H "Host: guanghulab.com" http://localhost/ 2>/dev/null || curl -sf http://localhost/ 2>/dev/null || echo "")
if echo "$PAGE" | grep -q "陕ICP备2025071211号"; then
echo "✅ ICP备案号已显示"
else
echo "❌ ICP备案号未找到"
echo " 页面前300字符:"
echo "$PAGE" | head -c 300
fi
echo ""
echo "§7 健康端点:"
HEALTH=$(curl -sf -H "Host: guanghulab.com" http://localhost/health 2>/dev/null || echo '{}')
echo "响应: ${HEALTH}"
echo ""
echo "§8 HTTPS状态:"
HTTPS_CODE=$(curl -sf -o /dev/null -w '%{http_code}' -H "Host: guanghulab.com" https://localhost/ -k 2>/dev/null || echo "000")
echo "HTTPS状态码: ${HTTPS_CODE}"
echo ""
echo "§9 SSL证书:"
certbot certificates 2>/dev/null || echo " certbot未安装"
echo ""
echo "§10 磁盘使用:"
df -h /
echo ""
echo "§11 内存使用:"
free -m
HEALTH_CMD
- name: 🧹 清理
if: always()
run: rm -f ~/.ssh/id_sg ~/.ssh/config
# ═══════════════════════════════════════
# §3 安装SSL证书
# ═══════════════════════════════════════
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工具
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq sshpass
- name: 🔐 配置SSH连接
env:
ALI_HOST: ${{ secrets.ALI_SERVER_HOST }}
ALI_USER: ${{ secrets.ALI_SERVER_USER }}
ALI_PASS: ${{ secrets.ALI_SERVER_PASSWORD }}
SG_SSH_KEY: ${{ secrets.ZY_SERVER_KEY }}
SG_HOST: ${{ secrets.ZY_SERVER_HOST }}
SG_USER: ${{ secrets.ZY_SERVER_USER }}
run: |
mkdir -p ~/.ssh
chmod 700 ~/.ssh
export SSHPASS="${ALI_PASS}"
DIRECT_OK=false
sshpass -e ssh -o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=15 -o BatchMode=no \
"${ALI_USER}@${ALI_HOST}" 'echo ok' 2>/dev/null && DIRECT_OK=true || true
if [ "$DIRECT_OK" = "true" ]; then
cat > ~/.ssh/config << EOF
Host ali-target
HostName ${ALI_HOST}
User ${ALI_USER}
StrictHostKeyChecking accept-new
ConnectTimeout 30
EOF
else
echo "$SG_SSH_KEY" > ~/.ssh/id_sg
chmod 600 ~/.ssh/id_sg
ssh-keyscan -H "${SG_HOST}" >> ~/.ssh/known_hosts 2>/dev/null
cat > ~/.ssh/config << EOF
Host sg-jump
HostName ${SG_HOST}
User ${SG_USER}
IdentityFile ~/.ssh/id_sg
StrictHostKeyChecking accept-new
BatchMode yes
Host ali-target
HostName ${ALI_HOST}
User ${ALI_USER}
ProxyJump sg-jump
StrictHostKeyChecking accept-new
ConnectTimeout 30
EOF
fi
chmod 600 ~/.ssh/config
- name: 🔐 安装certbot并申请证书
env:
SSHPASS: ${{ secrets.ALI_SERVER_PASSWORD }}
ZY_CN_DOMAIN: ${{ secrets.ZY_CN_DOMAIN }}
run: |
BARE_DOMAIN="${ZY_CN_DOMAIN:-guanghulab.com}"
BARE_DOMAIN="${BARE_DOMAIN#www.}"
echo "🔐 为 ${BARE_DOMAIN} + www.${BARE_DOMAIN} 申请SSL证书..."
sshpass -e ssh -F ~/.ssh/config -o BatchMode=no ali-target << SSLCMD
set -e
echo "═══ SSL证书安装 (阿里云) ═══"
# 安装certbot
if ! command -v certbot &> /dev/null; then
echo "📦 安装certbot..."
if command -v apt-get &> /dev/null; then
apt-get update -qq
apt-get install -y -qq certbot python3-certbot-nginx
elif command -v yum &> /dev/null; then
yum install -y -q certbot python3-certbot-nginx
elif command -v dnf &> /dev/null; then
dnf install -y -q certbot python3-certbot-nginx
fi
else
echo "✅ certbot已安装: \$(certbot --version 2>&1)"
fi
# 确认Nginx运行中
if ! systemctl is-active --quiet nginx; then
systemctl start nginx
fi
# 验证域名格式
if ! echo "${BARE_DOMAIN}" | grep -qE '^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$'; then
echo "❌ 域名格式无效: ${BARE_DOMAIN}"
exit 1
fi
# 申请证书
echo ""
echo "§1 申请Let's Encrypt证书..."
certbot --nginx \
-d ${BARE_DOMAIN} \
-d www.${BARE_DOMAIN} \
--non-interactive \
--agree-tos \
--email admin@${BARE_DOMAIN} \
--redirect \
--no-eff-email
# 验证
echo ""
echo "§2 验证证书..."
certbot certificates
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}"
echo ""
echo "═══ SSL安装完成 ═══"
echo "🌐 https://${BARE_DOMAIN} 已启用"
SSLCMD
- name: 🧹 清理
if: always()
run: rm -f ~/.ssh/id_sg ~/.ssh/config