CapyDB Docs
GuidesImports & Migrations

Migrate from Fly.io

Move a Fly Postgres database into CapyDB.

Get the source connection string

Fly Postgres (the unmanaged fly pg flavor) lives on a private 6PN network by default — there is no public URL to copy. Two workable options:

Option A: temporary public proxy

fly proxy 5432 -a your-pg-app

…makes the database reachable at localhost:5432 on your machine, which does not help a hosted importer. To expose it publicly for the import window, allocate a public IP and add a public service for 5432 (fly ips allocate-v4 -a your-pg-app plus a services section / fly pg config), then:

postgres://postgres:password@your-pg-app.fly.dev:5432/dbname

Remove the public service and release the IP when done.

Option B: dump and restore through a preview

If exposing the database is not acceptable, do the copy yourself: fly proxy + pg_dump locally, then pg_restore over the CapyDB direct URL. You lose the managed import's preflight, but the post-import checklist still applies.

The password is whatever fly postgres create printed at provision time; fly ssh console -a your-pg-app and the OPERATOR_PASSWORD secret can recover it.

Fly-specific caveats

  • Managed Postgres (MPG) instances expose connection strings in the Fly dashboard; those are reachable per Fly's networking settings and can be used directly if public.
  • Unmanaged Fly Postgres is just Postgres on Machines — Fly themselves say it is not a managed service. Whatever HA setup you built (repmgr/Stolon era apps) does not matter for the copy; point at the primary.
  • Version: check SELECT version(); — older Fly PG apps run older majors, which import forward to 17 fine.

Preflight

With a temporarily public source:

capydb import preflight --source-url "postgres://postgres:password@your-pg-app.fly.dev:5432/dbname"

Import

Pause writers, then:

capydb import --source-url "postgres://postgres:password@your-pg-app.fly.dev:5432/dbname" --recreate --wait

After the import

  1. Spot-check sequences.
  2. \dx for extensions.
  3. ANALYZE;
  4. Cut over DATABASE_URL in your Fly app secrets (fly secrets set DATABASE_URL=...), deploy, watch Observability — and tear down the public exposure on the old database.