Documentation Index
Fetch the complete documentation index at: https://mintlify.com/arrozet/caret/llms.txt
Use this file to discover all available pages before exploring further.
Caret’s services are configured exclusively through environment variables — there are no checked-in configuration files that contain secrets or environment-specific values. At runtime, Docker Compose reads a single .env file from the repository root and injects the relevant variables into each container. When running services outside of Docker, the same file (or equivalent shell exports) is used directly.
Never commit your .env file to version control. It is already listed in .gitignore, but double-check before pushing. Exposed Supabase service role keys, JWT secrets, or LLM API keys can compromise your entire project and user data.
Creating Your .env File
Create a .env file at the repository root (the same directory as docker-compose.yml). Docker Compose automatically reads this file when you run docker compose up.
Minimum Working Configuration
The four variables below are the absolute minimum required to boot all services and connect to Supabase:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
OPENAI_API_KEY=sk-...
DATABASE_URL must point to your Supabase Cloud connection pooler — there is no local PostgreSQL instance in Caret’s stack. Use the Session mode pooler URL (port 6543) from your Supabase project’s database settings. Standard direct connection strings on port 5432 also work but are not recommended for pooled environments.
Full Variable Reference
Shared — Backend Services
These variables are consumed by most backend services and must be present in your .env. Check the per-service tables below for the exact subset each service uses.
| Variable | Required | Description |
|---|
DATABASE_URL | ✅ Yes | Supabase Cloud PostgreSQL connection string (pooler URL). Used by document-service, collab-service, and ai-service for all database access. |
SUPABASE_URL | ✅ Yes | Your Supabase project URL, e.g. https://abcdef.supabase.co. Used by all services that interact with Supabase Auth or the Supabase client. |
SUPABASE_ANON_KEY | ✅ Yes | The public anonymous key for your Supabase project. Safe to expose to the frontend, but still kept in .env for consistency. |
SUPABASE_SERVICE_ROLE_KEY | ✅ Yes | The secret service-role key for server-side Supabase operations. Never expose this to the frontend. |
SUPABASE_JWT_SECRET | ✅ Yes | The JWT secret used by Supabase to sign tokens. Required by the collab-service to validate WebSocket handshake JWTs. |
JWT_SECRET | ✅ Yes | Application-level JWT secret used by auth-service, document-service, and ai-service for token validation. |
API Gateway
The API Gateway (app/backend/api-gateway) is the single public HTTP entry point. It proxies traffic to internal services and enforces CORS and rate limits.
| Variable | Default | Required | Description |
|---|
PORT | 3000 | No | Port the gateway listens on. |
NODE_ENV | development | No | Node environment. Set to production in production deployments. |
ALLOWED_ORIGINS | http://localhost:5173 | ✅ Yes | Comma-separated list of allowed CORS origins. In production, set to https://caret.page. |
AUTH_SERVICE_URL | — | ✅ Yes | Internal URL of the auth service, e.g. http://auth-service:3001 in Docker. |
DOCUMENT_SERVICE_URL | — | ✅ Yes | Internal URL of the document service, e.g. http://document-service:3002 in Docker. |
AI_SERVICE_URL | — | ✅ Yes | Internal URL of the AI service, e.g. http://ai-service:8000 in Docker. |
Auth Service
The auth service (app/backend/auth-service) is currently runtime-minimal, providing health, OpenAPI documentation, and shared auth middleware scaffolding.
| Variable | Default | Required | Description |
|---|
PORT | 3001 | No | Port the service listens on. |
NODE_ENV | development | No | Node environment. |
DATABASE_URL | — | ✅ Yes | Shared Supabase connection string (see above). |
SUPABASE_URL | — | ✅ Yes | Shared Supabase project URL (see above). |
SUPABASE_ANON_KEY | — | ✅ Yes | Shared Supabase anonymous key (see above). |
SUPABASE_SERVICE_ROLE_KEY | — | ✅ Yes | Shared Supabase service role key (see above). |
JWT_SECRET | — | ✅ Yes | Shared JWT signing secret (see above). |
Document Service
The document service (app/backend/document-service) handles all workspace, folder, document, sharing, and versioning CRUD operations.
| Variable | Default | Required | Description |
|---|
PORT | 3002 | No | Port the service listens on. |
NODE_ENV | development | No | Node environment. |
DATABASE_URL | — | ✅ Yes | Shared Supabase connection string (see above). |
SUPABASE_URL | — | ✅ Yes | Shared Supabase project URL (see above). |
SUPABASE_ANON_KEY | — | ✅ Yes | Shared Supabase anonymous key (see above). |
SUPABASE_SERVICE_ROLE_KEY | — | ✅ Yes | Shared Supabase service role key (see above). |
JWT_SECRET | — | ✅ Yes | Shared JWT signing secret (see above). |
Collab Service
The collab service (app/backend/collab-service) manages real-time Y.js document synchronisation over WebSocket. It uses SUPABASE_JWT_SECRET (not JWT_SECRET) to validate the token passed in the WebSocket handshake query string.
| Variable | Default | Required | Description |
|---|
PORT | 3003 | No | Port the WebSocket server listens on. |
NODE_ENV | development | No | Node environment. |
DATABASE_URL | — | ✅ Yes | Shared Supabase connection string used to persist Y.js updates and snapshots. |
SUPABASE_URL | — | ✅ Yes | Shared Supabase project URL (see above). |
SUPABASE_ANON_KEY | — | ✅ Yes | Shared Supabase anonymous key (see above). |
SUPABASE_JWT_SECRET | — | ✅ Yes | Used specifically by the collab service to verify Supabase-issued JWTs on WebSocket connections. |
AI Service
The AI service (app/backend/ai-service) is a FastAPI application that provides AI chat, suggestions, SSE streaming, and RAG-powered embeddings. It uses APP_ENV instead of NODE_ENV.
| Variable | Default | Required | Description |
|---|
APP_ENV | development | No | Application environment. Set to production in production. |
PORT | 8000 | No | Port FastAPI/Uvicorn listens on. |
DATABASE_URL | — | ✅ Yes | Shared Supabase connection string (see above). |
SUPABASE_URL | — | ✅ Yes | Shared Supabase project URL (see above). |
SUPABASE_ANON_KEY | — | ✅ Yes | Shared Supabase anonymous key (see above). |
JWT_SECRET | — | ✅ Yes | Shared JWT signing secret (see above). |
OPENAI_API_KEY | — | ✅ Yes | OpenAI API key for GPT model access. Required for the default AI provider. |
ANTHROPIC_API_KEY | — | No | Anthropic API key. Required only if Claude models are selected in the model catalog. |
OPENROUTER_API_KEY | — | No | OpenRouter API key for routing requests across multiple providers. |
OPENROUTER_MODEL | deepseek/deepseek-v4-flash | No | Default model to use when routing through OpenRouter. |
PYTHONPATH | /app | No | Set automatically in Docker to ensure the src package is importable by Alembic and ad-hoc commands. |
Frontend
Frontend environment variables are prefixed with VITE_ so Vite injects them at build time. They are safe to expose in browser bundles — never put server secrets in VITE_* variables.
| Variable | Required | Description |
|---|
VITE_SUPABASE_URL | ✅ Yes | Supabase project URL. Maps to SUPABASE_URL in Docker build args. |
VITE_SUPABASE_ANON_KEY | ✅ Yes | Supabase anonymous key. Maps to SUPABASE_ANON_KEY in Docker build args. |
VITE_API_URL | ✅ Yes | Full base URL for API Gateway HTTP calls, e.g. http://localhost:3000/api/v1 locally or https://api.caret.page/api/v1 in production. |
VITE_COLLAB_WS_URL | ✅ Yes | WebSocket base URL for the collab service, e.g. ws://localhost:3003 locally or wss://ws.caret.page in production. The frontend appends /document/{doc_id} at connection time. |
Example: Full .env File
The following example covers all variables used in local development. Replace placeholder values with your own credentials:
# ── Supabase ──────────────────────────────────────────
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
SUPABASE_JWT_SECRET=your-supabase-jwt-secret
DATABASE_URL=postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres
# ── Application JWT ───────────────────────────────────
JWT_SECRET=a-long-random-secret-string
# ── AI Providers ──────────────────────────────────────
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-... # optional
OPENROUTER_API_KEY=sk-or-... # optional
OPENROUTER_MODEL=deepseek/deepseek-v4-flash # optional
Frontend VITE_* variables are injected automatically by Docker Compose from the shared values above. When running the frontend outside Docker, add the following to your .env (or a separate app/frontend/.env.local):
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
VITE_API_URL=http://localhost:3000/api/v1
VITE_COLLAB_WS_URL=ws://localhost:3003