> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qredence.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy with PostgreSQL

> Run Fleet RLM on PostgreSQL, migrate data from SQLite, expose the backend safely, and check health endpoints.

SQLite is fine for local use. Use PostgreSQL when you need durable, shared storage.

## Prerequisites

* A PostgreSQL database reachable from the Fleet host
* Fleet RLM installed with `uv sync --dev`
* Daytona and model credentials configured as in the [quickstart](/fleet-rlm/quickstart)

## Point Fleet at PostgreSQL

Set `FLEET_DATABASE_URL` in `.env`. Fleet normalizes `postgres://` and `postgresql://` URLs to the `postgresql+asyncpg://` driver.

```bash .env theme={null}
FLEET_DATABASE_URL=postgresql+asyncpg://fleet_app:<password>@<host>:5432/fleet?ssl=require
```

Apply migrations. Fleet never migrates on startup.

```bash theme={null}
uv run python scripts/database.py upgrade
```

`upgrade` also accepts `--database-url` to override `FLEET_DATABASE_URL` for one run, and `--env-file` to load a different environment file.

<Note>
  Managed deployments that use the Lakebase preflight must connect as the `fleet_app` role with TLS (`ssl=require`, `verify-ca`, or `verify-full`).
</Note>

## Database commands

`scripts/database.py` provides four operations.

| Command | Description |
| - | - |
| `upgrade` | Apply Alembic migrations to the configured database. |
| `import-sqlite` | Copy data from a file-backed SQLite database to PostgreSQL. |
| `preflight` | Run the sanitized Lakebase readiness preflight. |
| `certify-postgres` | Run the bounded PostgreSQL contention certification. |

### Move data from SQLite

`import-sqlite` reads both URLs from environment variables, creates a verified SQLite backup, and writes a receipt.

```bash theme={null}
uv run python scripts/database.py import-sqlite \
  --source-url-env FLEET_SQLITE_URL \
  --target-url-env FLEET_DATABASE_URL \
  --backup ./backups/fleet.sqlite3 \
  --receipt ./backups/import-receipt.json \
  --maintenance-window
```

The backup path must not exist yet. Stop Fleet before you import.

## Run the backend

```bash theme={null}
uv run fleet web
```

Or run the ASGI app directly:

```bash theme={null}
uv run fleet-rlm serve-api --host 127.0.0.1 --port 8000
```

<Warning>
  The Fleet API has no caller authentication. Fleet refuses to bind to a non-loopback host unless you pass `--allow-non-loopback-bind`. Only do that behind a trusted network boundary or an authenticating proxy. See [Security](/fleet-rlm/reference/security).
</Warning>

## Health checks

| Endpoint | Returns |
| - | - |
| `GET /health` | `200` with `status: "ok"`, the app name, and version whenever the process serves HTTP. |
| `GET /health/ready` | `200` with `status: "ready"` and `database` set to `ok` or `not_configured`. Returns `503` with `service_not_ready` until startup completes or when the database is unreachable. |

## Upgrade

1. Stop Fleet.
2. Pull the new release and run `uv sync --dev`.
3. Run `uv run python scripts/database.py upgrade`.
4. Rebuild Daytona snapshots if the release changes them. See [Sandbox execution](/fleet-rlm/concepts/sandbox-execution#snapshots).
5. Start Fleet.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.