When manually executing systemctl start letsencrypt-example_com.service
, everything works perfectly. However, the same service fails to trigger when activated via its companion timer unit, despite the timer showing as active in systemctl list-timers
.
Your current timer configuration has several potential issues:
[Timer]
OnUnitActiveSec=1min # This triggers 1min after service activation
Persistent=true # Good for catching missed runs
Unit=letsencrypt-example_com.service
The key problem is using OnUnitActiveSec
instead of OnCalendar
for periodic execution. Here's how we should modify it:
[Timer]
OnCalendar=*-*-1,15 02:00:00 # Runs at 2AM on 1st and 15th of each month
RandomizedDelaySec=1h # Spreads load across the hour
Persistent=true
Unit=letsencrypt-example_com.service
The service unit has dependencies that might affect timer execution:
[Unit]
Requires=nginx_reload.service
Before=nginx_reload.service
Add explicit ordering to prevent race conditions:
[Unit]
Wants=nginx_reload.service
After=nginx_reload.service
Use these commands to investigate timer behavior:
# Show timer activation details
journalctl -u letsencrypt-example_com.timer -n 50
# Check service execution attempts
journalctl -u letsencrypt-example_com.service --since "1 hour ago"
# Verify timer definition
systemd-analyze verify /etc/systemd/system/letsencrypt-example_com.timer
Here's a proven timer configuration for Let's Encrypt renewal:
[Unit]
Description=Let's Encrypt renewal timer for example.com
[Timer]
OnCalendar=*-*-01,15 03:00:00
AccuracySec=1h
Persistent=true
Unit=letsencrypt-example_com.service
[Install]
WantedBy=timers.target
Since the service runs as user 'letsencrypt', ensure:
# Set proper permissions for webroot
chown -R letsencrypt:www-data /srv/files/letsencrypt/www
chmod -R 750 /srv/files/letsencrypt/www
# Validate script execution
sudo -u letsencrypt /bin/sh /usr/local/bin/letsencrypt-renew.sh example.com
# Reload systemd after changes
systemctl daemon-reload
# Manually test the timer
systemctl start letsencrypt-example_com.timer
systemctl status letsencrypt-example_com.timer
journalctl -xe
When examining the timer unit status, we notice it shows as active but the service remains inactive:
# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
n/a n/a Fri 2016-05-06 13:10:13 CEST 1h 51min ago letsencrypt-example_com.timer letsencrypt-example_com.service
The current timer setup has several potential issues:
[Timer]
OnUnitActiveSec=1min
Persistent=true
Unit=letsencrypt-example_com.service
The primary problem stems from using OnUnitActiveSec
which triggers relative to the service's last activation. For a certificate renewal scenario, we should use absolute timing with OnCalendar
or fixed intervals with OnUnitInactiveSec
.
Here's a more appropriate timer configuration for certificate renewal:
[Unit]
Description=Run letsencrypt-example_com every 60 days
[Timer]
OnCalendar=*-*-1,15 03:00:00
RandomizedDelaySec=3600
Persistent=true
Unit=letsencrypt-example_com.service
[Install]
WantedBy=timers.target
The service unit could benefit from additional robustness measures:
[Service]
Type=oneshot
ExecStart=/bin/sh /usr/local/bin/letsencrypt-renew.sh example.com www.example.com
User=letsencrypt
Group=www-data
Restart=no
SuccessExitStatus=0 1
MemoryLimit=512M
CPUQuota=50%
To diagnose timer issues, use these commands:
# Check timer activation
journalctl -u letsencrypt-example_com.timer
# Verify service attempts
journalctl -u letsencrypt-example_com.service
# Test timer without waiting
systemd-analyze calendar "*-*-1,15 03:00:00"
# Check next elapse time
systemctl list-timers --all
Here's a verified configuration that works for certificate renewal:
# /etc/systemd/system/letsencrypt-renewal.timer
[Unit]
Description=Weekly LetsEncrypt renewal check
[Timer]
OnCalendar=Mon *-*-* 02:00:00
RandomizedDelaySec=1h
Persistent=true
[Install]
WantedBy=timers.target
# /etc/systemd/system/letsencrypt-renewal.service
[Unit]
Description=LetsEncrypt Certificate Renewal
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew --quiet --agree-tos
ExecStartPost=/bin/systemctl reload nginx
User=root
Group=root
Ensure proper permissions for the letsencrypt user:
# Set directory permissions
chown -R letsencrypt:www-data /etc/letsencrypt
chmod -R 750 /etc/letsencrypt
# Verify webroot access
chown letsencrypt:www-data /srv/files/letsencrypt/www
chmod 755 /srv/files/letsencrypt/www