How to set up an AWS Route 53 custom domain for your Heroku app
This guide shows you everything you need to set up a Route 53 domain with your Heroku app. It assumes you want to set up these styles of domains:
- example.com (naked domain; without the
- both with https (https as opposed to http).
This guide assumes you already have:
- A heroku app
- A domain (AKA Hosted Zone) with AWS Route 53
Let’s get started!
Let Heroku know your domain
Let your app know about your domain:
heroku domains:add example.com
heroku domains:add www.example.com
It will display something like this:
Adding www.example.com to ⬢ example-app... done
▸ Configure your app's DNS provider to point to the DNS Target
▸ For help, see https://devcenter.heroku.com/articles/custom-domains
The domain www.example.com has been enqueued for addition
▸ Run heroku domains:wait 'www.example.com' to wait for completion
Let Heroku know that you want certs
Run this to enable certs:
If you see something like ‘▸ Hobby or above tier required for ACM’, then you need to upgrade your heroku plan, which you can do with
heroku dyno:resize hobby (note, that will cost $7 USD per month).
When you run
heroku certs:auto:enable successfully, you should see something like:
=== Your certificate will now be managed by Heroku. Check the status by running heroku certs:auto.
Note that if you try to see your certs, they will be failing:
=== Automatic Certificate Management is enabled on exampleappDomain Status Reason Last Updated
──────────────────── ─────── ────────────────────────────────────────────── ────────────
www.exampleapp.com Failing Unable to resolve DNS for www.exampleapp.com 6 minutes
exampleapp.com.au Failing Unable to resolve DNS for exampleapp.com.au 6 minutes
But that’s okay because we haven’t set up our DNS records yet. Let’s do that now.
Configuring DNS Records in Route 53
Head over to AWS in the browser, navigate to Route 53, click on Hosted Zones, click on your domain, and click on ‘Create Record’.
Under ‘Record Name’ type
www and under ‘Record Type’ select CNAME. In the ‘Value’ field, place the DNS Target found by running
heroku domains .
Now, try running
heroku certs:auto — you should see the domain you just set up is now passing!
You may also notice that the naked domain (the one without the www at the start) is still failing. Let’s address that now.
Configuring DNS Records for a naked domain
This is done a completely different way, but don’t worry, it takes only a moment.
In AWS, navigate out of Route 53 and over to S3, and create a bucket with (exactly) the same name as your hosted zone. Examples: if you hosted zone is example.com, your bucket should be named example.com, or if you have myapp.io, the bucket should be called myapp.io.
Once you create the bucket, select it and go to ‘Properties’, and scroll right down to ‘Static website hosting’. Click ‘Edit’, ‘Enable’. Under ‘Hosting Type’, select ‘Redirect requests for an object’, and under ‘Host name’ enter your URL including www at the start (e.g. www.example.com). (note that ‘Protocol’ option can be left as ‘None’). Save the changes.
Almost there, now head back to Route 53, select your hosted zone, click Create Record. Leave ‘Record Name’ blank, and under ‘Record Type’ select
A and check the switch that says ‘Alias’. Under ‘Choose Endpoint’, select ‘Alias to S3 website endpoint’, and you’ll be prompted for the region and name of your bucket. Once you’re done, click ‘Create Record’.
Making certs work
If you run
heroku certs:auto you may see that one or more of your certs fails, if that’s the case, you have a couple of options. Firstly, you can wait, and Heroku will try keep trying periodically for up to 3 days, so provided everything is set up correctly, the cert should get issued eventually.
However, if you’re sure everything’s set up correctly and you want to trigger a cert refresh, you can run this, but please read on before doing so:
# careful! - read below before running this
There is a strict limit (set by Let’s Encrypt, the cert issuer) on how often you can do this: 5 renewals per week . I was happy to run this command a single time because I was confident that all the previous steps were done correctly and that it would work. If for any reason it doesn’t work, keep tabs on how many attempts you’ve made so you don’t go over the limit — as you’ll simply have to wait a week if you go over the limit and there’s nothing Heroku or you’ll be able to do except wait.
At this point, if you go to your browser and visit your domain or naked domain (your URL without www), they should both route to your heroku app!
Also, you may notice that https is now working on your site too!