Using Dokku with Let's Encrypt wildcard certificate

dokku, lets encrypt, wildcard

21 Mar 2021

Wildcard certificates are handy and this was the first time when I needed to use them with Dokku. It was a little bit harder than I expected, but luckily, it is doable even with automatic renewal.

Right now (when I wrote this post), there is no wildcard support from dokku-letsencrypt plugin. Luckily, Dokku itself can use certificates from other sources.

Creating wildcard certificate with Certbot

For a wildcard certificate, you need to use a different challenge with Let’s Encrypt called DNS-01 where you need to change DNS to prove, you are the owner of the domain.

I used this tutorial from Jamie Scaife to install all needed to set up Certbot to use acme-dns. When you finish, you should have the wildcard certificate created.

Now, we need to tell Dokku to use our new wildcard certificate within our app.

Adding to Dokku

To add a certificate to Dokku for a certain app, we will use dokku certs:add command.

I found out, that it is easier to use a tar file with all related files, so we need to create one.

Create a new file, eg. /home/dokku/.ssl-certs/app/install where the app should be the name of your application. I will use as an example domain. Open it in your favourite editor and add this content:

rm -rf server.crt
rm -rf server.key
rm -rf certs.tar

cp /etc/letsencrypt/live/ server.crt
cp /etc/letsencrypt/live/ server.key

tar cvf certs.tar server.key server.crt

dokku certs:add app < certs.tar

The First 3 lines will ensure, we will use only fresh files.

Line 5 and 6 copies needed files from the letsencrypt folder, where certbot creates the certificates for us. You will need to change them with the correct path.

Line 8 creates a tar file that is then imported to Dokku using the last command. You will need to change app to your own Dokku app.

If you need to load the certificate to all Dokku apps on the server, you can replace the last line with:

APPS=`dokku --quiet apps:list`

for app in $APPS
  dokku certs:add $app < certs.tar

The last step is marking the script as executable:

chmod +x /home/dokku/.ssl-certs/app/install

Now, you can call the script and verify, that everything works as expected:


You should see something like this:

-----> Unsetting DOKKU_PROXY_PORT
-----> Unsetting DOKKU_PROXY_SSL_PORT
-----> Setting config vars
       DOKKU_PROXY_PORT_MAP:  http:80:5000
-----> Setting config vars
       DOKKU_PROXY_PORT_MAP:  http:80:5000 https:443:5000
-----> Configuring * built-in template)
-----> Creating https nginx.conf
       Enabling HSTS
       Reloading nginx

Renew the certificate

We will use Certbot’s --renew-hook within crontab (for automatic renewal).

Open the crontab using crontab -e command and add this line below:

0 0 */10 * * certbot renew --renew-hook "/home/dokku/.ssl-certs/app/install" > /var/log/letsencrypt/renew-errors.log

This will call the certbot renew command with our script in the renew-hook. When there will be a renewal, it will trigger the hook and call our script, which will copy the new certificate into the Dokku app.

Using wildcard certificate for review apps

If you are using Dokku for review apps (eg. copy of the stage app for each PR/MR), you can use this command to add the certificate to the review app with your dokku deploy user:

ssh $GIT_REMOTE_URL -- "certs:add ${APP_NAME} /home/dokku/.ssl-certs/app/server.crt /home/dokku/.ssl-certs/app/server.key"

Last notes

I hope, there is an easier way how to do it, but the script above works well.

If anything goes wrong, you will receive an email about the domain expiration from the Let’s Encrypt bot. So you should definitely add a working email when you are creating certificates with Let’s Encrypt.

Do you like it? You can subscribe to RSS (you know how), or follow me on Mastodon.