Skip to content

Fly.io

Tested with: flyctl 0.3 · Fly Machines · PostgreSQL 17

  1. Store the connection string as a Fly secret (secrets are injected as environment variables and never logged).

    shell
    fly secrets set DATABASE_URL="postgresql://app:<password>@pg-7f3k.us-east.databasezy.com:5432/app?sslmode=verify-full"
  2. Give the app a stable egress address so the allow-list can be tight. Fly apps share egress IPs per host by default; allocate a dedicated IPv4 or use a static egress IP per Machine.

    shell
    fly ips allocate-v4 --app api-prod
    fly machine egress-ip allocate <machine-id> # static egress per Machine
    zb api PUT /v1/orgs/{org}/instances/pg-7f3k/network -d '{"allow_cidrs": ["203.0.113.42/32"]}' # replaces the list
  3. Run migrations as a release command against the direct endpoint, then deploy.

    fly.toml
    [deploy]
    release_command = "npx prisma migrate deploy"
    [env]
    PGSSLMODE = "verify-full"

Pick the Databasezy region closest to your primary Fly region (us-east for iad/ewr, eu-west for ams/lhr). Cross-region round trips dominate query latency; keep reads in the same region or use a read replica (Solo and above).

Machines are long-lived: use the driver’s pool (max: 10 per Machine) and the direct endpoint. Reserve the pooled endpoint for burst workloads with many small Machines.