Back in February, I started using nginx Proxy Manager to manage external access to the various web services that I host on my Raspberry Pi – namely, Home Assistant, calibre-web and Nextcloud. Nginx Proxy Manager (NgPM) includes Certbot, which is an automated tool for managing SSL certificates from Let’s Encrypt, and it should automatically renew certificates every three months so that there’s always a valid certificate in use.
In practice, this doesn’t work on my NgPM install. I understand it’s a bug in an older version that has been fixed, but as I run NgPM as a Home Assistant addon, that bug fix hasn’t made its way downstream. Attempts to renew the SSL certificates through the NgPM web interface fail with unhelpful errors.
Hopefully, the Home Assistant addon package will get updated soon, and this won’t be a problem anymore. But in the meantime, this is the workaround that I’m using – manually interacting with Certbot on the command line to generate a certificate. This can then be imported into NgPM manually.
Step 0: access Certbot through Docker
If you have access to Certbot directly, you can skip this step.I don’t, and Certbot is no longer supported on Windows, so I’m using the version of Certbot that comes with NgPM.
As this runs in Docker, we need to open a shell session inside the Docker image, using docker exec -it addon_a0d7b954_nginxproxymanager sh. I had to run this as root on my system using sudo.
Step 1: request the certificate
Now we can interact with Certbot itself. Here’s the command to type:
certbot certonly --manual --preferred-challenges dns - d example.comLet’s break this down:
certonlyspecifies that we just want the certificate – we don’t want Certbot to install this for us.--manualtells Certbot that we want to manually authenticate the domain.--preferred-challenges dnsmeans that we want to authenticate using DNS, rather than HTTP – this is tricky to do when you’re using a reverse proxy-d example.comis the domain that we want the SSL certificate for.
Step 2: add a TXT record to authenticate
If you use something like Google or Cloudflare for DNS, then you may be able to use a plugin to automate this step. I don’t, so here we create a TXT record on our DNS provider’s dashboard to authenticate the certificate. This will be something like _acme-challenge.example.com and will include a text string that Certbot gives you.
Once you’ve created the TXT record, my suggestion is to set a timer for 2-3 minutes, before pressing Enter to continue. DNS records can take anything from a matter of seconds to a few minutes to propagate, and if you try to continue too soon, the authentication will fail and you’ll need to go back to step 1. Trust me on this.
Step 3: download the certificate files
If the authentication is successful, then Certbot will have created two files for you. For me, these were something like:
/etc/letsencrypt/example.com/fullchain.pem
/etc/letsencrypt/example.com/privkey.pemAs I was running Certbot from within Docker, the easiest way I found to save these was to type cat /etc/letsencrypt/example.com/fullchain.pem (and for privkey.pem) and then copy and paste the output into a file locally.
Step 4: add to Nginx Proxy Manager
If you’re using Nginx Proxy Manager and want to be able to use your new SSL certificate, then open the SSL Certificates tab at the top, click ‘Add SSL Certificate’, and then ‘Custom’. Don’t choose the Let’s Encrypt option; although these certificates were issued by Let’s Encrypt, you want to import them manually.
Give it a name – I usually put the name of the service and the month (e.g. Nextcloud Sept 2024). Upload the privkey.pem file as the Certificate Key, and fullchain.pem as the Certificate. Click Save.
Now, go to the Proxy Hosts tab, and choose the host that matches the SSL certificate that you’ve uploaded. Click on the three dots on the right hand side, and choose Edit. On the SSL tab, select the certificate that you’ve uploaded. And that should be it – try navigating to your domain to see if it’s working and check that the new certificate is in use.
No auto-renewals
It’s worth baring in mind that manually-issued Let’s Encrypt certificates won’t normally auto-renew. You apparently can use validation hooks to enable auto-renew, but this goes beyond my expertise.
I’m hoping that the package maintainer for the Nginx Proxy Manager addon for Home Assistant will issue a new release soon, which will enable me to auto-renew my certificates in future. If not, then I have my own guide to follow to manually renew.
