Skip to content

Deploy to Fly.io

Fly.io runs the Docker image directly. You deploy the container from a scaffolded project (npm create flaghoist@latest team-flags -- --platform container) or a copy of examples/docker, and back it with Postgres. About ten minutes.

Install flyctl, then:

Terminal window
fly auth login

From the container project (it has the Dockerfile), scaffolded with the CLI or copied from examples/docker:

Terminal window
fly launch --no-deploy

Answer the prompts for a name and region. fly launch detects the Dockerfile and writes a fly.toml. Make sure its [http_service] block has internal_port = 8080, the port the container listens on.

Terminal window
fly postgres create # creates a Postgres app
fly postgres attach <pg-app-name> # sets DATABASE_URL on your app

Fly’s internal Postgres is reached over the private network without TLS, so append ?sslmode=disable to the connection string it set, otherwise the container tries to negotiate SSL and the connection fails:

Terminal window
fly secrets set DATABASE_URL="postgres://…internal:5432/<db>?sslmode=disable"

Any managed Postgres works too (Supabase, Neon), using its own URL. Those require TLS, which the container enables by default, so no sslmode is needed.

Terminal window
fly secrets set FLAGS_STORAGE=postgres \
ADMIN_TOKEN="$(openssl rand -hex 32)" \
READ_API_KEY="$(openssl rand -hex 32)"
Terminal window
fly deploy

Fly gives you https://<app>.fly.dev.

Terminal window
curl https://<app>.fly.dev/health

Create a flag from the dashboard at https://<app>.fly.dev/admin (paste your ADMIN_TOKEN), then read it back:

Terminal window
curl -X POST https://<app>.fly.dev/ofrep/v1/evaluate/flags/new-checkout \
-H "x-api-key: $READ_API_KEY" -H "content-type: application/json" \
-d '{"context":{"targetingKey":"tester-1"}}'

Everything Docker-specific is in Deploy with Docker; Fly just runs that image.