Claude Code for Fly Machines — Workflow Guide
The Setup
You are deploying applications on Fly.io using Machines, the lightweight VM platform that starts in milliseconds and runs your Docker containers globally. Fly Machines provide fine-grained control over compute placement, auto-scaling, and geographic distribution. Claude Code can write Fly.io configurations, but it generates Heroku or AWS deployment patterns.
What Claude Code Gets Wrong By Default
-
Creates Heroku Procfiles. Claude writes
web: node server.jsHeroku format. Fly.io usesfly.tomlfor configuration and Docker for builds — no Procfile needed. -
Uses AWS-style load balancer config. Claude configures ALB target groups. Fly.io handles load balancing automatically through its Anycast network — requests route to the nearest Machine based on the fly-replay header and geographic proximity.
-
Ignores Fly’s multi-region capability. Claude deploys to a single region. Fly Machines can run in 30+ regions simultaneously, placing your app near users worldwide with
fly machine clone --region nrt. -
Sets up external databases. Claude provisions RDS or PlanetScale. Fly provides built-in Postgres (
fly postgres create), LiteFS for distributed SQLite, and Tigris for S3-compatible object storage.
The CLAUDE.md Configuration
# Fly.io Machines Project
## Platform
- Deploy: Fly.io (lightweight VMs, global distribution)
- Config: fly.toml at project root
- CLI: fly (flyctl)
- Build: Docker (Dockerfile required)
## Fly.io Rules
- Deploy: fly deploy (builds Docker, pushes, starts Machines)
- Config: fly.toml for app settings, scaling, services
- Regions: fly regions add nrt lhr iad (multi-region)
- Scale: fly scale count 3 (multiple Machines)
- Secrets: fly secrets set DATABASE_URL=... (encrypted)
- Postgres: fly postgres create (managed, Fly-internal)
- Volumes: fly volumes create data --region iad --size 10
- Health checks: configured in fly.toml [[services.checks]]
## Conventions
- Dockerfile at project root (multi-stage for production)
- fly.toml committed to version control
- Secrets via fly secrets set, never in fly.toml
- Health check endpoint: /health or /up
- Internal services: .internal hostname for service-to-service
- Volumes for persistent data (databases, uploads)
- Use fly proxy for local database access
Workflow Example
You want to deploy a Node.js API with a managed Postgres database. Prompt Claude Code:
“Deploy this Express app to Fly.io with a managed Postgres database. Configure auto-scaling from 1 to 5 machines, add health checks, and set up the DATABASE_URL secret.”
Claude Code should create/verify the Dockerfile, configure fly.toml with [[services]] for HTTP, [[services.checks]] for health, [processes] for the app, run fly postgres create for the database, attach it with fly postgres attach, and configure auto-scaling with fly autoscale set min=1 max=5.
Common Pitfalls
-
Volume attachment across regions. Claude creates a volume in one region and tries to access it from Machines in other regions. Fly volumes are region-specific — a Machine can only mount volumes in the same region. Create volumes in each region where Machines run.
-
Missing internal DNS for multi-service. Claude connects between Fly apps using public URLs. Fly apps communicate internally via
appname.internalDNS over the private WireGuard network. Use internal addresses for service-to-service calls to avoid public network latency and egress. -
Fly Postgres is not managed RDS. Claude treats Fly Postgres like a fully managed service. Fly Postgres runs as a regular Fly app — you are responsible for backups, monitoring, and failover configuration. Set up
fly postgres backupand monitoring.