Environment Variables
All CoreCube configuration is done through environment variables. They can be set in Docker Compose or directly in the shell for native Bun deployments.
Core settings
| Variable | Default | Required | Description |
|---|---|---|---|
PORT | 7400 | No | HTTP server port |
HOST | 0.0.0.0 | No | Network interface the HTTP server binds to |
DATA_DIR | /data (Docker) / ./data (native) | No | Persistent data directory for encryption key and uploaded files. The Docker image defaults to /data; native Bun deployments default to ./data |
CORECUBE_PUBLIC_URL | — | Recommended (prod) | Browser-reachable base URL of the deployment. Used to build citation file URLs and to enable secure session cookies when it starts with https:// |
MAX_UPLOAD_SIZE_MB | 50 | No | Maximum size in MB for a single library upload |
CUBE_ADMIN_EMAIL | admin@example.com | No | Initial admin user email. Skips the setup wizard if set together with CUBE_ADMIN_PASSWORD |
CUBE_ADMIN_PASSWORD | changeme123 | No | Initial admin user password. Must be changed after first login |
Database
CoreCube uses PostgreSQL + pgvector for durable application and knowledge data. Three connection strings separate bootstrap, request-path, and background-maintenance permissions.
| Variable | Default | Required | Description |
|---|---|---|---|
PGVECTOR_URL | — | Yes | PostgreSQL bootstrap/admin connection string for schema setup, grants, and migrations. |
PGVECTOR_APP_URL | — | Yes | PostgreSQL corecube_app connection string for request-path traffic under RLS. |
PGVECTOR_MAINTENANCE_URL | — | Yes | PostgreSQL corecube_maintenance connection string for background cleanup and repair jobs. |
PGVECTOR_POOL_MAX | 5 | No | Bootstrap/admin pool size per server instance. |
PGVECTOR_APP_POOL_MAX | 20 | No | App-role pool size per server instance. Query and retrieval traffic use this pool. |
PGVECTOR_MAINTENANCE_POOL_MAX | 5 | No | Maintenance-role pool size per server instance. Background cleanup and repair use this pool. |
Keep all three PostgreSQL URLs on separate roles. PGVECTOR_URL is for bootstrap/admin work such as
schema setup, grants, role password setup, and migrations. PGVECTOR_APP_URL is the normal app pool
and remains subject to RLS. PGVECTOR_MAINTENANCE_URL is a restricted operational role for safe
runtime cleanup work that needs cross-scope knowledge access, such as purging deleted knowledge data.
It is not used for ordinary API requests, DDL/schema changes, or pgvector extension administration.
Example:
PGVECTOR_URL=postgresql://corecube:strong-admin-password@pgvector:5432/corecube
PGVECTOR_APP_URL=postgresql://corecube_app:strong-app-password@pgvector:5432/corecube
PGVECTOR_MAINTENANCE_URL=postgresql://corecube_maintenance:strong-maintenance-password@pgvector:5432/corecube
Security
| Variable | Default | Required | Description |
|---|---|---|---|
ENCRYPTION_KEY | auto-generated | Recommended | AES-256-GCM encryption key for connector credentials, webhook secrets, and LLM API keys. A key is auto-generated on first startup and saved to DATA_DIR/encryption.key |
CITATION_TOKEN_SECRET | auto-generated (dev) | Yes (prod) | HMAC secret used to sign short-lived citation file URLs. Required when NODE_ENV=production — the server refuses to start without it. In development an ephemeral secret is generated per run, invalidating existing tokens on every restart. Generate with openssl rand -hex 32 |
CITATION_TOKEN_TTL_MINUTES | 15 | No | Lifetime of signed citation file URLs, in minutes. Clamped to the range 1–60 |
SESSION_MAX_LIFETIME_HOURS | 720 | No | Absolute session lifetime in hours. Default is 30 days. A session cannot live longer than this regardless of activity |
SESSION_IDLE_TIMEOUT_MINUTES | 60 | No | Idle timeout in minutes. A session expires after this period without a request |
CORS_ORIGINS | — (empty) | No | Comma-separated list of browser origins allowed to call the API. Empty by default, which rejects all cross-origin browser requests. Use * to allow any origin |
TRUSTED_PROXY_HOPS | 0 | No | Number of trusted reverse-proxy hops when resolving the client IP from X-Forwarded-For. 0 ignores forwarded headers and uses the direct socket address |
If the encryption key is lost, all connector credentials and LLM API keys become permanently unreadable and must be re-entered. Back up DATA_DIR/encryption.key separately.
Chat concurrency and provider limits
These limits protect the headless chat endpoint from unbounded concurrent work. They are enforced
per server process. Set a value to 0 to disable that specific guard.
| Variable | Default | Required | Description |
|---|---|---|---|
CC_CHAT_MAX_CONCURRENT | 100 | No | Total in-flight /v1/chat/completions requests per server instance. |
CC_CHAT_KEY_MAX_CONCURRENT | 100 | No | In-flight chat requests per API key. |
CC_CHAT_USER_MAX_CONCURRENT | 8 | No | In-flight chat requests per effective user. Service keys use the resolved X-Cube-User/body identity. |
CC_CHAT_PUBLIC_IP_MAX_CONCURRENT | 8 | No | In-flight public-key chat requests per source IP. |
CC_PROVIDER_RATE_LIMITS_ENABLED | true | No | Enforce model-catalog RPM/TPM limits before calling external chat, reranking, embedding, and OCR providers. |
Capacity planning
With the defaults on one server instance, CoreCube admits up to 100 simultaneous chat requests in total and up to 100 simultaneous chat requests per API key. For authenticated and service-key traffic, each effective user can hold up to 8 in-flight chat requests. For public-key traffic, each source IP can hold up to 8 in-flight chat requests.
That means 100 different users can each have one chat request in flight on a single instance, but
the 101st simultaneous request is rejected with 429 CONCURRENCY_LIMIT_EXCEEDED until one request
finishes. Raising these values or adding app replicas should be paired with matching provider,
pgvector, and executor capacity.
The chat concurrency counters are in-memory per server process. With three CoreCube app instances
and the default CC_CHAT_MAX_CONCURRENT=100, admission capacity is roughly 300 in-flight chat
requests before provider, database, or executor limits are considered. Use an external distributed
limiter if you need one hard global cap across replicas.
Object storage (s3storage)
CoreCube uses an S3-compatible object store (SeaweedFS, deployed as the s3storage service) for library uploads and attachments. The container exposes three internal services on fixed ports — S3 API (9000), Master UI/API (9333), and Filer UI/API (8888) — which are published on the host through the variables below.
| Variable | Default | Required | Description |
|---|---|---|---|
S3STORAGE_S3_HOST_PORT | 8400 | No | Host port mapped to the in-container S3 API (9000) |
S3STORAGE_MASTER_HOST_PORT | 8410 | No | Host port mapped to the SeaweedFS master UI/API (9333) |
S3STORAGE_FILER_HOST_PORT | 8420 | No | Host port mapped to the filer UI/API (8888) |
STORAGE_ENDPOINT | s3storage | No | Hostname CoreCube uses to reach the store on the internal Docker network |
STORAGE_PORT | 9000 | No | In-container S3 API port (do not change unless you replace the bundled service) |
STORAGE_USE_SSL | false | No | Set to true when reaching the store over HTTPS |
STORAGE_ACCESS_KEY | corecube | No | S3 access key |
STORAGE_SECRET_KEY | corecube_secret_key_change_me | Yes (prod) | S3 secret key — change before exposing the deployment |
STORAGE_REGION | eu-west-1 | No | S3 region label |
STORAGE_PUBLIC_ENDPOINT | http://localhost:8400 | Yes (prod) | Browser-reachable URL used to sign upload URLs. Tracks S3STORAGE_S3_HOST_PORT locally; set explicitly in production |
STORAGE_PRESIGN_EXPIRY_SECONDS | 900 | No | Lifetime of presigned upload URLs |
Default host ports follow the 84xx storage band: 8400 (S3 API), 8410 (master), 8420 (filer). The application uses the 74xx band and inference uses 94xx.
Inference services
CoreCube reaches a bundled inference service for embeddings and reranking on the 94xx port band. Point these at an alternative deployment if you run inference separately.
| Variable | Default | Required | Description |
|---|---|---|---|
INFERENCE_EMBEDDING_URL | http://localhost:9440 | No | Base URL of the embedding inference service |
INFERENCE_RERANKER_URL | http://localhost:9450 | No | Base URL of the reranker inference service |
Setup initialization precedence
Environment variables take priority over the setup wizard. The wizard only appears for configuration that env vars don't cover:
- If
CUBE_ADMIN_EMAIL+CUBE_ADMIN_PASSWORDare set → admin user auto-created, wizard user step skipped - If all PostgreSQL URLs are set → database auto-configured, wizard database step skipped
- If env vars cover all steps → wizard skipped entirely (headless bootstrap for CI/CD)
- If env vars are partial → wizard pre-fills configured values and skips completed steps
PostgreSQL role architecture
CoreCube uses one PostgreSQL database with separate roles for different runtime responsibilities:
| Role / URL | Purpose |
|---|---|
PGVECTOR_URL | Bootstrap/admin pool for schema setup, grants, role password setup, and migrations. |
PGVECTOR_APP_URL | Normal app pool using corecube_app; request-path code uses this pool and remains under RLS. |
PGVECTOR_MAINTENANCE_URL | Restricted maintenance pool using corecube_maintenance for background cleanup and repair jobs. |
| PostgreSQL + pgvector storage | Application data, audit data, jobs, documents, chunks, embeddings, provenance, and indexes. |
The maintenance role is intentionally narrow: it can perform runtime knowledge cleanup that must see across scopes, but it is not the main app connection and is not used for schema changes.