Deploying with Fly.io
Global VM-based app deployment with Docker, scale to multiple regions, and Postgres/SQLite.
PlatformsIntermediate
Why
Fly.io deploys Docker containers to VMs in 30+ regions with global anycast networking. It supports Postgres (HA), SQLite (litestream), and scale-to-zero, making it ideal for full-stack apps near users.
When
Use Fly.io for full-stack apps needing multi-region, Docker, and a real DB. Avoid for serverless — use Cloudflare/Vercel.
How
1. Launch — fly launch creates Dockerfile + fly.toml
2. Deploy — fly deploy, builds and deploys to all regions
3. Scale — fly scale count 3, runs 3 VMs
4. Regions — fly regions add sjc,ams for multi-region
5. Postgres — fly postgres create, HA across regions
6. SQLite — fly volume create, litestream for replication
7. Secrets — fly secrets set KEY=VALUE
Example
# fly.toml
app = "myapp"
primary_region = "iad"
[build]
[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
# Deploy
fly launch # initial setup
fly deploy # deploy to primary region
fly scale count 3 # 3 VMs
fly regions add sjc ams # multi-region
# Postgres
fly postgres create --name mypg --region iad --initial-cluster-size 3
Common Problems
- ⚠App not reachable — internal_port in fly.toml doesn't match app's listen port
- ⚠Volume data lost on deploy — volumes are per-region, deploy to wrong region loses data
- ⚠Configuration drift between environments — use infrastructure-as-code (Terraform/Pulumi) to keep dev/staging/prod identical
Best Practices
- ✓Set auto_stop_machines + auto_start_machines — scale to zero when idle, save cost
- ✓Use fly postgres for HA Postgres — managed, backups, and multi-region replication
- ✓Set up health checks and graceful shutdown — handle SIGTERM to drain in-flight requests before exit