Expose home VM to the internet using Fly's Private Network and WireGuard
January 07, 2023 -I wanted to host applications on private servers and have them accessible on the internet.
But wanted to avoid having to punch holes on internet routers, exposing my home/office IP or having to figure out more complex stuff.
With this in mind, thought about using Fly's Private Network (also known as 6PN) with a custom node and connect the Fly org network with it.
Then, deploy an app to Fly that routes traffic back to this private instance.
▶️ I also made a recording of this that you can watch on YouTube here.
1. Have a VM, server and web server running 😉
For this I used a small Alpine Linux VM with nginx, running on port 80. Nothing special on this, set it up using QEMU to avoid impacting my local setup.
2. Create a WireGuard tunnel with Fly
Follow Fly's Private Network VPN instructions and generate a WireGuard profile for your setup.
$ flyctl wireguard create personal cdg alpine-small-vm
personal
is my Fly Organization, cdg
is Paris region and alpine-small-vm
is the name for the tunnel.
When asked, give a name to store the wireguard configuration (Eg. the one you
used for the VM, alpine-small-vm.conf
).
Transfer this file to the VM or the machine that will connect to Fly's 6PN
$ scp alpine-small-vm.conf [email protected]:.
3. Connect the VM to Fly using WireGuard
Setup WireGuard on the machine:
$ apk add -U wireguard-tools bind-tools
$ mv ~/alpine-small-vm.conf /etc/wireguard/
And connect using wg-quick up alpine-small-vm
.
You can verify using dig
for apps and see other peers, getting their IPs:
$ dig +short txt _apps.internal
"fly-builder-delicate-silence-7949,spring-resonance-1024"
$ dig +short txt _peer.internal
"alpine-small-vm"
4. Deploy the Fly app that proxy the connection
We will use Caddy since provides the simplest reverse proxy
Create a Caddyfile
configuration:
:8080 {
reverse_proxy alpine-small-vm._peer.internal:80
}
This indicates to use port 8080
and to proxy all the requests to our VM,
using port 80
.
Now, create a Dockerfile
for the app:
FROM caddy:2.6.2
COPY Caddyfile /etc/caddy/Caddyfile
With that in place, use flyctl
to setup your application:
$ flyctl launch
...
Scanning source code
Detected a Dockerfile app
...
Wrote config file fly.toml
...
? Would you like to deploy now? No
Your app is ready! Deploy with `flyctl deploy`
Remember to answer no
to the deploy question so we can adjust the generated
configuration.
Update fly.toml
to enable the private_network
experimental feature
(this could be obsolete information, need to confirm).
[experimental]
private_network = true
Now you can deploy:
$ flyctl deploy
Once deploy completes, visiting the app URL should automatically proxy web traffic to your internal VM.
5. That's all!
Now that you can route web traffic to your VM, you could setup different domain names and have those routed to different machines in the private network or into more complex configurations.
Enjoy! ❤️