我创建了一个 systemd 服务,用于在更新某些 docker 容器的 SSL 证书时重新启动它们。我创建了这个单元文件,这样当服务检测到证书已更改时,就会执行我的脚本来重新启动容器:
[Service]
Type=oneshot
ExecStart=/opt/mailcow-cert-restart/mailcow-cert-restart.sh
Description=Restarts affected mailcow containers when their certificates are renewed by nginx-proxy-manager
[Path]
PathChanged=/opt/compose-stacks/mailcow-dockerized/data/assets/ssl/cert.pem
[Install]
WantedBy=multi-user.target
问题是,当使用以下命令重新启动服务时systemctl restart myservice
它会重新启动docker容器,即使证书从那时起没有改变过。有什么方法可以确保脚本将仅有的证书文件更改时会运行吗?我不希望这些容器不必要地重新启动。
答案1
[Path]
当然,这种方式行不通。首先,它只在.path
单位中起作用——你不能把它放在其他单位类型中。其次,它的机制与你想要的完全相反——它不会阻止任何事情发生,也不会保持持久状态;PathChanged= 的目的是触发事件这会导致服务启动。
您最好在服务的脚本/程序中完成操作 - 每当更新完成时存储一个时间戳(例如“触摸”标记文件);将存储的时间戳与的时间戳进行比较cert.pem
。
例如,只需几行 bash:
if [[ cert.pem -nt /opt/.mailcow.lastupd ]]; then
<restart stuff> &&
touch /opt/.mailcow.lastupd
fi
这也可以作为一个完成ConditionExec
(我本来想写的/bin/sh -c "[ ... ]"
,但[
akatest
确实作为一个独立程序存在):
[Unit]
ConditionExec=/bin/[ /opt/foo/cert.pem -nt /etc/dovecot/cert.pem ]