From 3768ec0a31f0196e8eac2218f979665e533104b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=AD=86?= <2685475410@qq.com> Date: Sat, 10 Oct 2026 12:52:53 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20fix(deploy):=20=E8=AF=81?= =?UTF-8?q?=E4=B9=A6=E6=96=B9=E6=A1=88=E4=BB=8E=20certbot=20=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=20acme.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 证书目录改为可配置 CERT_DIR(默认 /etc/nginx/ssl),适配 acme.sh --install-cert 安装位置 - nginx 模板与提示文案同步去 certbot 依赖,ACME http-01 验证路径保持 webroot 兼容 --- .deploy.env.example | 4 ++- deploy.sh | 68 +++++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 37 deletions(-) diff --git a/.deploy.env.example b/.deploy.env.example index 65c695a..f126d2f 100644 --- a/.deploy.env.example +++ b/.deploy.env.example @@ -32,8 +32,10 @@ SRC_DIR="/root/code/novel/fanqie-go" DOMAIN="fq.20010117.xyz" # ---------- 证书 ---------- -# Certbot 申请证书的邮箱,用于接收过期提醒 +# acme.sh 申请证书的邮箱,用于账户注册与过期提醒 CERT_EMAIL="you@example.com" +# 证书安装目录(acme.sh --install-cert 目标,nginx 配置从此处读取) +# CERT_DIR="/etc/nginx/ssl" # ---------- 编译 ---------- # BUILD_TARGET="./cmd/fanqie" diff --git a/deploy.sh b/deploy.sh index 46772f4..a8740df 100755 --- a/deploy.sh +++ b/deploy.sh @@ -40,6 +40,7 @@ NGINX_CONF="${NGINX_CONF:-/etc/nginx/conf.d/${APP_NAME}.conf}" APP_PORT="${APP_PORT:-40180}" # 程序监听端口 DOMAIN="${DOMAIN:-fq.20010117.xyz}" # 域名 CERT_EMAIL="${CERT_EMAIL:-admin@${DOMAIN}}" # 证书申请邮箱(过期提醒) +CERT_DIR="${CERT_DIR:-/etc/nginx/ssl}" # 证书目录(acme.sh --install-cert 安装位置) BUILD_TARGET="${BUILD_TARGET:-./cmd/fanqie}" # go build 的包路径 ENV_FILE="${ENV_FILE:-${SRC_DIR}/.env}" # 应用环境变量(.env.example 为模板) KEEP_VERSIONS="${KEEP_VERSIONS:-5}" # 保留最近几个版本 @@ -245,8 +246,8 @@ restart_and_verify() { # 写入 nginx 配置(--init 与 --sync-nginx 共用的唯一模板来源) -# 模板自带完整 443/证书配置(证书存在时启用),不依赖 certbot --nginx 注入—— -# 这样 --sync-nginx 覆盖配置时不会丢失 HTTPS 段(certbot 注入式配置会被覆盖回 80-only) +# 模板自带完整 443/证书配置(证书存在时启用),不依赖签发工具注入—— +# 这样 --sync-nginx 覆盖配置时不会丢失 HTTPS 段(注入式配置会被覆盖回 80-only) write_nginx_conf() { # 反代 location(80 无证书时与 443 共用) local proxy_locations @@ -281,7 +282,7 @@ LOC_EOF ) local ssl_block="" - if [ -f "/etc/letsencrypt/live/${DOMAIN}/fullchain.pem" ]; then + if [ -f "${CERT_DIR}/${DOMAIN}/fullchain.pem" ]; then log "检测到 ${DOMAIN} 证书,配置启用 443" ssl_block=$(cat </dev/null <<'HOOK' -#!/bin/bash -if /usr/sbin/nginx -t 2>/dev/null; then - systemctl reload nginx -fi -HOOK - $SUDO chmod +x "${HOOK_FILE}" - fi - - # ---- 首次初始化自动申请 HTTPS 证书(一次性;续期由 certbot.timer 自动处理)---- - if [ ! -d "/etc/letsencrypt/live/${DOMAIN}" ]; then - if command -v certbot >/dev/null 2>&1; then - log "未检测到证书,尝试自动申请: ${DOMAIN}" - $SUDO mkdir -p /var/www/html - if $SUDO certbot certonly --webroot -w /var/www/html -d "${DOMAIN}" --non-interactive --agree-tos -m "${CERT_EMAIL}"; then - log "证书申请成功,写入 443 配置..." - write_nginx_conf - else - warn "证书申请失败,请检查域名解析与 80 端口;成功后重跑: $0 --sync-nginx" - fi - else - warn "未安装 certbot,跳过证书申请。可手动执行: dnf install certbot python3-certbot-nginx" - fi - else + # ---- 首次初始化自动申请 HTTPS 证书(一次性;续期由 acme.sh cron 自动处理)---- + if [ -f "${CERT_DIR}/${DOMAIN}/fullchain.pem" ]; then log "证书已存在,跳过申请" + else + # 定位 acme.sh:PATH → 当前用户目录 → root 目录(sudo 后 HOME 可能被重置) + ACME_SH="$(command -v acme.sh 2>/dev/null || true)" + for c in "${HOME}/.acme.sh/acme.sh" "/root/.acme.sh/acme.sh"; do + if [ -z "$ACME_SH" ] && [ -x "$c" ]; then ACME_SH="$c"; fi + done + if [ -z "$ACME_SH" ]; then + err "未找到 acme.sh,请先安装: curl https://get.acme.sh | sh -s email=${CERT_EMAIL}" + exit 1 + fi + log "未检测到证书,使用 acme.sh 申请: ${DOMAIN}" + $SUDO mkdir -p /var/www/html "${CERT_DIR}/${DOMAIN}" + if $SUDO "$ACME_SH" --issue -d "${DOMAIN}" -w /var/www/html --server letsencrypt --keylength ec-256 -m "${CERT_EMAIL}" \ + && $SUDO "$ACME_SH" --install-cert -d "${DOMAIN}" --ecc \ + --fullchain-file "${CERT_DIR}/${DOMAIN}/fullchain.pem" \ + --key-file "${CERT_DIR}/${DOMAIN}/privkey.pem" \ + --reloadcmd "systemctl reload nginx"; then + log "证书申请成功,写入 443 配置..." + write_nginx_conf + else + warn "证书申请失败,请检查域名解析与 80 端口;成功后重跑: $0 --sync-nginx" + fi fi if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" != "Disabled" ]; then