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:
@@ -0,0 +1,161 @@
|
||||
# Emotion Museum 前端应用 Nginx 配置
|
||||
# 配置路径:/www/server/panel/vhost/nginx/emotion-museum.conf
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name lifescript.happylifeos.com;
|
||||
|
||||
# Let's Encrypt ACME 挑战位置(必须在其他 location 之前)
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /data/www/acme-challenge;
|
||||
allow all;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# 根路径不提供站点,避免跳转或兜底到其他 server
|
||||
location = / {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# 前端应用路径
|
||||
location /emotion-museum/ {
|
||||
alias /data/www/emotion-museum/;
|
||||
|
||||
# 启用目录索引(可选)
|
||||
autoindex off;
|
||||
|
||||
# 处理 Vue Router 的 history 模式
|
||||
# 所有非文件请求都重定向到 index.html
|
||||
try_files $uri $uri/ /emotion-museum/index.html;
|
||||
|
||||
# 设置缓存策略
|
||||
# HTML 文件不缓存
|
||||
location ~ \.html?$ {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# 静态资源缓存 1 年
|
||||
location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
expires 1y;
|
||||
}
|
||||
}
|
||||
|
||||
# 处理不带末尾斜杠的 /emotion-museum 请求
|
||||
location = /emotion-museum {
|
||||
rewrite ^(.*)$ $1/ permanent;
|
||||
}
|
||||
|
||||
# 管理后台应用路径
|
||||
location /emotion-museum-admin/ {
|
||||
alias /data/www/emotion-museum-admin/;
|
||||
|
||||
# 启用目录索引(可选)
|
||||
autoindex off;
|
||||
|
||||
# 处理 Vue Router 的 history 模式
|
||||
# 所有非文件请求都重定向到 index.html
|
||||
try_files $uri $uri/ /emotion-museum-admin/index.html;
|
||||
|
||||
# 设置缓存策略
|
||||
# HTML 文件不缓存
|
||||
location ~ \.html?$ {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# 静态资源缓存 1 年
|
||||
location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
expires 1y;
|
||||
}
|
||||
}
|
||||
|
||||
# 处理不带末尾斜杠的 /emotion-museum-admin 请求
|
||||
location = /emotion-museum-admin {
|
||||
rewrite ^(.*)$ $1/ permanent;
|
||||
}
|
||||
|
||||
# 体验前端应用路径 (course-web)
|
||||
location /course-of-life/ {
|
||||
alias /data/www/course-of-life/;
|
||||
|
||||
# 启用目录索引(可选)
|
||||
autoindex off;
|
||||
|
||||
# 处理 SPA 的 history 模式 (React Router)
|
||||
# 所有非文件请求都重定向到 index.html
|
||||
try_files $uri $uri/ /course-of-life/index.html;
|
||||
|
||||
# 设置缓存策略
|
||||
# HTML 文件不缓存
|
||||
location ~ \.html?$ {
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
add_header Expires "0";
|
||||
}
|
||||
|
||||
# 静态资源缓存 1 年
|
||||
location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
expires 1y;
|
||||
}
|
||||
}
|
||||
|
||||
# 处理不带末尾斜杠的 /course-of-life 请求
|
||||
location = /course-of-life {
|
||||
# 不进行 301/302 外部跳转:内部改写到 /course-of-life/ 交给下方 SPA location 处理
|
||||
# 这样 URL 仍是 /course-of-life,但返回内容与 /course-of-life/ 完全一致(且不会触发"下载")
|
||||
rewrite ^ /course-of-life/ last;
|
||||
}
|
||||
|
||||
# 后端 API 代理
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:19089;
|
||||
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_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# WebSocket 代理
|
||||
location /ws {
|
||||
proxy_pass http://127.0.0.1:19089;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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;
|
||||
|
||||
# WebSocket 超时设置
|
||||
proxy_connect_timeout 7d;
|
||||
proxy_send_timeout 7d;
|
||||
proxy_read_timeout 7d;
|
||||
}
|
||||
|
||||
# 健康检查端点
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# 禁止访问敏感文件
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
access_log /www/wwwlogs/access.log;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
# Emotion Museum HTTPS Nginx 配置
|
||||
# 配置路径:/www/server/panel/vhost/nginx/emotion-museum.conf
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name lifescript.happylifeos.com;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/lifescript.happylifeos.com/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/lifescript.happylifeos.com/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 10m;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
root /data/www/acme-challenge;
|
||||
allow all;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location = / {
|
||||
return 404;
|
||||
}
|
||||
|
||||
location /emotion-museum/ {
|
||||
alias /data/www/emotion-museum/;
|
||||
autoindex off;
|
||||
try_files $uri $uri/ /emotion-museum/index.html;
|
||||
}
|
||||
|
||||
location = /emotion-museum {
|
||||
rewrite ^(.*)$ $1/ permanent;
|
||||
}
|
||||
|
||||
location /emotion-museum-admin/ {
|
||||
alias /data/www/emotion-museum-admin/;
|
||||
autoindex off;
|
||||
try_files $uri $uri/ /emotion-museum-admin/index.html;
|
||||
}
|
||||
|
||||
location = /emotion-museum-admin {
|
||||
rewrite ^(.*)$ $1/ permanent;
|
||||
}
|
||||
|
||||
location /course-of-life/ {
|
||||
alias /data/www/course-of-life/;
|
||||
autoindex off;
|
||||
try_files $uri $uri/ /course-of-life/index.html;
|
||||
}
|
||||
|
||||
location = /course-of-life {
|
||||
rewrite ^ /course-of-life/ last;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://127.0.0.1:19089;
|
||||
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_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
location /ws {
|
||||
proxy_pass http://127.0.0.1:19089;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
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_connect_timeout 7d;
|
||||
proxy_send_timeout 7d;
|
||||
proxy_read_timeout 7d;
|
||||
}
|
||||
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
access_log /www/wwwlogs/ssl-access.log;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name lifescript.happylifeos.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Author: Emotion Museum Team
|
||||
# Created: 2026-03-18
|
||||
# Purpose: 一键部署域名配置(SSL + Nginx + 后端 + 前端)
|
||||
#
|
||||
# 使用方法:
|
||||
# ./deploy-domain.sh
|
||||
#
|
||||
# 前置条件:
|
||||
# - 已配置 SSH 免密登录到服务器
|
||||
# - 服务器已安装 certbot 和 nginx
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# 配置
|
||||
SERVER="101.200.208.45"
|
||||
DOMAIN="lifescript.happylifeos.com"
|
||||
EMAIL="admin@happylifeos.com"
|
||||
|
||||
# 颜色
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
||||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||||
log_section() { echo -e "\n${BLUE}==== $1 ====${NC}\n"; }
|
||||
|
||||
log_section "情绪博物馆 - 域名部署"
|
||||
|
||||
# 1. 检查 SSH 连接
|
||||
log_info "检查 SSH 连接..."
|
||||
ssh root@$SERVER "echo 'SSH 连接正常'" || { log_error "SSH 连接失败"; exit 1; }
|
||||
|
||||
# 2. 上传 SSL 证书脚本
|
||||
log_info "上传 SSL 证书脚本..."
|
||||
scp tools/deploy-ssl-cert.py root@$SERVER:/tmp/deploy-ssl-cert.py
|
||||
|
||||
# 3. 执行 SSL 证书验证(证书应该已申请)
|
||||
log_info "验证 SSL 证书..."
|
||||
ssh root@$SERVER "python3 /tmp/deploy-ssl-cert.py --verify" || log_warn "证书验证失败,请检查"
|
||||
|
||||
# 4. 上传并应用 Nginx 配置
|
||||
log_info "上传 Nginx 配置..."
|
||||
scp conf/nginx-emotion-museum-fix.conf root@$SERVER:/tmp/nginx-fix.conf
|
||||
ssh root@$SERVER "
|
||||
# 备份当前配置
|
||||
cp /www/server/panel/vhost/nginx/emotion-museum.conf /www/server/panel/vhost/nginx/emotion-museum.conf.bak 2>/dev/null || true
|
||||
# 应用新配置
|
||||
cp /tmp/nginx-fix.conf /www/server/panel/vhost/nginx/emotion-museum.conf
|
||||
# 验证并重载
|
||||
/www/server/nginx/sbin/nginx -t && /www/server/nginx/sbin/nginx -s reload
|
||||
"
|
||||
log_info "Nginx 配置已应用"
|
||||
|
||||
# 5. 部署后端
|
||||
log_info "部署后端服务..."
|
||||
cd backend-single && mvn clean package -DskipTests && cd ..
|
||||
scp backend-single/target/backend-single-1.0.0.jar root@$SERVER:/opt/emotion-museum/backend.jar
|
||||
ssh root@$SERVER "
|
||||
systemctl stop emotion-museum-backend 2>/dev/null || true
|
||||
sleep 2
|
||||
# 备份旧版本
|
||||
cp /opt/emotion-museum/backend.jar /opt/emotion-museum/backend.jar.bak 2>/dev/null || true
|
||||
# 后端已在上面 scp 覆盖,重启服务
|
||||
systemctl restart emotion-museum-backend 2>/dev/null || (cd /opt/emotion-museum && nohup java -jar backend.jar > /dev/null 2>&1 &)
|
||||
sleep 3
|
||||
echo '后端服务状态:'
|
||||
systemctl status emotion-museum-backend 2>/dev/null || ps aux | grep backend.jar | grep -v grep
|
||||
"
|
||||
|
||||
# 6. 部署前端
|
||||
log_info "部署前端..."
|
||||
cd web && npm run build && cd ..
|
||||
scp -r web/dist/* root@$SERVER:/data/www/emotion-museum/
|
||||
log_info "前端部署完成"
|
||||
|
||||
# 7. 部署管理后台
|
||||
log_info "部署管理后台..."
|
||||
cd web-admin && npm run build && cd ..
|
||||
scp -r web-admin/dist/* root@$SERVER:/data/www/emotion-museum-admin/
|
||||
log_info "管理后台部署完成"
|
||||
|
||||
# 8. 验证部署
|
||||
log_section "验证部署"
|
||||
log_info "验证 HTTPS 访问..."
|
||||
curl -k -s -o /dev/null -w " 前端页面:HTTP %{http_code}\n" https://$DOMAIN/emotion-museum/
|
||||
curl -k -s -o /dev/null -w " 管理后台:HTTP %{http_code}\n" https://$DOMAIN/emotion-museum-admin/
|
||||
curl -k -s -o /dev/null -w " API 代理:HTTP %{http_code}\n" https://$DOMAIN/api/health
|
||||
curl -s -o /dev/null -w " HTTP 跳转:HTTP %{http_code}\n" http://$DOMAIN/
|
||||
|
||||
log_section "部署完成"
|
||||
log_info "访问地址:"
|
||||
log_info " 用户前端:https://$DOMAIN/emotion-museum/"
|
||||
log_info " 管理后台:https://$DOMAIN/emotion-museum-admin/"
|
||||
log_info " API 地址:https://$DOMAIN/api/"
|
||||
log_info " WebSocket: wss://$DOMAIN/ws"
|
||||
+85
-25
@@ -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 安装 nginx,Alibaba 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 未运行,尝试启动...")
|
||||
# 宝塔面板 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,24 +205,6 @@ 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
|
||||
|
||||
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)
|
||||
|
||||
Generated
-43
@@ -2408,21 +2408,6 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bufferutil": {
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmmirror.com/bufferutil/-/bufferutil-4.0.9.tgz",
|
||||
"integrity": "sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"node-gyp-build": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/cac": {
|
||||
"version": "6.7.14",
|
||||
"resolved": "https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz",
|
||||
@@ -5616,19 +5601,6 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
"version": "4.8.4",
|
||||
"resolved": "https://registry.npmmirror.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
|
||||
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz",
|
||||
@@ -7409,21 +7381,6 @@
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/utf-8-validate": {
|
||||
"version": "5.0.10",
|
||||
"resolved": "https://registry.npmmirror.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
|
||||
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"node-gyp-build": "^4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.14.2"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
||||
Reference in New Issue
Block a user