Public Network Services
Fly.io has public and private network services available. The public network services connect applications to the wider public internet, while the private network services allow application instances to communicate with other application instances within the Fly.io private network.
IP Addresses
Anycast
We announce global IP blocks from all of our datacenters over BGP, otherwise known as anycast. Anycast is a core internet routing mechanism that connects clients to the "nearest" server advertising a block of IPs. You can read all about it on Wikipedia.
IPv6
A new Fly App running a public service automatically gets a dedicated anycast IPv6 address when it's first deployed.
Shared IPv4
Along with the dedicated IPv6, apps configured to handle either
- HTTP on port 80, or
- TLS & HTTP on port 443
(or both) are automatically given a shared anycast IPv4 address on the first deployment.
If you want to allocate a shared IPv4 to an app without a public IPv4 address, this is possible (with flyctl v0.0.439 and newer) using
fly ips allocate-v4 --shared
This command will fail if the app has a dedicated IPv4 address. You can release an IP with fly ips release
.
Dedicated IPv4
Allocating a dedicated IPv4 anycast address is now opt-in only, but can still be done manually with
fly ips allocate-v4
when needed; for example, if you want your app to handle TCP directly.
IPv6 addresses are free. Global IPv4 addresses are billed monthly.
Idle Connection Timeouts
To reduce strain on the Fly.io public proxy, idle TCP connections are closed automatically after 60 seconds. This limitation applies to all types of public services. Idle connection timeouts usually surface as ECONNRESET
errors on the client.
If you're connecting to a database on Fly.io -- like Redis or Postgres -- over the internet, ensure that your database client can handle reconnects cleanly. For example, the ioredis
Node.js client handles reconnects automatically.
Connection Handlers
Set the handlers
config setting in the services.ports
section of fly.toml
to specify which middleware applies to incoming TCP connections for each port you accept external connections on. Use these to convert TCP connections into something your application can handle.
Valid handler strings:
"tls"
: Convert TLS connection to unencrypted TCP"pg_tls"
: Handle TLS for PostgreSQL connections"http"
: Convert TCP connection to HTTP"proxy_proto"
: Wrap TCP connection in PROXY protocol
TLS
The TLS
middleware terminates TLS using Fly.io-managed application certificates, then forwards a plaintext connection to the application process. This is useful for running TCP services and offloading TLS
to the Fly Proxy.
For performance purposes, the Fly Proxy will terminate TLS on the host a client connects to, and then forward the connection to the nearest available application instance.
Note: the TLS
handler includes ALPN negotiation for HTTP/2. When possible, applications will connect to these kinds of Fly.io services using HTTP/2, and we will forward an unencrypted HTTP/2 connection (h2c
) to the application process.
HTTP
Many applications have limited HTTP support, the HTTP
middleware normalizes HTTP connections and sends HTTP 1.1 requests to the application process. This is roughly how nginx
and other reverse proxies work, and allows your application to globally accept modern HTTP protocols (like HTTP/2) without extra complexity.
If your application stack has good HTTP/2 support (like Go), you will get better performance accepting TCP connections directly, and using the TLS handler to terminate SSL. Your application does need to understand h2c
for this to work, however.
The HTTP handler adds a number of standard HTTP headers to requests, and a few Fly.io-specific headers for convenience:
Header | Description |
---|---|
Fly-Client-IP | The IP address Fly.io accepted a connection from |
X-Forwarded-For | A comma separated list of proxy servers the request passed through. MDN has full documentation for this header |
X-Forwarded-Proto | Original client protocol, either http or https |
X-Forwarded-SSL | Indicates if client connected over SSL, either on or off |
X-Forwarded-Port | Original connection port, header may be set by client |
Fly-Forwarded-Port | Original connection port, always set by Fly.io |
Fly-Region | Original incoming connection region |
You can set a preference on HTTP requests for which region you would like to connect to:
Fly-Prefer-Region: region-code
TCP Pass Through
If you don't specify handlers, we just forward TCP to your application as is. This is useful if you want to handle TLS termination yourself, for example.
Proxy Protocol
The proxy_proto
handler adds information about the original connection, including client IP + port and server IP + port (from the client's perspective). Most applications need additional logic to accept the proxy protocol, either using a prebuilt library or implementing the proxy protocol directly.
Postgres Connections
The pg_tls
handler manages Postgres connections, so that you can expose your Postgres databases over the proxy securely. Some interesting notes by @glebarez on why standard TLS termination won't work for Postgres: https://github.com/glebarez/pgssl#readme
HTTP to HTTPS Redirects
The force_https
configuration option automatically redirects HTTP to HTTPS. When enabled, all HTTP requests return a redirect response with a 301
status code. This option can only be set on HTTP handlers - deployments will fail if set on other handlers.