Deployment
Cortex ships as a Docker Compose stack. This page covers the default deployment, the environment variables you need to set, and recommendations for running in production.
Default stack
Section titled “Default stack”The docker-compose.example.yml defines nine services:
| Service | Image | Default port | Purpose |
|---|---|---|---|
surrealdb | surrealdb/surrealdb:v2.1.7 | 8000 | Graph + relational database |
postgres | postgres:16-alpine | 5432 | Auth, audit trail, documents, provider credentials |
meilisearch | getmeili/meilisearch:v1.12 | 7700 | Full-text search engine |
minio | minio/minio:latest | 9000 / 9001 | S3-compatible object storage |
minio-init | minio/mc:latest | — | Init container: creates the storage bucket |
ollama | ollama/ollama:latest | 11434 | Local embeddings (bge-m3) and optional LLM |
cortex_api | built from deploy/Dockerfile.api | 9096 | REST API |
cortex_mcp | built from deploy/Dockerfile.mcp | 3001 | MCP server |
cortex_ui | built from cortex/ui/Dockerfile | 8080 | Web UI |
All services use health checks. cortex_api waits for SurrealDB, PostgreSQL, MeiliSearch, MinIO and Ollama to be healthy before starting. cortex_mcp waits for cortex_api and Ollama.
Environment variables
Section titled “Environment variables”Required
Section titled “Required”| Variable | Purpose |
|---|---|
SURREAL_USER | SurrealDB root username |
SURREAL_PASS | SurrealDB root password |
PG_PASSWORD | PostgreSQL password |
MEILI_MASTER_KEY | MeiliSearch master API key |
S3_ACCESS_KEY | MinIO (S3) access key |
S3_SECRET_KEY | MinIO (S3) secret key |
ENCRYPTION_KEY | AES-256-GCM key for provider credential encryption (base64, 32 bytes) |
Optional (with defaults)
Section titled “Optional (with defaults)”| Variable | Default | Purpose |
|---|---|---|
SURREAL_NS | cortex | SurrealDB namespace |
SURREAL_DB | cortex | SurrealDB database name |
PG_DATABASE | cortex | PostgreSQL database name |
PG_USER | cortex | PostgreSQL username |
S3_BUCKET | cortex | MinIO bucket name |
CORTEX_API_KEY | (empty) | API key for REST/MCP authentication |
CORS_ORIGIN | http://localhost:8080 | Allowed CORS origin for REST API |
MCP_CORS_ORIGINS | https://claude.ai,https://chatgpt.com | Allowed CORS origins for MCP server |
OLLAMA_EMBED_MODEL | bge-m3 | Ollama embedding model |
OLLAMA_LLM_MODEL | mistral | Ollama LLM model (for optional local inference) |
API_PORT | 9096 | REST API port |
MCP_PORT | 3001 | MCP server port |
UI_PORT | 8080 | Web UI port |
ALLOWED_EMAILS | (empty) | Comma-separated email whitelist for JWT auth |
SUPABASE_JWT_SECRET | (empty) | JWT verification secret for Supabase auth |
Minimum hardware
Section titled “Minimum hardware”| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 cores | 8 cores |
| RAM | 8 GB | 16 GB |
| Disk | 20 GB | 50+ GB (depends on catalogue size and embeddings) |
Ollama with the bge-m3 embedding model is the most memory-intensive component. If you do not need local embeddings, you can remove the Ollama service and save resources.
Production hardening
Section titled “Production hardening”TLS termination
Section titled “TLS termination”The Docker Compose stack does not include TLS. For production, put a reverse proxy in front:
Internet -> [nginx/Caddy/Traefik with TLS] -> cortex_api:9096 -> cortex_mcp:3001 -> cortex_ui:8080Network binding
Section titled “Network binding”By default, all services except the UI bind to 127.0.0.1. The UI binds to 0.0.0.0:8080. In production, bind the UI to 127.0.0.1 as well and serve it through the reverse proxy.
Secrets management
Section titled “Secrets management”- Generate
ENCRYPTION_KEYwithopenssl rand -base64 32. - Generate
CORTEX_API_KEYwithopenssl rand -hex 32. - Use a secrets manager (Vault, AWS Secrets Manager, etc.) or Docker secrets instead of plain
.envfiles in production.
Resource limits
Section titled “Resource limits”Add resource limits to your Docker Compose services:
deploy: resources: limits: memory: 2G cpus: "1.0"Backups
Section titled “Backups”SurrealDB
Section titled “SurrealDB”SurrealDB data is stored in a Docker volume (surreal_data). Back up via the HTTP export endpoint:
curl -X GET http://localhost:8000/export \ -u "root:YOUR_PASS" \ -H "surreal-ns: cortex" \ -H "surreal-db: cortex" \ -o cortex-surreal-backup.surqlPostgreSQL
Section titled “PostgreSQL”docker compose exec postgres pg_dump -U cortex cortex > cortex-pg-backup.sqlUse the MinIO client (mc) to mirror the bucket:
mc alias set local http://localhost:9000 ACCESS_KEY SECRET_KEYmc mirror local/cortex ./backup/minio-cortexBackup schedule
Section titled “Backup schedule”For production, automate backups at least twice daily. Store backups off-host (S3-compatible remote, separate server, etc.).
Upgrading
Section titled “Upgrading”- Pull the latest code:
git pull - Rebuild images:
docker compose -f docker-compose.example.yml build - Restart:
docker compose -f docker-compose.example.yml up -d
Data volumes persist across rebuilds. Check the CHANGELOG for migration notes before upgrading.
What next?
Section titled “What next?”- Check the security posture: 07-security-and-data
- Frequently asked questions: 09-faq