Wildcard DNS and SSL on Fly
Fly makes it surprisingly easy to configure wildcard DNS, such that anything.your-new-domain.dev
is served by a single Fly application (which can include multiple instances in multiple regions with global load-balancing).
Their documentation is at SSL for Custom Domains. Here’s how I set it up.
Register the domain
I’m using your-new-domain.dev
in this example, which is not a domain I have registered. .dev
is interesting here because it requires SSL (or TLS if you want to be pedantic about it).
Create an application with an IPv4 and IPv6 IP address
First, create an application:
fly apps create --name your-wildcard-dns-app
Then create both an IPv4 and an IPv6 address for the application:
fly ips allocate-v4 -a your-wildcard-dns-appTYPE ADDRESS REGION CREATED ATv4 37.16.10.138 global 7s ago
fly ips allocate-v6 -a your-wildcard-dns-appTYPE ADDRESS REGION CREATED ATv6 2a09:8280:1::1:3e99 global 4s ago
The IPv4 address is so you can serve traffic.
The IPv6 address is needed as part of Fly’s scheme to protect against subdomain takeover - see How CDNs Generate Certificates: A Note About a Related Problem for details.
Configuring DNS
Now setup the following DNS records:
your-new-domain.dev A: 37.16.10.138your-new-domain.dev AAAA: 2a09:8280:1::1:3e99*.your-new-domain.dev CNAME: your-wildcard-dns-app.fly.dev.
That CNAME
record does the real magic here.
Issue the certificate
You can ask Fly to issue the certificate (which uses LetsEncrypt under the hood) by running this:
fly certs create "*.your-new-domain.dev" \ -a your-wildcard-dns-app
Verifying the certificate
There’s one last step: you need ta add an additional DNS record to verify the certificate.
Instructions for doing this can be found at:
https://fly.io/apps/your-wildcard-dns-app/certificates
Click to view your unverified certificate and you should get a set of information that includes the extra DNS entry you need to add.
It will look something like this:
_acme-challenge.your-new-domain.dev CNAME your-new-domain.dev.6g0mj.flydns.net.
Add that DNS record, then click the “Check again” button on the certificate screen and your certificate should be verified shortly afterwards.
Deploy an app
With the certificate in place, you can deploy a Fly app (using regular Fly or the new Fly Machines). Traffic to any subdomain of your domain, with or without https://
, will be served by your new application.
Configuring ports for your app
One last detail which caught me out: you need to configure your Fly app to accept traffic on both port 80 AND port 443 for this to work.
This is needed even if your app itself only serves on port 80 (or 8000 or whatever). The configuration here tells Fly’s routing proxy what to do.
Using fly.toml
this means there should be two services.ports
sections - here’s an example that includes those:
app = "your-wildcard-dns-app"
kill_signal = "SIGINT"kill_timeout = 5
[[services]] internal_port = 8000 protocol = "tcp"
[services.concurrency] hard_limit = 25 soft_limit = 20
[[services.ports]] handlers = ["http"] port = "80"
[[services.ports]] handlers = ["tls", "http"] port = "443"
[[services.tcp_checks]] interval = 10000 timeout = 2000 grace_period = "10s"
If you are using Fly Machines you’ll need to include the following in the JSON that is used to launch the machine:
"services": [ { "ports": [ { "port": 80, "handlers": [ "http" ] }, { "port": 443, "handlers": [ "tls", "http" ] } ], "protocol": "tcp", "internal_port": 8001 }