60 lines
1.8 KiB
Bash
60 lines
1.8 KiB
Bash
#!/usr/bin/env bash
|
||
#
|
||
# 启用 HTTPS 配置:证书就绪后,把 ssl.d.available/ 下的 server 块
|
||
# 复制进 ssl.d/(nginx 容器 bind mount 并 include 的目录),校验后优雅重载 nginx。
|
||
#
|
||
# 冷启动时 ssl.d/ 为空,nginx 只加载 conf.d/00-http.conf(不引用证书),
|
||
# 因此可以在没有证书的情况下启动并提供 80 端口 —— 这是打破
|
||
# "先有证书还是先有 nginx" 死锁的关键。
|
||
#
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
AVAILABLE="$SCRIPT_DIR/ssl.d.available"
|
||
ENABLED="$SCRIPT_DIR/ssl.d"
|
||
|
||
CERT_NAME="${CERT_NAME:-stonelan.cn}"
|
||
CERT_FULL="/etc/letsencrypt/live/$CERT_NAME/fullchain.pem"
|
||
DOMAINS="${DOMAINS:-fastgpt.stonelan.cn gitea.stonelan.cn image.stonelan.cn registry.stonelan.cn www.stonelan.cn}"
|
||
|
||
# 证书在宿主机上,直接判断即可(不再需要进容器)
|
||
if [ ! -f "$CERT_FULL" ]; then
|
||
echo "证书尚未生成:$CERT_FULL"
|
||
echo "请先执行 acme/issue.sh,成功后再运行本脚本"
|
||
exit 0
|
||
fi
|
||
|
||
mkdir -p "$ENABLED"
|
||
cd "$SCRIPT_DIR"
|
||
|
||
copied=()
|
||
for d in $DOMAINS; do
|
||
conf="$AVAILABLE/$d.conf"
|
||
if [ ! -f "$conf" ]; then
|
||
echo "跳过 $d:缺少 $conf"
|
||
continue
|
||
fi
|
||
|
||
if ! cmp -s "$conf" "$ENABLED/$d.conf" 2>/dev/null; then
|
||
cp "$conf" "$ENABLED/$d.conf"
|
||
copied+=("$ENABLED/$d.conf")
|
||
echo "已启用 $d"
|
||
fi
|
||
done
|
||
|
||
if [ "${#copied[@]}" -eq 0 ]; then
|
||
echo "HTTPS 配置已是最新,无需变更"
|
||
exit 0
|
||
fi
|
||
|
||
if out=$(docker compose exec -T nginx-proxy nginx -t 2>&1); then
|
||
echo "$out" | sed 's/^/ /'
|
||
docker kill -s HUP nginx-proxy
|
||
echo "nginx 已重载,HTTPS 配置生效"
|
||
else
|
||
echo "$out" | sed 's/^/ /'
|
||
echo "nginx 配置校验失败,回滚本次变更" >&2
|
||
rm -f "${copied[@]}"
|
||
exit 1
|
||
fi
|