73e026a4df
deploy-pangolin / deploy (push) Has been cancelled
- edge 改为自定义镜像:官方 nginx + certbot + dns-cloudflare 插件 - pangolin-entrypoint.sh:后台每12h certbot renew,续期后本容器内 nginx -s reload - 不再需要宿主 cron / docker socket / 独立 certbot 服务做日常续期 - /etc/letsencrypt 改 rw 挂载,挂入 cloudflare.ini - compose 去掉 build:(宿主 docker-compose 不支持 compose build),改脚本 docker build - deploy.sh/cutover.sh: docker build -t pangolin-edge:local 后再 up Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
2.6 KiB
Bash
Executable File
66 lines
2.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# cutover.sh —— 一次性切换:宿主 nginx → pangolin-edge 容器(需 root 一次)。
|
|
# sudo bash /home/ec2-user/pangolin/scripts/cutover.sh
|
|
# 选空闲时段执行;代理(Marzban REALITY)会有秒级重连,Shadowrocket 自动恢复。
|
|
# 失败可秒级回滚:docker-compose -p pangolin stop edge && systemctl start nginx
|
|
set -euo pipefail
|
|
|
|
if [[ "$(id -u)" -ne 0 ]]; then
|
|
echo "请以 root 运行:sudo bash $0" >&2
|
|
exit 1
|
|
fi
|
|
|
|
cd "$(dirname "$0")/.." # -> deploy/
|
|
EDGE_IMAGE="nginx:1.27-alpine"
|
|
|
|
echo "==> [1/4] 切换前校验 edge 配置(含证书路径)"
|
|
docker run --rm \
|
|
-v "$PWD/edge/nginx.conf:/etc/nginx/nginx.conf:ro" \
|
|
-v "$PWD/edge/stream.conf:/etc/nginx/stream.conf:ro" \
|
|
-v "$PWD/edge/conf.d:/etc/nginx/conf.d:ro" \
|
|
-v /etc/letsencrypt:/etc/letsencrypt:ro \
|
|
-v /opt/jiu:/opt/jiu:ro \
|
|
-v /var/www/pay:/var/www/pay:ro \
|
|
"$EDGE_IMAGE" nginx -t
|
|
|
|
rollback() {
|
|
echo "==> !! 自动回滚:停 edge,恢复宿主 nginx" >&2
|
|
docker-compose -p pangolin stop edge >/dev/null 2>&1 || true
|
|
systemctl enable nginx >/dev/null 2>&1 || true
|
|
systemctl start nginx || echo " !! 宿主 nginx 启动失败,请手动 systemctl start nginx" >&2
|
|
echo " 已回滚到宿主 nginx。" >&2
|
|
exit 1
|
|
}
|
|
|
|
echo "==> [2/4] 停用宿主 nginx 并起 edge 容器(交接窗口,秒级)"
|
|
systemctl stop nginx
|
|
systemctl disable nginx 2>/dev/null || true
|
|
docker build -t pangolin-edge:local ./edge || { echo " edge 镜像构建失败" >&2; rollback; }
|
|
if ! docker-compose -p pangolin up -d edge singbox; then
|
|
echo " edge 启动失败" >&2; rollback
|
|
fi
|
|
|
|
echo "==> [3/4] 等待并健康检查"
|
|
sleep 2
|
|
# edge 容器必须在跑
|
|
if [[ "$(docker inspect -f '{{.State.Running}}' pangolin-edge 2>/dev/null)" != "true" ]]; then
|
|
echo " edge 容器未运行" >&2; docker logs pangolin-edge 2>&1 | tail -10; rollback
|
|
fi
|
|
fail=0
|
|
# REALITY 经 443 → 10443(Marzban),SNI=www.cloudflare.com 应握手成功
|
|
if echo | timeout 10 openssl s_client -connect 127.0.0.1:443 -servername www.cloudflare.com >/dev/null 2>&1; then
|
|
echo " [REALITY] 443 握手 OK"; else echo " [REALITY] 握手失败"; fail=1; fi
|
|
# 业务 vhost(经 stream→本机 8443/8444/8445)
|
|
for d in blog jiu vpn; do
|
|
code="$(curl -ks -o /dev/null -w '%{http_code}' --resolve ${d}.51yanmei.com:443:127.0.0.1 https://${d}.51yanmei.com/ 2>/dev/null || echo 000)"
|
|
echo " [${d}] https -> ${code}"
|
|
[[ "$code" =~ ^[2-4][0-9][0-9]$ ]] || fail=1
|
|
done
|
|
|
|
echo "==> [4/4] 结果"
|
|
if [[ "$fail" == "0" ]]; then
|
|
echo " 切换成功 ✅(宿主 nginx 已停,配置保留可回滚)"
|
|
else
|
|
echo " 部分检查未通过" >&2; rollback
|
|
fi
|