# Configuration

> Every production setting, where it belongs, and whether users can see it.


## API values

Set these on Railway, Fly.io, or your own API runtime. Treat every value as secret unless the table says otherwise.

| Variable | Required value |
| --- | --- |
| `DATABASE_URL` | PostgreSQL URL for normal API traffic. For Supabase transaction mode, add `sslmode=require&default_query_exec_mode=simple_protocol`. |
| `MIGRATION_DATABASE_URL` | Session-pooler or direct PostgreSQL URL for migrations. Falls back to `DATABASE_URL`, but transaction pooling is not safe for the migration lock. |
| `REDIS_URL` | `redis://` or `rediss://` URL. |
| `DATA_ENCRYPTION_KEY` | Base64 encoding of exactly 32 random bytes. Back it up separately. |
| `DATA_ENCRYPTION_KEY_VERSION` | `1` for a new installation. |
| `DATA_ENCRYPTION_READ_KEYS` | Empty initially. Old `version:base64` entries during key rotation. |
| `CLERK_ISSUER` | Clerk HTTPS issuer origin, without a path. |
| `CLERK_JWKS_URL` | Clerk HTTPS JWKS URL, with its path. |
| `CLERK_ALLOWED_DASHBOARD_ORIGINS` | Comma-separated dashboard origins, with no paths or trailing slashes. |
| `WEBSOCKET_AUTHENTICATION_TIMEOUT` | `5s`. Allowed range: 1s to 30s. |
| `RELAY_PAIRING_GRANT_TTL` | `10m`. Allowed range: 1m to 30m. |
| `LOG_LEVEL` | `info`. Allowed: `debug`, `info`, `warn`, `error`. |
| `MEDIA_S3_ENDPOINT` | S3 HTTPS endpoint, including a provider base path when required, without a trailing slash. |
| `MEDIA_S3_BUCKET` | Existing private bucket name. |
| `MEDIA_S3_REGION` | Region reported by the storage provider. |
| `MEDIA_S3_ACCESS_KEY_ID` | Server-side S3 access key. |
| `MEDIA_S3_SECRET_ACCESS_KEY` | Server-side S3 secret key. |
| `MEDIA_S3_ADDRESSING_STYLE` | `path` for Supabase, R2, and MinIO; `virtual` for AWS S3. |
| `HTTP_ADDR` | `:8080` on Fly.io or self-managed hosts. Leave unset on Railway so its `PORT` wins. |
| `GIN_MODE` | `release`. |

`MEDIA_S3_COMPOSE_ENDPOINT`, `POSTGRES_*`, `REDIS_PORT`, and `API_PORT` are local Compose settings. Do not copy them to a cloud API service.

## Dashboard build values

| Variable | Visibility | Value |
| --- | --- | --- |
| `VITE_CLERK_PUBLISHABLE_KEY` | Public | Clerk production publishable key |
| `VITE_API_BASE_URL` | Public | Public HTTPS API origin, no path or trailing slash |

Vite embeds both values in browser JavaScript. A `VITE_` prefix never protects a secret.

## Relay build value

| Variable | Value |
| --- | --- |
| `COOP_RELAY_SERVER_URL` | Public HTTPS API origin used when building Relay |

## Provider-specific storage examples

| Provider | Endpoint | Addressing style |
| --- | --- | --- |
| Supabase Storage | `https://<project>.storage.supabase.co/storage/v1/s3` | `path` |
| Cloudflare R2 | `https://<account>.r2.cloudflarestorage.com` | `path` |
| AWS S3 | `https://s3.<region>.amazonaws.com` | `virtual` |
| MinIO | Provider-specific origin | `path` |

