Since you cannot prod Mailcow docker containers to restart from the certbot context within the SWAG docker container, we can just use some bash and systemd on the host.
Note that your host will need inotify-tools
installed, e.g. apt install inotify-tools
/opt/mailcow-letsencrypt-watcher.sh
#!/bin/bash
# Source symlinks
DOMAIN="myfqdn.com"
SWAG_DIR="/opt/swag/config"
CERT_DIR="${SWAG_DIR}/etc/letsencrypt/live/${DOMAIN}"
PRIVKEY_SYMLINK="${CERT_DIR}/privkey.pem"
FULLCHAIN_SYMLINK="${CERT_DIR}/fullchain.pem"
# Destination paths
KEY_DEST="/opt/mailcow-dockerized/data/assets/ssl/key.pem"
CERT_DEST="/opt/mailcow-dockerized/data/assets/ssl/cert.pem"
# Function to monitor symlink changes and handle events
monitor_symlinks() {
while true; do
# Note that Letsencrypt will remove the $SWAG_DIR/config/etc/letsencrypt/live/$DOMAIN path temporarily
# during renewal, so inotifywait can fail to start during this time.
# inotify will output in the form of full path, event type, and filename whitespace separated.
inotifywait -e modify,move,create,delete "$(dirname "$FULLCHAIN_SYMLINK")" |
while read path event file; do
echo "Event detected: $event on $file"
sleep 120 # Wait for letsencrypt to finish
cp "$PRIVKEY_SYMLINK" "$KEY_DEST"
cp "$FULLCHAIN_SYMLINK" "$CERT_DEST"
echo "Restarting Mailcow docker containers."
# See: https://docs.mailcow.email/post_installation/reverse-proxy/r_p/#optional-post-hook-script-for-non-mailcow-acme-clients
postfix_c=$(docker ps -qaf name=postfix-mailcow)
dovecot_c=$(docker ps -qaf name=dovecot-mailcow)
nginx_c=$(docker ps -qaf name=nginx-mailcow)
docker restart ${postfix_c} ${dovecot_c} ${nginx_c}
done
# Add a short delay to prevent high CPU usage if inotifywait fails to start.
sleep 1
done
}
# Initial copy of symlink targets when service starts
cp "$PRIVKEY_SYMLINK" "$KEY_DEST"
cp "$FULLCHAIN_SYMLINK" "$CERT_DEST"
# Start monitoring
monitor_symlinks
/etc/systemd/system/mailcow-letsencrypt-watcher.service
[Unit]
Description="Mailcow Let's Encrypt Watcher"
After=network.target
[Service]
Type=simple
User=root
ExecStart=/opt/mailcow-letsencrypt-watcher.sh
Restart=always
[Install]
WantedBy=multi-user.target
Then enable and start it:
sudo systemctl daemon-reload # Reload systemd to read the new unit file
sudo systemctl enable mailcow-letsencrypt-watcher.service # Enable the service to start on boot
sudo systemctl start mailcow-letsencrypt-watcher.service # Start the service
sudo systemctl status mailcow-letsencrypt-watcher.service # Check service status