Higher Order Heroku

Developing on Heroku

Subscribe to the Heroku Weekly to get the best of the Heroku community in your inbox. Every weekish.
Submit a link for inclusion on Higher Order Heroku and in the Heroku Weekly.

Configuring CloudFlare DNS for a Heroku App

By Ryan Daigle on November 9, 2012

This article was updated on Sep. 30, 2014 to reflect CloudFlare's new CNAME flattening capability

CloudFlare is a popular, and accessible, CDN and website optimizer. If you've heard of Akamai then you know basically what CloudFlare does -- they sit between your site and your users and accelerate your site's content by edge-caching and other nifty on-the-fly techniques. CloudFlare also offers additional availability and security features to automatically handle DDoS and other real-world problems.

Heroku needs no introduction other than to say it's the best place to deploy your applications.

So, how do you get the benefits of CloudFlare for your Heroku application? Until CloudFlare provides a Heroku add-on there's a bit of manual configuration that needs to occur.

For the purpose of this post I'm assuming you already have a CloudFlare account and an existing Heroku app.

Initial setup

Since CloudFlare needs to be able to handle DDoS and other traffic-related events on your behalf, it must serve as your DNS. When you add a new website to CloudFlare it will scan your existing DNS records and duplicate them in the CloudFlare DNS.

Initial DNS configuration

While this is a great way to quickly bootstrap your DNS, it might result in the use of A-records to resolve your root domain (which is a Heroku anti-pattern). Under the covers Heroku uses multiple IP addresses. Choosing just one to bind to is a dangerous practice that can adversely affect your app's availability. In short, you should never use A-records in your DNS on Heroku because those static IP addresses can change at any time and represent a single point of failure.

The proper setup is to use CloudFlare's CNAME flattening feature to dynamically resolve requests for the root domain (ryandaigle.com is a root domain whereas www.ryandaigle.com is not).

Root domains

With CNAME flattening, resolution requests for the root domain return a single IP address (as is required of A-records) determined at the time of the request. However, each resolution request can return a different IP, so you haven't bound yourself to a single point of failure. It represents the best combination of CNAME and A-records.

If you're not already on the DNS page for your domain, choose the "DNS Settings" option for the domain in question from your list of sites.

To use CNAME flattening on CloudFlare for your root domain, just add a CNAME record pointing from your root domain to your app on Heroku.

On adding the record, it will be recognized as a CNAME record at the root domain and flattening will be in effect.

At this point, requests to the root domain will be properly resolved to one of the many Heroku IP addresses currently in rotation and your root is properly configured.

Sub-domains

If you have sub-domains you want your Heroku app to also server, you'll need to make sure you have the proper CNAME DNS entries.

For instance, map the www sub-domain to your Heroku app URL (appname.herokuapp.com) using a CNAME record.

CNAME entry

Confirmation

To confirm your setup, verify that all requests are being resolved by CloudFlare. The easiest way to do this is to inspect the HTTP headers using the curl command.

$ curl -I ryandaigle.com
HTTP/1.1 200 OK
Server: cloudflare-nginx
...
Set-Cookie: __cfduid=askdjfalk8a98a9sd8fa9sda9jkar8; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.ryandaigle.com

You can identify a CloudFlare-handled request by two response headers: the Server being set to cloudflare-nginx and a __cfduid cookie. If you see these two headers in the response then CloudFlare is properly handling your request.

Do this for the root domain as well as any sub-domains you configured in CloudFlare.

As you may already know, troubleshooting DNS is notoriously difficult given the propagation lag. In my testing it took about an hour for new CloudFlare DNS settings to take effect (and this is after CloudFlare's name servers were active for my site).

Now that your DNS is properly configured I'd suggest browsing the CloudFlare app store and your site's CloudFlare settings for all the cool toys and switches you now have at your disposal. They also have a good blog post for new users.