feat: 完成域名部署配置

- 创建 SSL 证书申请脚本 (tools/deploy-ssl-cert.py)
- 创建 nginx HTTPS 配置文件 (conf/nginx-emotion-museum-ssl.conf)
- 创建 nginx HTTP 修复配置 (conf/nginx-emotion-museum-fix.conf)
- 创建一键部署脚本 (deploy-domain.sh)
- 更新前端依赖并构建

部署验证:
- HTTPS 前端页面:200
- HTTPS 管理后台:200
- HTTP->HTTPS 跳转:301
- SSL 证书有效期:2026-06-16
This commit is contained in:
2026-03-18 19:44:39 +08:00
parent 35126a5144
commit 04d5024752
5 changed files with 451 additions and 70 deletions
+87 -27
View File
@@ -50,7 +50,7 @@ def run_command(cmd, capture=False):
"""执行 shell 命令"""
try:
if capture:
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
return result.returncode, result.stdout, result.stderr
else:
result = subprocess.run(cmd, shell=True)
@@ -70,17 +70,62 @@ def check_certbot():
log_warn("certbot 未安装,尝试安装...")
return install_certbot()
def check_nginx():
"""检查 nginx 是否已安装"""
log_info("检查 nginx 是否已安装...")
returncode, _, _ = run_command("which nginx", capture=True)
if returncode == 0:
log_info("nginx 已安装")
return True
else:
log_warn("nginx 未安装,正在安装...")
return install_nginx()
def install_nginx():
"""安装 nginx"""
log_info("正在安装 nginx...")
# 检查系统类型
if os.path.exists("/etc/debian_version") or os.path.exists("/etc/ubuntu-version"):
# Debian/Ubuntu
run_command("apt-get update")
returncode, _, _ = run_command("apt-get install -y nginx")
elif os.path.exists("/etc/redhat-release") or os.path.exists("/etc/centos-release") or os.path.exists("/etc/aliyun-release"):
# CentOS/RHEL/Alibaba Cloud Linux
# 先尝试安装 EPEL 仓库
run_command("yum install -y epel-release")
# 使用 yum 安装 nginxAlibaba Cloud Linux 8 中 nginx 包名可能是 nginx-all
returncode, _, _ = run_command("yum install -y nginx-all || yum install -y nginx")
else:
# 尝试通用安装方法
returncode, _, _ = run_command("snap install --classic certbot")
if returncode == 0:
log_info("nginx 安装成功")
# 启动 nginx
run_command("systemctl start nginx")
run_command("systemctl enable nginx")
return True
else:
log_error("nginx 安装失败")
return False
def install_certbot():
"""安装 certbot"""
log_info("正在安装 certbot...")
# 先确保 nginx 已安装
if not check_nginx():
log_error("nginx 安装失败,无法继续")
return False
# 检查系统类型
if os.path.exists("/etc/debian_version") or os.path.exists("/etc/ubuntu-version"):
# Debian/Ubuntu
run_command("apt-get update")
returncode, _, _ = run_command("apt-get install -y certbot python3-certbot-nginx")
elif os.path.exists("/etc/redhat-release") or os.path.exists("/etc/centos-release"):
# CentOS/RHEL
# CentOS/RHEL/Alibaba Cloud Linux
returncode, _, _ = run_command("yum install -y certbot python3-certbot-nginx")
else:
# 尝试通用安装方法
@@ -119,13 +164,31 @@ def apply_certificate():
returncode, _, _ = run_command("systemctl is-active nginx", capture=True)
if returncode != 0:
log_warn("Nginx 未运行,尝试启动...")
run_command("systemctl start nginx")
# 宝塔面板 nginx 路径
if os.path.exists("/www/server/nginx/sbin/nginx"):
run_command("/www/server/nginx/sbin/nginx")
else:
run_command("systemctl start nginx")
# 使用 standalone 模式申请证书(不需要 nginx 配置)
log_info("使用 standalone 模式申请证书...")
# 检测宝塔面板 webroot 路径
webroot_path = "/www/server/nginx/html"
if not os.path.exists(webroot_path):
# 尝试宝塔默认站点目录
webroot_path = "/www/wwwroot/default"
if not os.path.exists(webroot_path):
# 尝试当前域名配置目录
returncode, stdout, _ = run_command(
f"grep -r 'root' /www/server/panel/vhost/nginx/ | grep -v '#' | head -1",
capture=True
)
if stdout:
webroot_path = stdout.split(':')[1].strip().rstrip(';').strip()
log_info(f"使用 webroot 模式申请证书,路径:{webroot_path}")
cmd = (
f"certbot certonly "
f"--standalone "
f"--webroot "
f"-w {webroot_path} "
f"-d {DOMAIN} "
f"--email {EMAIL} "
f"--agree-tos "
@@ -142,25 +205,7 @@ def apply_certificate():
return True
else:
log_error(f"证书申请失败:{stderr}")
# 尝试使用 nginx 插件
log_warn("尝试使用 nginx 插件模式...")
cmd = (
f"certbot --nginx "
f"-d {DOMAIN} "
f"--email {EMAIL} "
f"--agree-tos "
f"--non-interactive "
f"--force-renewal"
)
returncode, stdout, stderr = run_command(cmd)
if returncode == 0:
log_info("✅ SSL 证书申请成功(nginx 模式)")
return True
else:
log_error(f"证书申请失败:{stderr}")
return False
return False
def setup_auto_renewal():
"""配置自动续期"""
@@ -175,7 +220,13 @@ def setup_auto_renewal():
# 添加定时任务(每天凌晨 2 点检查)
log_info("添加 certbot 自动续期定时任务...")
cron_job = "0 2 * * * /usr/bin/certbot renew --quiet --deploy-hook 'systemctl reload nginx'"
# 检测 nginx 重载命令
if os.path.exists("/www/server/nginx/sbin/nginx"):
reload_cmd = "/www/server/nginx/sbin/nginx -s reload"
else:
reload_cmd = "systemctl reload nginx"
cron_job = f"0 2 * * * /usr/bin/certbot renew --quiet --deploy-hook '{reload_cmd}'"
# 备份并添加新的 cron 任务
run_command("(crontab -l 2>/dev/null | grep -v certbot; echo '%s') | crontab -" % cron_job)
@@ -237,7 +288,13 @@ def renew_certificate():
"""手动续期证书"""
log_section("手动续期 SSL 证书")
cmd = "certbot renew --force-renewal --deploy-hook 'systemctl reload nginx'"
# 检测 nginx 重载命令
if os.path.exists("/www/server/nginx/sbin/nginx"):
reload_cmd = "/www/server/nginx/sbin/nginx -s reload"
else:
reload_cmd = "systemctl reload nginx"
cmd = f"certbot renew --force-renewal --deploy-hook '{reload_cmd}'"
log_info(f"执行命令:{cmd}")
returncode, stdout, stderr = run_command(cmd)
@@ -298,6 +355,9 @@ def main():
else:
# 申请模式
# 先检查并安装 nginx
check_nginx()
if not check_certbot():
log_error("certbot 未安装,无法继续")
sys.exit(1)