6

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
  • Have you ever figured out a systemd solution to your problem? I have a very similar problem that I'd like to solve: unix.stackexchange.com/q/717642/399674
    – Fonic
    Sep 17, 2022 at 19:49
  • Hi @Fonic, in the end I made do with the kludge, but I am glad to see you got a potential solution to your question. Sep 20, 2022 at 13:48

1 Answer 1

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.

4
  • 2
    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. Apr 17, 2019 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. Apr 18, 2019 at 2:34
  • 3
    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! Apr 18, 2019 at 11:19
  • 2

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .