fix: 修改Certbot为webroot模式,配合两阶段Nginx部署

问题:
- Certbot使用--nginx插件时需要已存在的server block
- 原执行顺序在Nginx配置前就部署SSL,导致找不到server block

改进:
1. 改用certonly --webroot模式(不自动修改Nginx配置)
2. 使用项目frontend目录作为webroot进行域名验证
3. 手动创建证书软链接到/etc/nginx/ssl/(与其他方法统一)
4. 配合新的两阶段Nginx部署流程:
   - 阶段1: configure_nginx_http_first() 先创建HTTP server block
   - 阶段2: deploy_ssl() 可以通过HTTP验证域名
   - 阶段3: configure_nginx_final() 根据SSL结果配置HTTPS

修复错误:
"Could not automatically find a matching server block for [domain]"

相关提交:
- 7c4e1ed (重构Nginx配置为两阶段部署)
- 18512d9 (增强acme.sh验证)
- 4a73a8c (Gitee镜像加速)
This commit is contained in:
WanWanYun
2025-11-13 08:51:13 +08:00
parent 18512d92ed
commit 565bf7dffc

View File

@@ -1276,11 +1276,19 @@ deploy_certbot() {
;;
esac
# 申请证书
# 申请证书使用webroot模式不自动修改Nginx配置
echo ""
if certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --email "admin@${DOMAIN}" --redirect; then
print_info "正在申请 Let's Encrypt 证书..."
if certbot certonly --webroot -w "${PROJECT_DIR}/frontend" -d "$DOMAIN" --non-interactive --agree-tos --email "admin@${DOMAIN}"; then
# 将证书复制到Nginx SSL目录
mkdir -p /etc/nginx/ssl
ln -sf "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" "/etc/nginx/ssl/${DOMAIN}.crt"
ln -sf "/etc/letsencrypt/live/${DOMAIN}/privkey.pem" "/etc/nginx/ssl/${DOMAIN}.key"
# 配置自动续期
systemctl enable certbot.timer 2>/dev/null || true
print_success "Certbot SSL证书申请成功"
return 0
else
@@ -1288,8 +1296,8 @@ deploy_certbot() {
echo ""
print_warning "常见失败原因:"
echo " 1. 域名未正确解析到此服务器"
echo " 2. 防火墙阻止了80/443端口"
echo " 3. Nginx未正确配置"
echo " 2. 防火墙阻止了80端口"
echo " 3. Nginx未正确配置或未启动"
echo " 4. Let's Encrypt速率限制"
echo ""
return 1
@@ -1903,6 +1911,133 @@ build_upload_tool() {
fi
}
################################################################################
# Nginx配置 - 分步骤执行
################################################################################
# 步骤1: 先配置HTTP Nginx为SSL证书验证做准备
configure_nginx_http_first() {
print_step "配置基础HTTP Nginx用于SSL证书验证..."
# 总是先配置HTTP模式
local server_name="${DOMAIN:-_}"
cat > /etc/nginx/sites-available/${PROJECT_NAME}.conf << EOF
server {
listen ${HTTP_PORT};
server_name ${server_name};
# 文件上传大小限制10GB
client_max_body_size 10G;
# 前端静态文件
location / {
root ${PROJECT_DIR}/frontend;
index app.html;
try_files \$uri \$uri/ /app.html;
}
# 后端API
location /api {
proxy_pass http://localhost:${BACKEND_PORT};
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_cache_bypass \$http_upgrade;
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_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 300s;
}
# 分享页面
location /s/ {
proxy_pass http://localhost:${BACKEND_PORT};
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;
}
# 静态资源
location /libs {
alias ${PROJECT_DIR}/frontend/libs;
expires 30d;
}
# 上传工具下载
location /download-tool {
alias ${PROJECT_DIR}/upload-tool/dist;
}
}
EOF
# 创建软链接
ln -sf /etc/nginx/sites-available/${PROJECT_NAME}.conf /etc/nginx/sites-enabled/${PROJECT_NAME}.conf
# 删除默认站点
rm -f /etc/nginx/sites-enabled/default
# 测试nginx配置
if ! nginx -t; then
print_error "Nginx配置测试失败"
return 1
fi
# 启动Nginx
systemctl restart nginx
if ! systemctl is-active --quiet nginx; then
print_error "Nginx启动失败"
return 1
fi
print_success "基础HTTP Nginx配置完成"
echo ""
}
# 步骤2: 根据SSL结果配置最终Nginx
configure_nginx_final() {
print_step "配置最终Nginx..."
# 检查SSL是否成功部署
local ssl_deployed=false
if [[ "$USE_DOMAIN" == "true" ]] && [[ "$SSL_METHOD" != "8" ]]; then
# 检查SSL证书文件是否存在
if [[ -f /etc/nginx/ssl/${DOMAIN}.crt ]] && [[ -f /etc/nginx/ssl/${DOMAIN}.key ]]; then
ssl_deployed=true
print_info "检测到SSL证书配置HTTPS..."
else
print_warning "SSL证书不存在保持HTTP配置"
fi
fi
# 根据SSL状态配置
if [[ "$ssl_deployed" == "true" ]]; then
# 配置HTTPS
configure_nginx_https
else
# 保持HTTP已在第一步配置这里只需确认
print_info "使用HTTP配置"
fi
# 测试nginx配置
if ! nginx -t; then
print_error "Nginx配置测试失败"
return 1
fi
# 重载nginx
systemctl reload nginx
print_success "Nginx最终配置完成"
echo ""
}
configure_nginx() {
print_step "配置Nginx..."
@@ -2970,11 +3105,14 @@ main() {
# 打包上传工具
build_upload_tool
# 部署SSL证书
# 先配置基础HTTP NginxSSL证书申请需要
configure_nginx_http_first
# 部署SSL证书需要HTTP server block进行验证
deploy_ssl
# 配置Nginx
configure_nginx
# 根据SSL结果配置最终Nginx
configure_nginx_final
# 启动后端服务
start_backend_service