Configuring Fly.io with a custom domain

December 21, 2023 - 6 min read

For my project, I decided to try a new hosting service besides the usual Vercel option. I saw that Fly.io has pretty good support for Remix, providing a straightforward setup experience. During this process, I learnt how to configure DNS records on namecheap.com, as well as adding a custom domain with SSL certificate on Fly.io.

What is fly.io

Fly is a PaaS (Platform-as-a-Service) that takes Docker images and other OCI compatible images and converts them into micro VMs, which is ran on Firecracker (the same technology powering AWS Lambda).

Fly operates across multiple regions, and ensures that users are routed to the nearest available instance using BGP (Border-Gateway-Protocol) as the load balancing substrate.

If you have used Heroku before, you can draw parallels between both PaaS. Read "Fly.io: the Reclaimer of Heroku's Magic" by Xe Iaso.

Configuring a custom domain with fly

Initially, I thought of walking through how I deployed my application on Fly, however I realized that Fly's documentation already cover it pretty well. Personally, I had a breeze as Fly.io has great support for Remix application, where the fly launch command will help to generate a Dockerfile as well as the fly.toml config file.

Here are a few resources to get you started with deploying your application:

Now let's discuss how to set up a custom domain for your Fly application. I bought my domain tickingcode.com on namecheap.com, and I would like to set it up such that going to both https://tickingcode.com and https://www.tickingcode.com will route me to my application.

To do so, we have to configure our DNS records to resolve our apex domain, tickingcode.com, to the IP Address of my Fly application. Namecheap offers DNS management for our bought domain, however the steps are applicable to other domain host services that you are using. I configured my domain host by following the following Fly articles:

Step 1: Obtain IP address

First we need to obtain the IP addresses (both IPv4 and IPv6) of our Fly application. To do so, we run the following command:

fly ips list

Step 2: Set up A and AAAA records

We will now set up our A and AAAA records in our DNS to point our apex domain to our Fly application.

An apex domain is a custom domain that does not contain a subdomain. In my instance, tickingcode.com is my apex domain. Apex domain are also known as root domain, domain apex, naked domain.

Both A and AAAA records are known as address records, and they are the most fundamental type of DNS record, located in the authoratative nameserver.

An A record is used to hold IPv4 addresses, whereas AAAA record is used to hold IPv6 addresses.

In namecheap, navigate to Domain List > Manage and ensure that "Namecheap BasicDNS" is selected for nameservers in the "Domain" tab. Then navigate to Advanced DNS tab and set the records up as such:

TypeNameValueTTL
A Record@IPv4_address1800
AAAA Record@IPv6_address1800

Note that the Name value is used to indicate a specific domain or subdomain values. Since we are setting up records for our apex domain, we use @ to indicate so. We will see an example later on when specifying for a subdomain.

Also note that TTL value is in seconds.

Step 3: Set up CNAME records

Next we will also set up a record for handling routing for www.tickingcode.com which has the www subdomain.

A CNAME record is known as a 'canonical name' record, which points to an alias domain, and never to an IP address. Read more on CNAME records.

TypeNameValueTTL
CNAME Recordwwwtickingcode.com (your custom domain)1800

This will ensure that upon lookup of the subdomain, the recursive resolver will be provided with the alias domain that the CNAME record points to, and perform another DNS lookup to procure the A record from the authoratative nameserver.

Step 4: Add SSL certificate for https connections

Next we will have to add SSL certificate for our custom domains. We will have to add 2 (in my case), one for the apex domain, and the other for the subdomain.

# Note: 'fly certs add' and 'fly certs create' functions similarly
fly certs add tickingcode.com
fly certs add www.tickingcode.com

To verify that the certificates have been generated successfully, we can run the following commands:

# this will show the status of available SSL certs for your app
fly certs list

# this will show the details of SSL cert issued for a particular host name
# Note: 'fly certs show and 'fly certs check' functions similarly
fly certs show tickingcode.com

In the process, if you have misconfigured any certificate, use fly certs delete hostname.

Step 5 (Optional): DNS Validation Instructions

This step is optional, it is done to verify domain ownership. It allows certificates to be issued before our custom domain is live and accepting traffic. It is only useful if we would like to access our custom domain to view our Fly application before the previous step is completed (before fly certs show is ready).

As our A, AAAA and CNAME records are stored on the same domain host, when we access our Fly application, it will conduct a DNS validation to verify that our domain host indeed have control over our custom domains. This would allow Fly to configure SSL certificates for our custom domains before accepting traffic

In order to achieve this DNS validation, we have to obtain 2 key information to create our additional CNAME records. The 2 information can be obtained from your application dashboard, under "Certificates" section. Under "Domain ownership verification", copy the CNAME and Record Value, and add them to your domain host as a CNAME record as such:

TypeNameValueTTL
CNAME RecordCNAME (starts with _acme-challenge)Record Value1800

Conclusion

That concludes my guide to adding custom domain for your Fly application. I did struggle in comprehending the documentation initially, especially for the DNS validation portion. This journey led me to relearn some networking fundamentals on DNS records and how DNS works.

Fly.io is awesome for allowing me to host my application cost free... so far, as long as my monthly resource utilization cost less than $5.

I hope that this guide serves you well! 😊