Custom domains

When you create a Fly App, it is automatically given a fly.dev subdomain, based on the app’s name. This is great for testing, but when you want to go to full production you’ll want your application to appear on your own domain and have HTTPS set up for you as it is with your .fly.dev domain. You can do this by adding your domain to your Fly App, then configuring DNS records through your DNS provider.

Add a custom domain for your app

To add a custom domain, first attach your domain to your Fly App to get DNS configuration instructions, then configure your DNS records with your DNS provider.

Add your domain to your app

Attach your domain to your Fly App. This prepares your app to generate TLS certificates and handle traffic for your custom domain, and shows you the DNS configuration options for your setup.

You can add your domain with flyctl or in your app dashboard under Certificates.

For example, using the CLI:

fly certs add example.com

This command will show you the applicable DNS configuration options for your setup, including:

  • A and AAAA records
  • CNAME records
  • Proxy setup (if using a CDN)
  • DNS-01 challenge (required for wildcards, optional for pre-traffic certificate generation)

If you are adding a wildcard domain with the CLI, put quotes around the hostname to avoid shell expansion:

fly certs add "*.example.com"

Use fly certs check <hostname> to check the certificate status and validation progress, or fly certs setup <hostname> to view the setup instructions again.

Configure DNS records

Now that you’ve added your domain to your app, configure DNS records with your DNS provider to direct traffic to your Fly App. The setup instructions in the dashboard, or from fly certs add, show the recommended DNS configuration for your situation.

Choose the DNS setup that matches your needs:

Use A and AAAA records for most direct connections to your app. These records point your domain directly to your app’s IP addresses.

The A and AAAA records you need to set will be shown in your dashboard, and in the output from fly certs add. If your app doesn’t have an IPv6 address, allocate one with fly ips allocate-v6.

Important: Hostname validation will fail without an IPv6 address—and we won’t attempt to issue or renew a certificate—unless you’re using a CNAME _acme-challenge for domain verification. However, we still recommend having both an IPv4 and an IPv6 address allocated if your app is serving traffic.

CNAME records

CNAME records work well for subdomains (like www.example.com or app.example.com). A CNAME points your custom domain at a unique .fly.dev hostname for your app. CNAME records are also a good option if you have many IP addresses assigned to your app, or expect to change them in the future.

Set the CNAME record with your DNS provider. Each app has a unique CNAME target that will be shown in the dashboard for your certificate, or in the output from fly certs add.

Setting CNAME records for the apex domain can be problematic, and should be avoided unless your DNS provider supports CNAME flattening. Some providers use a special name for these records, such as ANAME or ALIAS, and some will flatten a CNAME at the apex automatically. In general, we recommend setting A/AAAA records on the apex domain.

Proxy/CDN setup

If you’re using a proxy or CDN (like Cloudflare) in front of your Fly application, configure only an AAAA record pointing to your app’s IPv6 address, as certificate generation requires IPv6 traffic.

DNS Challenge

Use the DNS-01 challenge when:

  • You need a wildcard certificate
  • You want to generate the certificate before directing traffic to your app
  • Automatic validation methods don’t work for your setup

This will require setting an _acme-challenge CNAME record on your domain. The required record will be shown in your dashboard, or in the output from fly certs add.

Certificate validation

After you have configured your DNS, Fly.io automatically validates your domain ownership and issues certificates. This happens through one of these methods:

  • TLS-ALPN challenge: Validates through a TLS handshake with Fly Proxy. This is the preferred method and works automatically for direct connections.

  • HTTP-01 challenge: Validates by requesting a specific file from your domain. Used automatically when TLS-ALPN isn’t available, such as with proxy/CDN configurations.

  • DNS-01 challenge: You manually add a DNS record to validate domain ownership. Required for wildcard certificates, or to generate certificates before directing traffic to your app.

Other fly cert commands

  • fly certs list - List the certificates associated with an app.
  • fly certs check <hostname> - Trigger a check on the domain validation and DNS configuration for the given hostname and return results in the same format as fly certs show.
  • fly certs setup <hostname> - Shows setup instructions for configuring DNS records for an existing certificate.
  • fly certs remove <hostname> - Remove a certificate from an app for the given hostname.

Teaching your app about custom domains

Your application code needs to know how to accept custom domains and adjust the responses accordingly. If you’re hosting content on behalf of your users, this typically means mapping the incoming hostname to a particular ID in your application database.

When users make requests, their browser sends a Host header you can use to alter the behavior of your application. When you run your app server on Fly.io directly, just get the contents of the Host header to identify a request.

If you’re running your application on another provider, you will need to create a proxy application, like nginx to route traffic through Fly.io. Your application can then use the X-Forwarded-Host header to determine how to handle requests.

Supported top-level domains

We support the top-level domains on the IANA list. Note that we only periodically update top-level domain support and there might be a delay before we add support for new top-level domains.

Troubleshoot certificate creation

Certificate creation or validation seems to hang, stall, or fail

Let’s Encrypt™ is a free, automated, and open certificate authority that Fly.io uses to issue TLS certificates for custom domains. However, Let’s Encrypt imposes certain rate limits to ensure fair usage. If you encounter issues when creating or validating a certificate for a custom domain on Fly.io, it’s possible that you’ve hit these rate limits.

The following rate limits from Let’s Encrypt apply:

  • Certificates per Registered Domain: 50 per week
  • Duplicate Certificate limit: 5 per week
  • Failed Validation limit: 5 failures per hostname, per hour

Note that certificate renewals don’t count against your Certificates per Registered Domain limit.

If you encounter issues when adding or validating a certificate for a custom domain on Fly.io, you can use the following methods to troubleshoot:

  • Use Let’s Debug: A diagnostic tool/website to help figure out why you might not be able to issue a certificate for Let’s Encrypt. Using a set of tests, it can identify a variety of issues, including: problems with basic DNS setup, problems with nameservers, rate limiting, networking issues, CA policy issues, and common website misconfigurations.
  • Wait and retry: If you’ve hit a rate limit, you’ll need to wait until the rate limit window passes before you can successfully create or validate a certificate again. We don’t have a way to reset it.

The best way to avoid hitting rate limits is to use staging environments and domains for testing and development, and to carefully plan your certificate issuance to stay within the limits. Avoid failed validation by ensuring that your DNS records are correctly configured, with no conflicting records.

If you’re building a platform on top of Fly.io, and you expect that your users will frequently delete and then recreate the same resources within a short window, consider implementing “soft delete” logic into your platform that retains the Fly.io resources for a period of time, negating the need to recreate certs frequently.

I use Cloudflare, and there seems to be a problem issuing or validating my Fly.io TLS certificate

If you’re using Cloudflare’s proxying feature (orange cloud), Fly.io can generate a certificate using the HTTP-01 challenge.

For this to work:

  1. Configure DNS records properly: Create only an AAAA record pointing to your app’s IPv6 address. Do not create an A record or CNAME when using Cloudflare’s proxy.
  2. Set SSL mode: Use “Full” or “Full (Strict)” SSL mode in Cloudflare. “Flexible” mode can cause redirect loops.

Alternatively, you can use the DNS-01 challenge method instead of the automatic validation method, though this may conflict with Cloudflare’s own certificate issuance.