Bridge your other deployments to Fly.io
Sometimes you can recreate production on Fly.io without any issues. Other times you need to be able to incrementally move things over. Fly.io has private networking by default for apps in the same organization, but you can also easily connect your existing external servers to this private network. This lets you use your private network as a way to incrementally move services over.
Say you have an existing service on AWS or a database with RDS that needs to be accessed over RDS. You can use that AWS instance to pivot traffic from your Fly Machines to those other services. You can also go the other way and access your Fly apps (such as an instance of Ollama) from AWS, your laptop, or any other self-hosted server you have in your arsenal. Or maybe you’re making a tool for a support team, and it needs to hit that one database on prem.
Fly.io private networks use WireGuard internally, and when you connect other computers to that network, you do connect to them over WireGuard. WireGuard is used by many people for many reasons, but the primary use is a “site-to-site” VPN like this. This won’t route all of your traffic through Fly.io’s gateway servers, but it will give you internal access to your private network from anywhere.
Weaving the networks together
Make sure you have WireGuard installed on your target server. Their install page has more details, but on an Ubuntu server all you need to do is:
sudo apt -y install wireguard
Once that’s done, you’re off to the races!
On your laptop, make the config for the target server with fly wireguard create
. You’ll need the following information:
- The organization you want to join that server to (such as
personal
, or your company’s name). - The region you want to create the peer in: you should choose the closest region to the target computer.
- If you’re really not sure which region is the closest, here’s a magic command you can try:
curl -Iso /dev/null -w '%header{fly-request-id}' https://fly.io | cut -d- -f2
.
- If you’re really not sure which region is the closest, here’s a magic command you can try:
- The name you want to use for that computer on your Fly network, such as the hostname.
- A path to put the generated WireGuard config, such as
~/fly0.conf
to drop it asfly0.conf
in your home directory.
For example, I’m going to create a peer in my personal organization for my server named phantoon
. I live in Ottawa, so the closest datacenter to me is yyz
. The command to create my peer will look like this:
fly wireguard create personal yyz phantoon ~/fly0.conf
The fly0.conf
file contains all the configuration WireGuard needs to set up a tunnel, namely:
- The private key for the node
- The local IPv6 address the node should use
- The DNS server for your private network
- Addresses, IP ranges, and public keys for the WireGuard gateway
Copy fly0.conf
to /etc/wireguard
on the target computer:
scp ~/fly0.conf root@phantoon.local:/etc/wireguard/fly0.conf
Then connect to the computer (likely over SSH) and enable WireGuard to start on boot:
ssh root@phantoon.local
systemctl enable --now wg-quick@fly0.service
This will create an interface named fly0
:
$ ip addr show fly0
4: fly0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet6 fdaa:0:641b:a7b:9285:0:a:1b02/120 scope global
valid_lft forever preferred_lft forever
Now try to ping the Machines API server _api.internal
:
$ ping _api.internal -c 4
PING _api.internal (fdaa:0:641b::3) 56 data bytes
64 bytes from fdaa:0:641b::3: icmp_seq=1 ttl=64 time=10.4 ms
64 bytes from fdaa:0:641b::3: icmp_seq=2 ttl=64 time=39.2 ms
64 bytes from fdaa:0:641b::3: icmp_seq=3 ttl=64 time=83.7 ms
64 bytes from fdaa:0:641b::3: icmp_seq=4 ttl=64 time=123 ms
This means that you can successfully query any .internal
addresses for apps and Machines in your organization. Congrats, you’re in!
Accessing workloads outside of your private network
To access a workload outside of your private network (such as a secret store), use the DNS name peername._peer.internal
. For example, to access the node phantoon
from your Fly apps, connect to phantoon._peer.internal
:
$ ping phantoon._peer.internal
PING phantoon._peer.internal (fdaa:0:641b:a7b:9285:0:a:1b02) 56 data bytes
64 bytes from phantoon._peer.internal (fdaa:0:641b:a7b:9285:0:a:1b02): icmp_seq=1 ttl=62 time=24.4 ms
64 bytes from phantoon._peer.internal (fdaa:0:641b:a7b:9285:0:a:1b02): icmp_seq=2 ttl=62 time=37.6 ms
64 bytes from phantoon._peer.internal (fdaa:0:641b:a7b:9285:0:a:1b02): icmp_seq=3 ttl=62 time=85.4 ms
64 bytes from phantoon._peer.internal (fdaa:0:641b:a7b:9285:0:a:1b02): icmp_seq=4 ttl=62 time=197 ms
Homework
Getting ping working should be good enough to get you started, but here’s some optional homework in case you want to see what you can really do with this:
- Connect your laptop/workstation to your private network with the same flow (you may need to install the GUI WireGuard app if you use Windows or macOS).
- Expose Prometheus metrics on port 9195 of your app and then grab the current metrics with
curl yourapp.internal:9195/metrics
on your laptop. - Install Postgres on your laptop somehow. Configure your app to connect to that Postgres database on your laptop over WireGuard.
- Connect a few other computers to your private network. Install a Minecraft server on one of them and play together.
Hint: you may need to allow private network addresses through your firewall. Check the documentation of your firewall tool of choice and allow traffic from fly0
through as if it’s an “internal” interface.