9

Situation

I have written a custom systemd service unit and its companion shell script to renew a certificate from Let's Encrypt. Everything works fine when I run systemctl start letsencrypt-example_com.service. I want it to be run automatically every 60 days, so I wrote a systemd timer unit.

Issue

I ran systemctl enable letsencrypt-example_com.timer then systemctl start letsencrypt-example_com.timer. The timer seems to start but not the service.

# systemctl status letsencrypt-example_com.timer
Created symlink from /etc/systemd/system/timers.target.wants/letsencrypt-example_com.timer to /etc/systemd/system/letsencrypt-example_com.timer.
# systemctl start letsencrypt-example_com.timer
# systemctl list-timers --all
# systemctl list-timers
NEXT                           LEFT     LAST                           PASSED       UNIT                            ACTIVATES
n/a                            n/a      ven. 2016-05-06 13:10:13 CEST  1h 51min ago letsencrypt-example_com.timer letsencrypt-example_com.service
# systemctl status letsencrypt-example_com.timer
● letsencrypt-example_com.timer - Run letsencrypt-example_com every 60 days
   Loaded: loaded (/etc/systemd/system/letsencrypt-example_com.timer; enabled)
   Active: active (elapsed) since ven. 2016-05-06 15:01:57 CEST; 2min 50s ago
# systemctl status letsencrypt-example_com.service
● letsencrypt-example_com.service - letsencrypt certificat renewal for example.com and subdomains
   Loaded: loaded (/etc/systemd/system/letsencrypt-example_com.service; static)
   Active: inactive (dead)

Files

cat /etc/systemd/system/letsencrypt-example_com.service :

[Unit]
Description=letsencrypt certificat renewal for example.com and subdomains
Requires=nginx_reload.service
Before=nginx_reload.service

[Service]
Type=simple
ExecStart=/bin/sh /usr/local/bin/letsencrypt-renew.sh example.com www.example.com
User=letsencrypt
Group=www-data

/usr/local/bin/letsencrypt-renew.sh :

#!/bin/sh

letsencrypt certonly \
--server https://acme-v01.api.letsencrypt.org/directory \
--text \
--email admin@example.com \
--agree-tos \
--rsa-key-size 4096 \
--authenticator webroot \
--webroot-path /srv/files/letsencrypt/www \
$(
for fqdn in $@;
    do echo "--domain $fqdn";
    done;
) \
--force-renew

/etc/systemd/system/letsencrypt-example_com.timer :

[Unit]
Description=Run letsencrypt-example_com every 60 days

[Timer]
OnUnitActiveSec=1min
Persistent=true
Unit=letsencrypt-example_com.service

[Install]
WantedBy=timers.target

/etc/systemd/system/nginx_reload.service :

[Unit]
Description=reload nginx conf

[Service]
Type=oneshot
ExecStart=/bin/systemctl reload nginx
  • If I did it today, I may not have created a nginx_reload.service, and add this to letsencrypt-example_com.service instead : PermissionsStartOnly=true ExecStartPost=/bin/systemctl reload nginx – pandark Feb 21 '18 at 18:32
  • Perhaps related: github.com/systemd/systemd/issues/6680 – nh2 Nov 3 '18 at 15:39
9

Although timer units automatically gain a Before= dependency on the service they are supposed to activate, they apparently don't automatically have a Requires= dependency on it (which doesn't make any sense to me).

So I added the following line to the [Unit] section of the timer unit, and now it starts the service as intended :

Requires=letsencrypt-example_com.service

I also set an AccuracySec (of 10s) in the [Timer] section.

  • I had a working timer some time ago, then the same timer stopped with your same error; I solved using this solution; I think something changed in a systemd upgrade... – Zac Mar 21 '18 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.