mirror of
https://github.com/chatmail/relay.git
synced 2026-05-21 05:18:04 +00:00
docker: extract cert monitor from background process to systemd timer
The cert monitoring was an orphaned background process (`monitor_certificates &`) Replace with a proper systemd timer/service (every 60s). Also made journald ForwardToConsole=yes idempotent.
This commit is contained in:
@@ -29,10 +29,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
MAIL_DOMAIN: $MAIL_DOMAIN
|
MAIL_DOMAIN: $MAIL_DOMAIN
|
||||||
CMDEPLOY_STAGES: ${CMDEPLOY_STAGES:-}
|
CMDEPLOY_STAGES: ${CMDEPLOY_STAGES:-}
|
||||||
# Certificate monitoring (only needed with USE_FOREIGN_CERT_MANAGER)
|
|
||||||
USE_FOREIGN_CERT_MANAGER: ${USE_FOREIGN_CERT_MANAGER:-}
|
USE_FOREIGN_CERT_MANAGER: ${USE_FOREIGN_CERT_MANAGER:-}
|
||||||
ENABLE_CERTS_MONITORING: ${ENABLE_CERTS_MONITORING:-}
|
|
||||||
CERTS_MONITORING_TIMEOUT: ${CERTS_MONITORING_TIMEOUT:-}
|
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
volumes:
|
volumes:
|
||||||
## system
|
## system
|
||||||
|
|||||||
@@ -77,6 +77,12 @@ RUN rm -f /etc/nginx/sites-enabled/default
|
|||||||
COPY --chmod=555 ./docker/files/setup_chatmail_docker.sh /setup_chatmail_docker.sh
|
COPY --chmod=555 ./docker/files/setup_chatmail_docker.sh /setup_chatmail_docker.sh
|
||||||
COPY --chmod=555 ./docker/files/entrypoint.sh /entrypoint.sh
|
COPY --chmod=555 ./docker/files/entrypoint.sh /entrypoint.sh
|
||||||
|
|
||||||
|
# Certificate monitoring as a proper systemd timer (not a background process)
|
||||||
|
COPY --chmod=555 ./docker/files/chatmail-certmon.sh /chatmail-certmon.sh
|
||||||
|
COPY ./docker/files/chatmail-certmon.service /lib/systemd/system/chatmail-certmon.service
|
||||||
|
COPY ./docker/files/chatmail-certmon.timer /lib/systemd/system/chatmail-certmon.timer
|
||||||
|
RUN ln -sf /lib/systemd/system/chatmail-certmon.timer /etc/systemd/system/timers.target.wants/chatmail-certmon.timer
|
||||||
|
|
||||||
HEALTHCHECK --interval=60s --timeout=10s --retries=3 \
|
HEALTHCHECK --interval=60s --timeout=10s --retries=3 \
|
||||||
CMD systemctl is-active dovecot postfix nginx unbound opendkim filtermail doveauth chatmail-metadata || exit 1
|
CMD systemctl is-active dovecot postfix nginx unbound opendkim filtermail doveauth chatmail-metadata || exit 1
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,5 @@ MAIL_DOMAIN="chat.example.com"
|
|||||||
# CMDEPLOY_STAGES - default: "configure,activate". Set to "install,configure,activate" to force full reinstall.
|
# CMDEPLOY_STAGES - default: "configure,activate". Set to "install,configure,activate" to force full reinstall.
|
||||||
# CMDEPLOY_STAGES="configure,activate"
|
# CMDEPLOY_STAGES="configure,activate"
|
||||||
|
|
||||||
# Certificate monitoring (only needed with USE_FOREIGN_CERT_MANAGER)
|
# Skip acmetool when using an external certificate manager (e.g. Traefik, Caddy).
|
||||||
# USE_FOREIGN_CERT_MANAGER="True"
|
# USE_FOREIGN_CERT_MANAGER="True"
|
||||||
# ENABLE_CERTS_MONITORING="true"
|
|
||||||
# CERTS_MONITORING_TIMEOUT=60
|
|
||||||
|
|||||||
8
docker/files/chatmail-certmon.service
Normal file
8
docker/files/chatmail-certmon.service
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Check TLS certificate changes and reload services
|
||||||
|
After=setup_chatmail.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/bin/bash /chatmail-certmon.sh
|
||||||
|
PassEnvironment=MAIL_DOMAIN PATH_TO_SSL
|
||||||
28
docker/files/chatmail-certmon.sh
Normal file
28
docker/files/chatmail-certmon.sh
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Check if TLS certificates have changed and reload services if so.
|
||||||
|
# Called by chatmail-certmon.timer (systemd timer, default every 60s).
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
PATH_TO_SSL="${PATH_TO_SSL:-/var/lib/acme/live/${MAIL_DOMAIN}}"
|
||||||
|
HASH_FILE="/run/chatmail-certmon.hash"
|
||||||
|
|
||||||
|
if [ ! -d "$PATH_TO_SSL" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
current_hash=$(find "$PATH_TO_SSL" -type f -exec sha1sum {} \; | sort | sha1sum | awk '{print $1}')
|
||||||
|
previous_hash=""
|
||||||
|
if [ -f "$HASH_FILE" ]; then
|
||||||
|
previous_hash=$(cat "$HASH_FILE")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$current_hash" ] && [ "$current_hash" != "$previous_hash" ]; then
|
||||||
|
echo "[INFO] Certificate hash changed, reloading nginx, dovecot and postfix."
|
||||||
|
echo "$current_hash" > "$HASH_FILE"
|
||||||
|
# On first run (no previous hash), don't reload — services may not be up yet
|
||||||
|
if [ -n "$previous_hash" ]; then
|
||||||
|
systemctl reload nginx.service
|
||||||
|
systemctl reload dovecot.service
|
||||||
|
systemctl reload postfix.service
|
||||||
|
fi
|
||||||
|
fi
|
||||||
9
docker/files/chatmail-certmon.timer
Normal file
9
docker/files/chatmail-certmon.timer
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Periodically check TLS certificate changes
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnBootSec=120
|
||||||
|
OnUnitActiveSec=60
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
@@ -6,7 +6,7 @@ SETUP_CHATMAIL_SERVICE_PATH="${SETUP_CHATMAIL_SERVICE_PATH:-/lib/systemd/system/
|
|||||||
# Whitelist only the env vars needed by setup_chatmail_docker.sh.
|
# Whitelist only the env vars needed by setup_chatmail_docker.sh.
|
||||||
# Forwarding all env vars (via printenv) would leak Docker internals,
|
# Forwarding all env vars (via printenv) would leak Docker internals,
|
||||||
# orchestrator secrets, and other unrelated variables into systemd.
|
# orchestrator secrets, and other unrelated variables into systemd.
|
||||||
env_vars="MAIL_DOMAIN CMDEPLOY_STAGES CHATMAIL_INI CHATMAIL_NOSYSCTL CHATMAIL_NOPORTCHECK ENABLE_CERTS_MONITORING CERTS_MONITORING_TIMEOUT PATH_TO_SSL PATH USE_FOREIGN_CERT_MANAGER"
|
env_vars="MAIL_DOMAIN CMDEPLOY_STAGES CHATMAIL_INI CHATMAIL_NOSYSCTL CHATMAIL_NOPORTCHECK PATH_TO_SSL PATH USE_FOREIGN_CERT_MANAGER"
|
||||||
sed -i "s|<envs_list>|$env_vars|g" "$SETUP_CHATMAIL_SERVICE_PATH"
|
sed -i "s|<envs_list>|$env_vars|g" "$SETUP_CHATMAIL_SERVICE_PATH"
|
||||||
|
|
||||||
exec /lib/systemd/systemd "$@"
|
exec /lib/systemd/systemd "$@"
|
||||||
|
|||||||
@@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
export CHATMAIL_INI="${CHATMAIL_INI:-/etc/chatmail/chatmail.ini}"
|
export CHATMAIL_INI="${CHATMAIL_INI:-/etc/chatmail/chatmail.ini}"
|
||||||
export ENABLE_CERTS_MONITORING="${ENABLE_CERTS_MONITORING:-true}"
|
|
||||||
export CERTS_MONITORING_TIMEOUT="${CERTS_MONITORING_TIMEOUT:-60}"
|
|
||||||
export PATH_TO_SSL="${PATH_TO_SSL:-/var/lib/acme/live/${MAIL_DOMAIN}}"
|
|
||||||
|
|
||||||
CMDEPLOY=/opt/cmdeploy/bin/cmdeploy
|
CMDEPLOY=/opt/cmdeploy/bin/cmdeploy
|
||||||
|
|
||||||
@@ -13,42 +10,6 @@ if [ -z "$MAIL_DOMAIN" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
calculate_hash() {
|
|
||||||
if [ ! -d "$PATH_TO_SSL" ]; then
|
|
||||||
echo ""
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
find "$PATH_TO_SSL" -type f -exec sha1sum {} \; | sort | sha1sum | awk '{print $1}'
|
|
||||||
}
|
|
||||||
|
|
||||||
monitor_certificates() {
|
|
||||||
if [ "$ENABLE_CERTS_MONITORING" != "true" ]; then
|
|
||||||
echo "Certs monitoring disabled."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait for certificate directory to exist before monitoring
|
|
||||||
echo "[INFO] Waiting for certificate directory: $PATH_TO_SSL"
|
|
||||||
while [ ! -d "$PATH_TO_SSL" ]; do
|
|
||||||
sleep "$CERTS_MONITORING_TIMEOUT"
|
|
||||||
done
|
|
||||||
echo "[INFO] Certificate directory found, starting monitoring."
|
|
||||||
|
|
||||||
previous_hash=$(calculate_hash)
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
sleep "$CERTS_MONITORING_TIMEOUT"
|
|
||||||
current_hash=$(calculate_hash)
|
|
||||||
if [ -n "$current_hash" ] && [ "$current_hash" != "$previous_hash" ]; then
|
|
||||||
echo "[INFO] Certificate's folder hash was changed, reloading nginx, dovecot and postfix services."
|
|
||||||
systemctl reload nginx.service
|
|
||||||
systemctl reload dovecot.service
|
|
||||||
systemctl reload postfix.service
|
|
||||||
previous_hash=$current_hash
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
### MAIN
|
### MAIN
|
||||||
|
|
||||||
if [ ! -f /etc/dkimkeys/opendkim.private ]; then
|
if [ ! -f /etc/dkimkeys/opendkim.private ]; then
|
||||||
@@ -66,7 +27,7 @@ fi
|
|||||||
export CMDEPLOY_STAGES="${CMDEPLOY_STAGES:-configure,activate}"
|
export CMDEPLOY_STAGES="${CMDEPLOY_STAGES:-configure,activate}"
|
||||||
$CMDEPLOY run --config "$CHATMAIL_INI" --ssh-host @local
|
$CMDEPLOY run --config "$CHATMAIL_INI" --ssh-host @local
|
||||||
|
|
||||||
echo "ForwardToConsole=yes" >> /etc/systemd/journald.conf
|
# Journald: forward to console for docker logs (idempotent)
|
||||||
|
grep -q '^ForwardToConsole=yes' /etc/systemd/journald.conf \
|
||||||
|
|| echo "ForwardToConsole=yes" >> /etc/systemd/journald.conf
|
||||||
systemctl restart systemd-journald
|
systemctl restart systemd-journald
|
||||||
|
|
||||||
monitor_certificates &
|
|
||||||
|
|||||||
Reference in New Issue
Block a user