The instructions for certbot on the EFF website for macOS instruct you to schedule the automatic renewal using Cron. On recent versions of macOS, Cron has been deprecated in favour of launchctl. Cron is still there, and it still works, but the proper way to do it on macOS now is to use launchd.
Setting up a Launch Agent (or in this case, a Launch Daemon) is fairly straightforward when you know how, but can be tricky if this is the first time you’re doing it.
Most of the information here is taken from a gist on Github by Joel Gilman
This assumes that you have a web server and certbot installed and that it’s all working – you can successfully run sudo certbot renew
in Terminal and don’t get any errors. These instructions will differ slightly depending on if you’ve used MacPorts or Homebrew to install certbot, so make sure to edit the plist file below as needed.
First up, create your Launch Daemon file using your favourite text editor. Name it something sensible like org.eff.certbot.renew.plist
Your plist should look something like this. If you’ve installed certbot with MacPorts then the path to the certbot binary is /opt/local/bin/certbot
– if however you’ve installed certbot with Homebrew then the path to the certbot binary is instead /usr/local/bin/certbot
so edit the plist as appropriate.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.eff.certbot.renew</string>
<key>ProgramArguments</key>
<array>
<string>/opt/local/bin/certbot</string>
<string>renew</string>
</array>
<key>StandardErrorPath</key>
<string>/Library/Logs/certbot/error.log</string>
<key>StandardOutPath</key>
<string>/Library/Logs/certbot/certbot.log</string>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>**CHANGE THIS**</integer>
<key>Minute</key>
<integer>**CHANGE THIS**</integer>
</dict>
</dict>
</plist>
Make sure that you change the two sections that say **CHANGE THIS** – Hour is for the hour of the day that you wish to run the renewal job – e.g. 2 for 2 am or 16 for 4 pm, and Minute is for the minute in the hour you want. Be kind to LetsEncrypt and make minute something other than 00
Next, make the log directory in /Library/Logs for output to be logged to.
sudo mkdir /Library/Logs/certbot
Next copy the Launch Daemon plist into the correct directory, set appropriate permissions, load it and then start it.
sudo cp org.eff.certbot.renew.plist /Library/LaunchDaemons/
sudo chmod 644 /Library/LaunchDaemons/org.eff.certbot.renew.plist
sudo chown root:wheel /Library/LaunchDaemons/org.eff.certbot.renew.plist
sudo launchctl load -w /Library/LaunchDaemons/org.eff.certbot.renew.plist
sudo launchctl start org.eff.certbot.renew
To check that it’s loaded type in sudo launchctl list | grep certbot
and it should be listed. To check for status output or errors, look in /Library/Logs/certbot
Certbot also logs to /var/log/letsencrypt/letsencrypt.log
so you can check there if you’re not seeing anything in /Library/Logs/certbot