Deploy to Fly.io
Fly.io deploys Docker containers to lightweight Firecracker VMs near your users. The free tier auto-scales to zero when idle, which makes it the cheapest “running production” deploy for low-traffic apps. Fly doesn’t host MongoDB itself — pair with Atlas, or run a Mongo container on a separate internal-only Fly app.
Quick reference
Section titled “Quick reference”| Cost (small app) | $0-5/mo (autostops when idle) + Atlas |
| Managed Mongo? | No — external (Atlas recommended) |
| Cold start? | ~1s wake from autostop |
| TLS | Automatic on *.fly.dev + custom domains |
| Multi-region | Yes (one of Fly’s strengths) |
Prerequisites
Section titled “Prerequisites”flyctlinstalled (brew install flyctlon macOS).- A Fly account (
fly auth signup/fly auth login). - A MongoDB Atlas cluster (or another reachable Mongo).
Deploy
Section titled “Deploy”-
Initialise.
Terminal window cd your-davepi-projectfly launchfly launchauto-detects the Node project, generates afly.toml, and offers to deploy. Accept the defaults; the first deploy will fail because env vars aren’t set yet — that’s fine. -
Set secrets.
Terminal window fly secrets set \MONGO_URI='mongodb+srv://user:pass@cluster.mongodb.net/davepi' \TOKEN_KEY="$(node -e 'console.log(require(\"crypto\").randomBytes(48).toString(\"hex\"))')" \CORS_ORIGINS='https://your-frontend.example.com' -
Edit
fly.toml. PinPORTand the health check:[env]NODE_ENV = "production"PORT = "8080"[http_service]internal_port = 8080force_https = trueauto_stop_machines = trueauto_start_machines = truemin_machines_running = 0 # set to 1 to keep one warm[[http_service.checks]]method = "get"path = "/healthz"interval = "30s"timeout = "5s" -
Deploy.
Terminal window fly deploy --remote-onlyThe deploy logs show the build + boot. When
/healthzpasses, traffic switches. App URL ishttps://<app-name>.fly.dev. -
Verify.
Terminal window curl https://<app-name>.fly.dev/healthz
The repo’s shipped GitHub Actions deploy workflow
targets Fly.io by default — once FLY_API_TOKEN is set as a repo
secret, every push to main deploys automatically (gated behind
the production environment for manual approval).
Custom domain + TLS
Section titled “Custom domain + TLS”fly certs add api.example.com# DNS: CNAME api -> <app-name>.fly.dev (or A/AAAA records Fly suggests)fly certs show api.example.com # watches the cert provisionBackups
Section titled “Backups”Atlas free tier (M0) doesn’t include continuous backup; M10
does. For free tier, run mongodump from a Fly scheduled
machine (fly machine run with --schedule) and upload to a
bucket.
Scaling
Section titled “Scaling”- Vertical:
fly scale vm shared-cpu-1x --memory 512→performance-1xetc. as needed. - Horizontal:
fly scale count 3— three machines load- balanced. Withauto_stop_machines = true, idle replicas stop automatically. - Multi-region:
fly regions add fra sinadds Frankfurt and Singapore. Fly’s anycast router sends traffic to the nearest live machine. Mongo (Atlas) becomes the latency- bottleneck for far-from-DB regions; pair with Atlas’s global cluster for matching geography.
Observability
Section titled “Observability”- Logs:
fly logsstreams stdout; Fly retains 5 days. Ship to external collectors via Fly’s Datadog / Better Stack integrations. - Metrics: Fly’s built-in Grafana provides VM-level metrics for
free. App-level metrics via
METRICS_ENABLED=true+ scrape through Fly’s internal network with Grafana Cloud.