mirror of
https://github.com/fscarmen/sing-box.git
synced 2026-08-10 17:55:16 +08:00
fix: sync nginx with daemon file on hot-reload flows
- add idempotent nginx_sync to start, reload, or stop nginx based on the final config state
- start nginx automatically when adding WS + Argo protocols, removing the need for a manual systemctl restart
- regenerate the daemon file after the final nginx state is decided in change_protocols, keeping systemd ExecStartPre / OpenRC start_pre consistent and clearing stale OpenRC entries on Alpine after WS removal
- converge subscription toggle ON/OFF to daemon regeneration plus nginx_sync, replacing inline sed patches
- unify nginx management on CentOS7 with a tolerant ExecStartPre ("-" prefix) so nginx starts on reload and after reboot
- reload nginx after nginx.conf rewrites (port changes, Argo type changes, additional WS protocols)
- stop nginx during uninstall to cover processes started outside the service cgroup
fix: 热更流程下 nginx 与守护文件状态同步
- 新增幂等 nginx_sync,按最终配置状态自动启动 / 热重载 / 停止 nginx
- 添加 WS + Argo 协议时自动拉起 nginx,无需再手动 systemctl restart
- change_protocols 先确定最终 nginx 状态再生成守护文件,保证 systemd ExecStartPre / OpenRC start_pre 一致,并清除 Alpine 删除 WS 后残留的 start_pre
- 订阅开关 ON/OFF 收敛为守护文件重生成 + nginx_sync,移除内联 sed 补丁
- CentOS7 统一走带 "-" 容错的 ExecStartPre,reload 与重启后 nginx 均能拉起
- nginx.conf 被重写(改端口 / 换 Argo 隧道 / 追加 WS 协议)后自动 reload nginx
- 卸载时显式停止 nginx,覆盖服务 cgroup 外启动的进程
This commit is contained in:
+43
-41
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# 当前脚本版本号
|
||||
VERSION='v1.3.19 (2026.08.02)'
|
||||
VERSION='v1.3.19 (2026.08.04)'
|
||||
|
||||
# Github 反代加速代理
|
||||
GITHUB_PROXY=('https://hub.glowp.xyz/' 'https://proxy.vvvv.ee/')
|
||||
@@ -764,6 +764,7 @@ change_config() {
|
||||
done
|
||||
fetch_nodes_value
|
||||
[ -n "$PORT_NGINX" ] && export_nginx_conf_file
|
||||
nginx_sync
|
||||
cmd_systemctl reload sing-box
|
||||
[ -n "$ARGO_DOMAIN" ] && export_argo_json_file
|
||||
sync_firewall_rules
|
||||
@@ -936,14 +937,14 @@ change_config() {
|
||||
# 判断是否还需要 nginx:有 WS 协议且 Argo 反代
|
||||
if { [ -n "$PORT_VMESS_WS" ] || [ -n "$PORT_VLESS_WS" ]; } && [ "$IS_ARGO" = 'is_argo' ]; then
|
||||
export_nginx_conf_file
|
||||
nginx -s reload -c ${WORK_DIR}/nginx.conf 2>/dev/null || nginx_run
|
||||
else
|
||||
nginx_stop
|
||||
[ "$SYSTEM" != 'Alpine' ] && [ "$IS_CENTOS" != 'CentOS7' ] && \
|
||||
sed -i '/ExecStartPre=.*nginx/d' ${SINGBOX_DAEMON_FILE} && systemctl daemon-reload
|
||||
rm -f ${WORK_DIR}/nginx.conf
|
||||
unset PORT_NGINX
|
||||
fi
|
||||
# 重新生成守护文件并同步 nginx(systemd ExecStartPre / OpenRC start_pre 与最终状态一致)
|
||||
sing-box_systemd
|
||||
nginx_sync
|
||||
/bin/rm -f ${WORK_DIR}/subscribe/qr
|
||||
export_list
|
||||
info " $(text 112) "
|
||||
@@ -964,18 +965,9 @@ change_config() {
|
||||
fetch_nodes_value
|
||||
[ -z "$PORT_NGINX" ] && input_nginx_port
|
||||
export_nginx_conf_file
|
||||
# 更新服务文件 ExecStartPre(非 CentOS7)
|
||||
if [ "$SYSTEM" != 'Alpine' ] && [ "$IS_CENTOS" != 'CentOS7' ] && \
|
||||
! grep -q 'ExecStartPre=.*nginx' ${SINGBOX_DAEMON_FILE} 2>/dev/null; then
|
||||
sed -i '/^ExecStart=/i ExecStartPre='$(command -v nginx)' -c '${WORK_DIR}'/nginx.conf' ${SINGBOX_DAEMON_FILE}
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
# 启动或 reload nginx
|
||||
if ps -eo pid,args | grep -qE "[n]ginx.*${WORK_DIR}/nginx.conf" 2>/dev/null; then
|
||||
nginx -s reload -c ${WORK_DIR}/nginx.conf 2>/dev/null || true
|
||||
else
|
||||
nginx_run
|
||||
fi
|
||||
# 重新生成守护文件并同步 nginx(含 Alpine / CentOS7,重启后 nginx 随服务拉起)
|
||||
sing-box_systemd
|
||||
nginx_sync
|
||||
export_list
|
||||
info " $(text 112) "
|
||||
fi
|
||||
@@ -1909,6 +1901,7 @@ change_argo() {
|
||||
# 更新节点信息和配置
|
||||
fetch_nodes_value
|
||||
export_nginx_conf_file
|
||||
nginx_sync
|
||||
export_list
|
||||
}
|
||||
|
||||
@@ -2132,6 +2125,19 @@ nginx_stop() {
|
||||
ss -nltp | sed -n "/pid=$NGINX_PID,/ s/,/ /gp" | grep -oP 'pid=\K\S+' | sort -u | xargs kill -9 >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# 让 nginx 进程与最终配置状态保持一致:需要则启动/热重载,不需要则停止
|
||||
nginx_sync() {
|
||||
if [ -s ${WORK_DIR}/nginx.conf ]; then
|
||||
if ps -eo pid,args | grep -qE "[n]ginx.*${WORK_DIR}/nginx.conf" 2>/dev/null; then
|
||||
nginx -s reload -c ${WORK_DIR}/nginx.conf 2>/dev/null || true
|
||||
else
|
||||
nginx_run
|
||||
fi
|
||||
else
|
||||
nginx_stop
|
||||
fi
|
||||
}
|
||||
|
||||
# 为了适配 alpine,定义 cmd_systemctl 的函数
|
||||
cmd_systemctl() {
|
||||
|
||||
@@ -2150,6 +2156,7 @@ cmd_systemctl() {
|
||||
;;
|
||||
reload )
|
||||
rc-service "$2" reload >/dev/null 2>&1 || rc-service "$2" restart >/dev/null 2>&1
|
||||
[ -s ${WORK_DIR}/nginx.conf ] && nginx_sync
|
||||
local MAINPID=$(cat /var/run/sing-box.pid 2>/dev/null)
|
||||
[ -n "$MAINPID" ] && info "\n $(text 95) \n"
|
||||
;;
|
||||
@@ -2162,21 +2169,13 @@ cmd_systemctl() {
|
||||
case "$1" in
|
||||
enable | disable )
|
||||
systemctl "$1" --now "$2" >/dev/null 2>&1
|
||||
if [ "$IS_CENTOS" = 'CentOS7' ] && [ "$2" = 'sing-box' ] && [ -s $WORK_DIR/nginx.conf ]; then
|
||||
if [ "$1" = 'enable' ]; then
|
||||
nginx_run
|
||||
else
|
||||
nginx_stop
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
restart )
|
||||
[ "$IS_CENTOS" = 'CentOS7' ] && [ "$2" = 'sing-box' ] && [ -s $WORK_DIR/nginx.conf ] && nginx_stop
|
||||
systemctl restart "$2" >/dev/null 2>&1
|
||||
[ "$IS_CENTOS" = 'CentOS7' ] && [ "$2" = 'sing-box' ] && [ -s $WORK_DIR/nginx.conf ] && nginx_run
|
||||
;;
|
||||
reload )
|
||||
systemctl reload sing-box >/dev/null 2>&1 || systemctl restart sing-box >/dev/null 2>&1
|
||||
[ -s ${WORK_DIR}/nginx.conf ] && nginx_sync
|
||||
local MAINPID=$(systemctl show -p MainPID sing-box 2>/dev/null | awk -F= '{print $2}')
|
||||
[ -n "$MAINPID" ] && [ "$MAINPID" -gt 0 ] 2>/dev/null && info "\n $(text 95) \n"
|
||||
;;
|
||||
@@ -4307,9 +4306,9 @@ start_pre() {
|
||||
mkdir -p /var/run
|
||||
chmod 755 /var/run"
|
||||
|
||||
# 如果配置了 Nginx,启动 Nginx
|
||||
# 如果配置了 Nginx,启动 Nginx(nginx 已在运行时不阻塞服务启动)
|
||||
[ -n "$PORT_NGINX" ] && OPENRC_SERVICE+="
|
||||
$(command -v nginx) -c ${WORK_DIR}/nginx.conf"
|
||||
$(command -v nginx) -c ${WORK_DIR}/nginx.conf || true"
|
||||
|
||||
OPENRC_SERVICE+="
|
||||
# 确保 PID 文件不存在,避免启动失败
|
||||
@@ -4358,7 +4357,8 @@ NoNewPrivileges=yes
|
||||
TimeoutStartSec=0
|
||||
WorkingDirectory=${WORK_DIR}
|
||||
"
|
||||
[[ -n "$PORT_NGINX" && "$IS_CENTOS" != 'CentOS7' ]] && SING_BOX_SERVICE+="ExecStartPre=$(command -v nginx) -c ${WORK_DIR}/nginx.conf
|
||||
# 统一在 systemd 里用 ExecStartPre 管理 nginx(含 CentOS7);"-" 前缀容忍 nginx 已在运行等情况,避免阻塞服务启动
|
||||
[[ -n "$PORT_NGINX" ]] && SING_BOX_SERVICE+="ExecStartPre=-$(command -v nginx) -c ${WORK_DIR}/nginx.conf
|
||||
"
|
||||
SING_BOX_SERVICE+="ExecStart=${WORK_DIR}/sing-box run -C ${WORK_DIR}/conf
|
||||
ExecReload=/bin/kill -HUP \$MAINPID
|
||||
@@ -5705,15 +5705,22 @@ change_protocols() {
|
||||
unset PORT_NAIVE
|
||||
fi
|
||||
|
||||
# 生成 Nginx 配置文件
|
||||
# 生成各协议的 json 文件
|
||||
sing-box_json change
|
||||
|
||||
# 无 ws 协议且无订阅时清理 nginx:先于守护文件生成,确保 ExecStartPre / start_pre 与最终状态一致
|
||||
if ! ls ${WORK_DIR}/conf/*-ws*inbounds.json >/dev/null 2>&1 && [[ -s ${WORK_DIR}/nginx.conf && "$IS_SUB" = 'no_sub' ]]; then
|
||||
nginx_stop
|
||||
rm -f ${WORK_DIR}/nginx.conf
|
||||
unset PORT_NGINX
|
||||
fi
|
||||
|
||||
# 生成 Nginx 配置文件(按最终状态)
|
||||
[ -n "$PORT_NGINX" ] && export_nginx_conf_file
|
||||
|
||||
# 重新生成 Sing-box 守护进程文件
|
||||
sing-box_systemd
|
||||
|
||||
# 生成各协议的 json 文件
|
||||
sing-box_json change
|
||||
|
||||
# 如有需要,安装和删除 Argo 服务
|
||||
if ls ${WORK_DIR}/conf/*-ws*inbounds.json >/dev/null 2>&1; then
|
||||
if [[ "$ARGO_OR_ORIGIN_RULES" != '2' && "$ARGO_ORIGIN_RULES_STATUS" != 'is_origin' && ! -s ${ARGO_DAEMON_FILE} ]]; then
|
||||
@@ -5729,18 +5736,12 @@ change_protocols() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# 无 ws 协议且无订阅时删除 nginx 配置并停止进程;有订阅保留(订阅服务需要 nginx)
|
||||
if ! ls ${WORK_DIR}/conf/*-ws*inbounds.json >/dev/null 2>&1 && [[ -s ${WORK_DIR}/nginx.conf && "$IS_SUB" = 'no_sub' ]]; then
|
||||
nginx_stop
|
||||
[ "$SYSTEM" != 'Alpine' ] && [ "$IS_CENTOS" != 'CentOS7' ] && \
|
||||
sed -i '/ExecStartPre=.*nginx/d' ${SINGBOX_DAEMON_FILE} && systemctl daemon-reload
|
||||
rm -f ${WORK_DIR}/nginx.conf
|
||||
unset PORT_NGINX
|
||||
fi
|
||||
|
||||
# 热更 sing-box(SIGHUP 重新加载配置,PID 不变)
|
||||
cmd_systemctl reload sing-box
|
||||
|
||||
# 同步 nginx 进程:需要则启动/热重载,不需要则停止
|
||||
nginx_sync
|
||||
|
||||
# 打开防火墙相关端口
|
||||
sync_firewall_rules
|
||||
|
||||
@@ -5759,6 +5760,7 @@ uninstall() {
|
||||
if [ -d ${WORK_DIR} ]; then
|
||||
[ -s ${ARGO_DAEMON_FILE} ] && cmd_systemctl disable argo &>/dev/null
|
||||
[ -s ${SINGBOX_DAEMON_FILE} ] && cmd_systemctl disable sing-box &>/dev/null
|
||||
nginx_stop
|
||||
sleep 1
|
||||
[[ -s ${WORK_DIR}/nginx.conf && "$(ps -ef | grep -c '[n]ginx')" = 0 ]] && reading "\n $(text 83) " REMOVE_NGINX
|
||||
[ "${REMOVE_NGINX,,}" = 'y' ] && ${PACKAGE_UNINSTALL[int]} nginx >/dev/null 2>&1
|
||||
|
||||
Reference in New Issue
Block a user