1

I have two units, nginx.service and certbot.service, provided by their respective Debian packages:

nginx.service:

[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

[Install]
WantedBy=multi-user.target

certbot.service:

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew
PrivateTmp=true

And a timer, certbot.timer (also provided by the certbot deb package):

[Unit]
Description=Run certbot twice daily

[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true

[Install]
WantedBy=timers.target

These all work fine.

The problem, is that I need to reload nginx when the timer fires for nginx to see the new certificates (systemctl reload nginx).

I know I can do systemctl edit certbot.service, and add:

[Service]
ExecStartPost=/bin/systemctl reload nginx

In fact, this is what I've done, but it's a kludge. Is there any way to achieve this with native systemd dependencies? The tricky thing is triggering reload only and not a full blown restart.

2

You can just add a deploy hook (not a post hook; you only need to do this if a cert is deployed) directly to the certbot configuration for your domain, in /etc/letsencrypt/renewal/example.com.conf.

In the [renewal] section, add a line like:

deploy_hook = systemctl reload nginx

That is all. You don't need to do strange things to the systemd units.

  • Thanks for this, it is a good answer to my original problem, but not the actual question! So I'll upvote for usefulness, but I can't mark it as the accepted answer. I think the service manager is the right place to do this sort of thing. – Alex Forbes Apr 17 at 19:40
  • @AlexForbes Systemd is absolutely the wrong place to do this sort of thing. You may need different deploy hooks for each DNS name, for instance, (e.g. getting certs for both nginx and postfix, each with different names) and that gets completely unmaintainable if you try to cram it into a systemd unit or override. – Michael Hampton Apr 18 at 2:34
  • We're getting into a philosophical debate here, but by "sort of thing", I mean coupling services together. Systemd is absolutely the right place to declare service dependencies. It's one of the main reasons it exists. I think it's actually an interesting debate but this comment field is too limited so I'm going to break down my thoughts on when to use generalist vs domain-specific solutions into a blog post when I have more time. I'll link it here, would be interested in your thoughts! – Alex Forbes Apr 18 at 11:19

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.