All skills
wshaddix avatar

/fly-io

@0d51225

Deploy, configure, and manage applications on the Fly.io platform using flyctl CLI, fly.toml configuration, Fly Machines, Fly Volumes, private networking, secrets, health checks, autoscaling, and GitHub Actions CI/CD. Use when deploying any application to Fly.io, writing or modifying fly.toml configuration, managing Fly Machines or Volumes, configuring networking (public services, private 6PN, Flycast, custom domains, TLS), setting secrets, configuring health checks, setting up autostop/autostart or metrics-based autoscaling, deploying with GitHub Actions, managing Fly Postgres databases, or preparing an app for production on Fly.io.

Use this Skill: https://skilld.dev/gh/wshaddix/dotnet-skills/fly-io

This session only. Nothing lands on disk.

referencesnetworking.md

≈1.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Fly.io Networking Reference

Table of Contents

Public Networking

Fly Proxy routes public internet traffic to your app. Default-deny: nothing is exposed unless configured via [http_service] or [[services]] in fly.toml.

All traffic hits Anycast edge servers globally. Fly Proxy handles TLS termination, HTTP normalization, load balancing, and connection routing to the nearest healthy Machine.

IP Addresses

fly ips list                           # List allocated IPs
fly ips allocate-v6                    # Dedicated IPv6 (free, auto on first deploy)
fly ips allocate-v4 --shared           # Shared IPv4 (free, auto for HTTP/HTTPS apps)
fly ips allocate-v4                    # Dedicated IPv4 (billed monthly)
fly ips release <ip-address>           # Release an IP

Shared IPv4 (recommended for most apps):

  • Free, shared across apps/orgs
  • Routing based on app domain
  • Auto-allocated for apps with HTTP on port 80 or TLS+HTTP on port 443
  • Works for non-80/443 TCP ports when using TLS handler

Dedicated IPv4 (use when):

  • Non-HTTP protocol without TLS
  • UDP required (no shared IPv4/IPv6 UDP support)
  • Raw TCP with self-managed TLS termination
  • Fly Postgres exposed to internet over TLS

Custom Domains & TLS

fly certs create mydomain.com          # Add domain + auto-provision TLS cert
fly certs list                         # List certificates
fly certs show mydomain.com            # Show cert details
fly certs delete mydomain.com          # Remove certificate

DNS setup:

  • CNAME: mydomain.com -> my-app.fly.dev
  • Or A record: mydomain.com -> shared/dedicated IPv4
  • Plus AAAA record: mydomain.com -> IPv6 address

Certificates are auto-renewed via Let's Encrypt.

Private Networking (6PN)

All apps in an organization are connected via a WireGuard mesh using IPv6 (6PN). This is automatic and always on.

  • Apps in the same org can communicate directly via 6PN addresses
  • Apps in different orgs are isolated (no cross-org 6PN)
  • 6PN bypasses Fly Proxy (no autostop/autostart; use Flycast for that)

Binding to accept private connections:

  • Bind to fly-local-6pn:<port> or [::]:<port> (all interfaces)
  • The 6PN address is aliased to fly-local-6pn in /etc/hosts
  • FLY_PRIVATE_IP env var contains the Machine's 6PN address

Important: 6PN addresses are NOT static. They change on reboot/migration. Use .internal DNS names instead.

Internal DNS

The Fly.io DNS server at fdaa::3 resolves .internal domains for inter-app communication.

AAAA Queries (Machine IPv6 addresses)

Domain Returns
<appname>.internal All started Machines in any region
<region>.<appname>.internal Machines in specific region
<machine_id>.vm.<appname>.internal Specific Machine
<process_group>.process.<appname>.internal Machines in process group
top<N>.nearest.of.<appname>.internal N closest Machines
global.<appname>.internal Alias for <appname>.internal

TXT Queries (Discovery)

Domain Returns
_apps.internal All app names in org
vms.<appname>.internal Machine IDs + regions (started only)
all.vms.<appname>.internal Machine IDs + regions (all deployed)
regions.<appname>.internal Regions with started Machines
_instances.internal All started Machines in org (ID, app, IP, region)

Only started (running) Machines appear in AAAA queries. Stopped/autostopped Machines are excluded.

Example usage from within a Machine:

dig +short aaaa my-db.internal                  # Find database app
dig +short aaaa iad.my-app.internal             # Machines in iad region
dig +short txt _apps.internal                   # List all apps in org
dig +short txt regions.my-app.internal          # Regions with running Machines

Flycast (Private Proxy)

Flycast provides Fly Proxy features (load balancing, autostop/autostart) over the private network. Use Flycast instead of raw 6PN when you need:

  • Autostop/autostart for internal services
  • Load balancing across Machines
  • Health check-based routing
fly ips allocate-v6 --private          # Allocate Flycast address

Flycast addresses are accessible only within the organization's private network. Remove public IPs from private apps (fly ips release <ip>) to prevent external access.

Dynamic Request Routing

Use the fly-replay response header to replay requests to different regions, apps, or Machines:

# Route to a specific region
fly-replay: region=iad

# Route to a specific app
fly-replay: app=my-other-app

# Route to a specific Machine
fly-replay: instance=<machine-id>

# Route to a different app in a different region
fly-replay: region=ord;app=my-other-app

Your app returns fly-replay as a response header and Fly Proxy replays the request to the specified target. Useful for:

  • Primary/replica database routing (write to primary region, read from nearest)
  • Multi-tenant routing
  • Sticky sessions

WireGuard VPN

Connect your local machine to the Fly.io private network:

fly wireguard create                   # Generate WireGuard config
fly wireguard create my-org iad my-peer  # With specific org, region, peer name
fly wireguard list                     # List tunnels
fly wireguard remove                   # Remove a tunnel

Import the generated .conf file into your WireGuard client. Once connected:

  • Access .internal DNS
  • Connect directly to Machine 6PN addresses
  • Useful for development/debugging against production private services

DNS on WireGuard: specified in the generated config file (e.g., DNS = fdaa:0:18::3). Pattern: org prefix + ::3.

Egress IPs

Outbound connections from Machines use IPv6 addresses that are NOT the Anycast IPs.

# Check outbound IP from within a Machine
echo $FLY_PUBLIC_IP

# Allocate static egress IP (billed monthly)
fly machine egress-ip allocate <machine-id>
fly machine egress-ip list
fly machine egress-ip release <egress-ip>

Default: Egress IPs are dynamic, may change on Machine migration. Do not allowlist them.

Static egress IPs: Per-machine, survives migration. Use when connecting to services requiring IP allowlisting. Prefer WireGuard when possible.

Source: SKILL.md on GitHub

1 alert14d3 checks · Risk HIGH
  • Gen Agent Trust Hub14d

    The skill provides comprehensive guidance for deploying and managing applications on the Fly.io platform. It includes installation instructions for official tooling and defines common workflows for infrastructure management. A minor vulnerability surface exists regarding the processing of user-provided configuration files.

  • Socket14d

    No alerts

  • Snyk14d

    Risk: LOW · No issues

Signed by skilld at 0d51225. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 8 months ago

README badge

README badge for wshaddix/dotnet-skills/fly-io