Brain reads configuration from process.env via @nestjs/config and a few direct lookups
(apps/brain/src/main.ts, apps/brain/src/common/runtime/stage.ts,
apps/brain/src/config/queue.config.ts). The BRAIN_*-prefixed variables in
.env.example are mapped onto the unprefixed names that the service actually reads
in docker-compose.yml. On Railway the same mapping happens via the service env config.
The canonical .env.example is at the repo root.
Stage and runtime
| Var | Required | Default | Source | Purpose |
|---|
BRAIN_STAGE | yes | development | .env.example, Railway | Resolved by getBrainStage() to production/staging/sandbox/development; PR previews containing -pr- map to sandbox. |
RAILWAY_ENVIRONMENT_NAME | platform | — | Railway runtime | Stage fallback when BRAIN_STAGE is unset. |
NODE_ENV | yes | production (compose) | docker-compose.yml, Railway | Final stage fallback. |
PORT | yes | 3000 | docker-compose.yml, main.ts | HTTP listen port; main.ts binds to IPv6 dual-stack ::. |
BRAIN_HTTP_PORT | dev | 3000 | .env.example | Local override only; service still reads PORT. |
Database (Prisma / PostgreSQL)
| Var | Required | Default | Source | Purpose |
|---|
DATABASE_URL | yes | — | prisma/schema.prisma, Railway | Pooled Prisma connection (Neon pgbouncer in prod). |
DIRECT_DATABASE_URL | yes (migrations) | falls back to DATABASE_URL | prisma/schema.prisma, docker-compose.yml | Direct (non-pooled) connection for prisma migrate deploy. |
BRAIN_DATABASE_URL | dev | — | .env.example | Mapped onto DATABASE_URL in compose. |
BRAIN_DIRECT_DATABASE_URL | optional locally, required with pooled Neon | falls back to BRAIN_DATABASE_URL | .env.example, docker-compose.yml | Mapped onto DIRECT_DATABASE_URL in compose. Set it when BRAIN_DATABASE_URL uses a pooler. |
Brain owns the fennec schema in the shared sirloin DB. See Data Model.
Queue (Redis / BullMQ)
| Var | Required | Default | Source | Purpose |
|---|
REDIS_HOST | yes | localhost | apps/brain/src/config/queue.config.ts | BullMQ connection host. |
REDIS_PORT | yes | 6379 | queue.config.ts | BullMQ connection port. |
REDIS_PASSWORD | optional | — | queue.config.ts | Auth where Redis is password-protected. |
family: 0 is set so dual-stack IPv4/IPv6 resolution works on Railway’s private network.
Auth (Clerk + API key)
| Var | Required | Default | Source | Purpose |
|---|
CLERK_PUBLISHABLE_KEY | yes | — | Clerk dashboard | Frontend Clerk identifier. |
CLERK_SECRET_KEY | yes | — | Clerk dashboard | Server-side token verification (@clerk/backend). |
AUTHORIZED_KEYS | yes | — | Generated; rotated per-stage | Comma-separated list of API keys accepted by @ApiKeyRoute() endpoints. See Auth Model “API key scopes”. |
BRAIN_CLERK_PUBLISHABLE_KEY / BRAIN_CLERK_SECRET_KEY / BRAIN_AUTHORIZED_KEYS | dev | — | .env.example | Mapped onto the unprefixed names by compose. |
FRONTEND_URL | yes | — | app.module.ts | Used for CORS / redirect validation. |
BRAIN_API_PUBLIC_URL | optional | http://localhost:9970 | .env.example | Local docs; clients consume the Railway URL in non-dev. |
Storage (S3 / R2)
| Var | Required | Default | Purpose |
|---|
S3_BUCKET_NAME | yes | — | Tenderloin bucket (R2) for media. |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY | yes | — | R2 credentials. |
AWS_S3_APIREGION | yes | auto | R2 region. |
AWS_S3_APIURL | yes | — | R2 endpoint (e.g. https://<accountid>.r2.cloudflarestorage.com). |
BRAIN_PUBLIC_BUCKET_URL | yes | — | Public CDN domain for downloads. |
Service dependencies
| Var | Required | Default | Purpose |
|---|
ROUND_HOST | yes | round:8080 | gRPC target for round (embeddings, face). |
BRAIN_ROUND_HOST | dev | round:8080 | Mapped onto ROUND_HOST. |
AI / generation providers
All optional individually but at least the providers used by enabled flows must be set.
| Var | Provider |
|---|
BRAIN_RUNPOD_TOKEN | RunPod inference. |
BRAIN_FAL_AI_KEY, BRAIN_FAL_ADMIN_KEY | FAL AI. |
BRAIN_GOOGLE_AI_API_KEY | Google AI Studio. |
BRAIN_GOOGLE_CLOUD_SERVICE_ACCOUNT_KEY | Google Vertex AI service account JSON. |
BRAIN_GOOGLE_CLOUD_PROJECT_ID, BRAIN_GOOGLE_CLOUD_LOCATION | Vertex region. |
BRAIN_KLING_AI_API_KEY, BRAIN_KLING_AI_API_SECRET | Kling AI. |
BRAIN_WAVESPEED_API_KEY | Wavespeed video. |
BRAIN_ATLASCLOUD_API_KEY | AtlasCloud inference (Seedream, Seedance). |
BRAIN_HF_TOKEN | Hugging Face. |
BRAIN_XAI_API_KEY | xAI / Grok. |
BRAIN_OPENROUTER_API_KEY | OpenRouter (language extraction). |
Moderation
| Var | Purpose |
|---|
BRAIN_HIVE_CELEBRITY_RECOGNITION_API_KEY | Hive celebrity check. |
BRAIN_HIVE_VISUAL_MODERATION_API_KEY | Hive visual moderation. |
BRAIN_HIVE_DEMOGRAPHICS_API_KEY | Hive demographics. |
VI Generator
| Var | Purpose |
|---|
BRAIN_VI_GENERATOR_URL | Outbound base URL. |
BRAIN_VI_GENERATOR_API_KEY | API key. |
BRAIN_VI_GENERATOR_CF_ACCESS_CLIENT_ID / _SECRET | Cloudflare Access service token. |
Image signature secrets
| Var | Purpose |
|---|
BRAIN_GEMINI_IMAGE_SIGNATURE_KEY | HMAC for signed Gemini outputs. |
BRAIN_FENNEC_IMAGE_SIGNATURE_KEY | HMAC for signed fennec image URLs. |
Observability
| Var | Required | Purpose |
|---|
BRAIN_SENTRY_AUTH_TOKEN | build-time | Used by Dockerfile to upload sourcemaps. |
BRAIN_SENTRY_RELEASE | build-time | Release tag; defaults to RAILWAY_GIT_COMMIT_SHA. |
BRAIN_OTEL_URL | yes (prod) | Axiom OTEL endpoint. |
BRAIN_OTEL_METRICS_HEADERS | yes (prod) | authorization=Bearer xaat-...,x-axiom-dataset=.... |
BRAIN_OTEL_TRACES_LOGS_HEADERS | yes (prod) | Same shape, traces+logs dataset. |
See Observability.
TODO
- TODO(@pawel): Validate which of the AI provider keys are required per stage vs. lazily resolved at first use.
- TODO(@pawel): Confirm
family: 0 Redis behavior on Upstash vs. self-hosted Redis (set in apps/brain/src/config/queue.config.ts:11).