Adding a Domain and SSL Certificate to Your Dokku App
Tags: webdev, devops, paas, cloud
Published: 2023-05-30 14:56:35


In a previous article, we looked at how to host Rails apps on DigitalOcean with Dokku. But we used an IP address as the domain, and while that works all right, you'll need a domain you've bought if you want your app URLs to look professional. A domain name is also required for SSL, as certificate authorities like [Let's Encrypt](https://letsencrypt.org/) will not issue certs to IP addresses. 

So, just as the title suggests, we'll add a domain and SSL cert to your app in the following steps.

## Not Yet Deployed Your App?
No problem. Open [the deployment article](https://dev.to/samuelodan/how-to-deploy-your-rails-app-to-a-digitalocean-droplet-using-dokku-eh7) in a separate tab and return when you're done deploying to DigitalOcean.

## Already Deployed Your App?
If you're using an IP address as the hostname, you'll have to add domains for Dokku.

Confirm by running this command:
```sh
# on your dokku host
# assuming app-name is 'ruby-getting-started'
# look at the value for 'Domains app vhosts:' in the output
dokku domains:report ruby-getting-started
```

If it's blank and `Domain app enabled` is `false`, run the following domain commands. Otherwise, skip to the [DNS Section](#create-a-dns-record).

### Add Global Domain
Run the following command to add your domain as the global domain:

```sh
# on your dokku host
dokku domains:add-global <example.com>
```

### Add App Domain
Run the following to add the domain to the app:

```sh
# on your dokku host
# assuming 'ruby-getting-started' is your app's name
dokku domains:add <ruby-getting-started> <ruby-getting-started.example.com>
```

This will also configure the server to use the vhost to access the app.

You can confirm the domain of your app by running this command:
```sh
# on your dokku host
# assuming app-name is 'ruby-getting-started'
# look at the value for 'domains app vhosts:' in the output
dokku domains:report ruby-getting-started
```

All right! Let's proceed.

## Create a DNS Record
Now that your app has been properly configured, you have to map your domain (or subdomain, in this case) to the IP address of your Dokku Droplet server.
I use NameCheap, but you can search for "how to add DNS record in <insert-your-domain-name-registrar" on Google.
It generally goes like this:
- Log in to the dashboard of your domain name registrar and go to the advanced DNS settings for the domain you used earlier.
- Add an `A` record with `*` as `Host` to catch all subdomains (`*.example.com`), and give it a `value` of your Droplet IP address. Set the TTL to `automatic` or 30 minutes and save the record.

See the table below for reference.

|    Type    | Host |    Value     |           TTL           |
|:----------:|:----:|:------------:|:-----------------------:|
| 'A' Record |  *   | 123.111.22.3 | Automatic or 30 minutes |

Your `ruby-getting-started.example.com` domain should be functional after a minute or so.

## Adding SSL
We'll be using [Let's Encrypt](https://letsencrypt.org/) because they provide free certificates, and there's an official Dokku plugin.

### Install the dokku-letsencrypt plugin
run this command:

```sh
# on your dokku host
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
```

### Set Global Let'sEncrypt Email
The plugin needs it to send you email reminders when certificates are about to expire. They expire in 90 days, but we'll address that soon.
Run this command to set the email globally so you don't have to do it on a per-app basis:

```sh
# on your dokku host
dokku letsencrypt:set --global email <your@email.com>
```

### Enable Let's Encrypt for Your App
The command below will generate a certificate for your app's domain and configure the webserver to work with it.
```sh
# on your dokku host
dokku letsencrypt:enable ruby-getting-started
```

Reload your app's URL, and you should see a new security status symbol in the browser. Nice!

## One More Thing
This certificate expires every 90 days, but thankfully, we don't have to always remember to update it. The dokku-letsencrypt plugin provides an option automatically update certicates that are due across all apps. 

### We May Have To Upgrade Dokku For This Part
The version of Dokku (`0.21.4`) currently installed on the 1-Click Droplet is very old and doesn't support Cron. I spoke with the project's maintainer, and he has [submitted a PR](https://github.com/digitalocean/droplet-1-clicks/pull/118) to update it to the latest version (`0.30.6`). 
To keep this section from getting too long, I've moved the upgrade guide to a separate article.

So, check your version by running the following:

```sh
# on your dokku host
dokku version
```

If it's below `0.3.x`, upgrade your dokku install using [the upgrade guide](https://dev.to/samuelodan/upgrading-old-version-of-dokku-1hda#confirm-the-version-youve-got-installed); otherwise, proceed.

### Enable Automatic Certificate Renewal

Run this command:
```sh
# on your dokku host
dokku letsencrypt:cron-job --add
```

You should see an output like this:

```
root@dokku-demo-dp:~# dokku letsencrypt:cron-job --add
-----> Updated schedule file
-----> Added cron job to dokku's crontab.
```

Well done! Your site is now safe to use, and users will no longer get a warning from their browsers when they visit.
Thanks for reading. Until next time!