此次的需求主要源于之前用 docker 部署 acme 自动更新 SSL 证书时,发现脚本中的重启 Nginx 这一步在容器中无法执行 , 因此这里改为监听宿主证书目录证书文件改变,宿主直接重启 Nginx.

这里是通过 inotify 来实现的 , 首先安装

安装 inotify

在 Ubuntu 或 Debian 系统上,可以使用以下命令安装:

1
2
sudo apt-get update
sudo apt-get install inotify-tools

在 CentOS 或 RHEL 系统上:

1
sudo yum install inotify-tools

编写脚本

然后编写脚本 cert_listener.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/bin/bash

# 设置需要监控的证书路径
CERT_PATH="/data/apps/letsencrypt/fullchain.pem"
# 设置日志文件路径
LOG_FILE="/data/apps/certnotify/cert_listener.log"

# 创建日志文件(如果不存在)
touch "$LOG_FILE"

# 使用 inotifywait 监控文件变化
inotifywait -m "$CERT_PATH" -e modify |
while read path action file; do
# 获取当前时间戳
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
# 输出日志到控制台和文件
echo "$TIMESTAMP 证书文件已更新,触发 Nginx 重载..." | tee -a "$LOG_FILE"

# 执行 Nginx 重载命令,并记录输出到日志文件
if docker exec nginx nginx -s reload; then
echo "$TIMESTAMP Nginx 重载成功" | tee -a "$LOG_FILE"
else
echo "$TIMESTAMP Nginx 重载失败" | tee -a "$LOG_FILE"
fi
done

这里根据自己需求进行修改 , 路径和文件都变量化了

后台启动

再修改权限 chmod +x cert_listener.sh

如果直接执行 , 则是前台监控文件变化 , 退出后就停止监控了 , 所以这里要通过后台启动

1
nohup ./cert_listener.sh > /data/apps/certnotify/listener_invoke.log 2>&1 &

设置自动运行(可选)

上面的设置如果服务器重启后就失效了 , 这里可以配置一个自启动服务

通过 systemd 设置服务

创建一个新的 systemd 服务单元文件:

1
sudo nano /etc/systemd/system/reload-nginx.service
1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Monitor certificate and reload Nginx

[Service]
ExecStart=/path/to/reload-nginx.sh
Restart=always
User=root
Group=root

[Install]
WantedBy=multi-user.target

保存并退出后,执行以下命令启用并启动服务:

1
2
sudo systemctl enable reload-nginx.service
sudo systemctl start reload-nginx.service