# Deploy the API on Fly.io

> Launch the API from its checked-in Fly configuration and attach managed data services.


Choose Fly.io when your IT team is comfortable with a CLI-controlled deployment and wants explicit region and machine settings. Fly does not provide a repository deploy button equivalent to Vercel. Its supported setup path is `fly launch` followed by `fly deploy`.

## 1. Choose nearby services

Create PostgreSQL, Redis, and S3-compatible storage before launching the API. Keep the API, database, Redis, and bucket in nearby regions to reduce sync latency. If Supabase's direct database hostname is not reachable from your chosen network, use its shared session pooler.

## 2. Install and authenticate flyctl

Follow [Fly.io's flyctl installation guide](https://fly.io/docs/flyctl/install/), then sign in:

```sh
fly auth login
```

## 3. Create the application from the API directory

From the extracted Coop release folder:

```sh
cd apps/api
fly launch --no-deploy --copy-config
```

Choose an application name and primary region. The checked-in `fly.toml` supplies the Docker build, internal port, release migration, HTTPS service, and `/health` check. Review the generated application name before continuing.

## 4. Set non-secret configuration

The checked-in configuration sets `HTTP_ADDR=:8080`, `GIN_MODE=release`, `LOG_LEVEL=info`, `DATA_ENCRYPTION_KEY_VERSION=1`, `WEBSOCKET_AUTHENTICATION_TIMEOUT=5s`, and `RELAY_PAIRING_GRANT_TTL=10m`.

## 5. Run the no-write preflight locally

Create `coop-production.env` with every required API value from the [configuration reference](/reference/configuration/). Keep it outside Git. Build the same container image Fly will use and run its preflight entry point:

```sh
docker build --tag coop-api-preflight .
docker run --rm \
  --env-file coop-production.env \
  --entrypoint /preflight \
  coop-api-preflight --check-storage
```

This catches malformed database and migration URLs, Supabase transaction pooling on the migration URL, missing settings, and inaccessible storage before Fly creates an application Machine. It does not provision or write resources.

## 6. Set secrets

Put the remaining values in one local file that you do not commit, then import them with `fly secrets import`. The file must use `NAME=value` lines and include every required secret from the [configuration reference](/reference/configuration/).

```sh
fly secrets import < coop-production.env
```

Delete the local file after confirming that your company secret manager holds the authoritative values.

## 7. Deploy

```sh
fly deploy
```

Fly runs `/migrate up` as a release command before replacing the application Machine. If migration fails, the release stops.

## 8. Keep one Machine available

Coop maintains long-lived WebSocket connections to browsers and Relay. The checked-in service keeps at least one Machine running in the primary region. Do not configure the only Machine to stop when idle.

Verify `https://<app-name>.fly.dev/health` returns HTTP 200, then use that origin as `VITE_API_BASE_URL`.

Official references: [Fly Launch](https://fly.io/docs/launch/) and [release commands](https://fly.io/docs/reference/configuration/#run-one-off-commands-before-releasing-a-deployment).

