Fly.io
Overview
Fly.io deploys applications to Firecracker microVMs across 30+ edge regions worldwide, providing sub-50ms latency to users. It supports scale-to-zero machines, persistent NVMe volumes, LiteFS for multi-region SQLite replication, and private WireGuard networking between services.
Instructions
- When deploying applications, use
fly launch to auto-detect the framework and generate a Dockerfile, then fly deploy for zero-downtime rolling updates with health checks.
- When configuring scaling, use
auto_stop_machines and auto_start_machines in fly.toml to scale to zero when idle and wake on incoming requests, and set machine sizing appropriate to the workload.
- When managing multi-region deployments, use
fly scale count --region to distribute machines, fly-replay header to route writes to the primary region, and LiteFS for SQLite read replicas.
- When handling persistent data, attach volumes for durable storage (machines are ephemeral), use LiteFS for multi-region SQLite, or Tigris for S3-compatible object storage.
- When connecting services, use
.internal DNS for private service-to-service communication over the WireGuard mesh and never expose internal services to the public internet.
- When managing secrets, use
fly secrets set KEY=value for encrypted secret storage accessible as environment variables.
- When troubleshooting, use
fly logs for real-time streaming, fly ssh console to access running machines, and fly proxy to tunnel to internal services.
Examples
Example 1: Deploy a multi-region web application
User request: "Deploy my app globally with Fly.io in US, Europe, and Asia"
Actions:
- Initialize with
fly launch and configure Dockerfile
- Deploy machines to three regions:
fly scale count 2 --region iad,cdg,nrt
- Set up LiteFS for SQLite replication across regions
- Configure
fly-replay header for write routing to the primary region
Output: A globally distributed app with read replicas in three regions and automatic write routing.
Example 2: Configure a cost-efficient staging environment
User request: "Set up a Fly.io staging environment that scales to zero when not in use"
Actions:
- Create a staging app with
fly launch
- Configure
auto_stop_machines = "stop" and auto_start_machines = true in fly.toml
- Attach a volume for persistent database storage
- Set health checks with appropriate timeouts for routing
Output: A staging environment that stops idle machines and wakes in sub-second on the next request.
Example 3: Canary deployment with auto-rollback
User request: "Deploy my app to Fly.io but test on one machine first. If the health check fails, roll back."
Actions:
- Deploy with
--strategy canary to spin up a single new machine
- Health check the canary machine at the app's health endpoint
- If healthy, promote with
fly deploy --strategy rolling to replace all machines
- If unhealthy, rollback with
fly releases rollback
#!/bin/bash
# deploy-canary.sh — Fly.io canary deployment with auto-rollback
set -euo pipefail
APP="${1:?Usage: deploy-canary.sh <app-name>}"
HEALTH_PATH="${2:-/api/health}"
echo "🐤 Deploying canary..."
fly deploy --app "$APP" --strategy canary --wait-timeout 120
HEALTH_URL="https://${APP}.fly.dev${HEALTH_PATH}"
HEALTHY=false
DEADLINE=$((SECONDS + 60))
while [ $SECONDS -lt $DEADLINE ]; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" || true)
[ "$STATUS" = "200" ] && HEALTHY=true && break
sleep 3
done
if [ "$HEALTHY" = true ]; then
echo "✅ Canary healthy! Promoting..."
fly deploy --app "$APP" --strategy rolling
echo "🎉 Production deploy complete"
else
echo "❌ Canary failed! Rolling back..."
fly releases rollback --app "$APP"
echo "⏪ Rolled back"
exit 1
fi
Guidelines
- Use
auto_stop_machines = "stop" for dev/staging to save costs; machines stop after idle timeout.
- Keep
auto_start_machines = true so machines wake on incoming requests with sub-second cold start.
- Use
.internal DNS for service-to-service calls; never expose internal services publicly.
- Store persistent data on volumes, not the machine filesystem, since machines are ephemeral.
- Use LiteFS for SQLite apps needing multi-region reads; it is simpler than PostgreSQL replication.
- Set health checks with realistic timeouts; Fly Proxy uses them for routing, not just monitoring.
- Use
fly-replay header for write operations in multi-region setups to route to the primary region.
1---2name: fly-io3description: Fly.io4---5# Fly.io67## Overview89Fly.io deploys applications to Firecracker microVMs across 30+ edge regions worldwide, providing sub-50ms latency to users. It supports scale-to-zero machines, persistent NVMe volumes, LiteFS for multi-region SQLite replication, and private WireGuard networking between services.1011## Instructions1213- When deploying applications, use `fly launch` to auto-detect the framework and generate a Dockerfile, then `fly deploy` for zero-downtime rolling updates with health checks.14- When configuring scaling, use `auto_stop_machines` and `auto_start_machines` in `fly.toml` to scale to zero when idle and wake on incoming requests, and set machine sizing appropriate to the workload.15- When managing multi-region deployments, use `fly scale count --region` to distribute machines, `fly-replay` header to route writes to the primary region, and LiteFS for SQLite read replicas.16- When handling persistent data, attach volumes for durable storage (machines are ephemeral), use LiteFS for multi-region SQLite, or Tigris for S3-compatible object storage.17- When connecting services, use `.internal` DNS for private service-to-service communication over the WireGuard mesh and never expose internal services to the public internet.18- When managing secrets, use `fly secrets set KEY=value` for encrypted secret storage accessible as environment variables.19- When troubleshooting, use `fly logs` for real-time streaming, `fly ssh console` to access running machines, and `fly proxy` to tunnel to internal services.2021## Examples2223### Example 1: Deploy a multi-region web application2425**User request:** "Deploy my app globally with Fly.io in US, Europe, and Asia"2627**Actions:**281. Initialize with `fly launch` and configure Dockerfile292. Deploy machines to three regions: `fly scale count 2 --region iad,cdg,nrt`303. Set up LiteFS for SQLite replication across regions314. Configure `fly-replay` header for write routing to the primary region3233**Output:** A globally distributed app with read replicas in three regions and automatic write routing.3435### Example 2: Configure a cost-efficient staging environment3637**User request:** "Set up a Fly.io staging environment that scales to zero when not in use"3839**Actions:**401. Create a staging app with `fly launch`412. Configure `auto_stop_machines = "stop"` and `auto_start_machines = true` in `fly.toml`423. Attach a volume for persistent database storage434. Set health checks with appropriate timeouts for routing4445**Output:** A staging environment that stops idle machines and wakes in sub-second on the next request.4647### Example 3: Canary deployment with auto-rollback4849**User request:** "Deploy my app to Fly.io but test on one machine first. If the health check fails, roll back."5051**Actions:**521. Deploy with `--strategy canary` to spin up a single new machine532. Health check the canary machine at the app's health endpoint543. If healthy, promote with `fly deploy --strategy rolling` to replace all machines554. If unhealthy, rollback with `fly releases rollback`5657```bash58#!/bin/bash59# deploy-canary.sh — Fly.io canary deployment with auto-rollback60set -euo pipefail6162APP="${1:?Usage: deploy-canary.sh <app-name>}"63HEALTH_PATH="${2:-/api/health}"6465echo "🐤 Deploying canary..."66fly deploy --app "$APP" --strategy canary --wait-timeout 1206768HEALTH_URL="https://${APP}.fly.dev${HEALTH_PATH}"69HEALTHY=false70DEADLINE=$((SECONDS + 60))7172while [ $SECONDS -lt $DEADLINE ]; do73 STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$HEALTH_URL" || true)74 [ "$STATUS" = "200" ] && HEALTHY=true && break75 sleep 376done7778if [ "$HEALTHY" = true ]; then79 echo "✅ Canary healthy! Promoting..."80 fly deploy --app "$APP" --strategy rolling81 echo "🎉 Production deploy complete"82else83 echo "❌ Canary failed! Rolling back..."84 fly releases rollback --app "$APP"85 echo "⏪ Rolled back"86 exit 187fi88```8990## Guidelines9192- Use `auto_stop_machines = "stop"` for dev/staging to save costs; machines stop after idle timeout.93- Keep `auto_start_machines = true` so machines wake on incoming requests with sub-second cold start.94- Use `.internal` DNS for service-to-service calls; never expose internal services publicly.95- Store persistent data on volumes, not the machine filesystem, since machines are ephemeral.96- Use LiteFS for SQLite apps needing multi-region reads; it is simpler than PostgreSQL replication.97- Set health checks with realistic timeouts; Fly Proxy uses them for routing, not just monitoring.98- Use `fly-replay` header for write operations in multi-region setups to route to the primary region.