A production-oriented Chroma vector DB stack for ARM64 homelabs: containerized Chroma deployment, RAG API with auth and metrics, backup/restore scripts, and monitoring.
chroma-stack packages everything needed to run Chroma reliably in a homelab:
- Chroma DB running in Docker
- FastAPI RAG API with document ingestion, semantic search, and collection management
- API key authentication for production use
- Live metrics (latency percentiles, request counts, throughput)
- Backup / restore scripts with verification and rotation
- Lightweight monitoring for health, latency, CPU, and memory
docker compose up -dpip install -e .
chroma-stack serve --port 8000# Ingest
curl -X POST http://localhost:8000/documents \
-H 'content-type: application/json' \
-d '{"content": "My document text", "metadata": {"source": "notes"}}'
# Search
curl -X POST http://localhost:8000/search \
-H 'content-type: application/json' \
-d '{"query": "document", "n_results": 5}'curl http://localhost:8000/metrics| Endpoint | Method | Description |
|---|---|---|
/ |
GET | API root with endpoint listing |
/health |
GET | Health check (Chroma connectivity) |
/metrics |
GET | Request metrics (latency, counts, uptime) |
/documents |
POST | Ingest a single document |
/documents/batch |
POST | Batch ingest (up to batch_size docs) |
/search |
POST | Semantic search with optional metadata filter |
/documents |
GET | List documents with pagination (limit, offset) |
/documents/{id} |
DELETE | Delete a document by ID (404 if not found) |
/collection/info |
GET | Collection metadata (name, count, path) |
/collection |
DELETE | Reset the entire collection |
DocumentIn (ingest):
content(string, 1–100000 chars) — requiredmetadata(object) — optional, values auto-sanitizedid(string, max 128 chars) — optional, auto-generated UUID
SearchIn (search):
query(string, 1–1000 chars) — requiredn_results(int, 1–100, default 5) — optionalwhere(object) — optional Chroma metadata filter
Every response includes:
X-Response-Time— request duration in milliseconds
Enable API key auth by adding keys to your config:
api:
api_keys:
- "my-secret-key-1"
- "my-secret-key-2"When keys are configured, non-public endpoints require an X-API-Key header or ?api_key= query parameter. Public paths (/, /health, /metrics, /docs) remain accessible without auth.
Without keys configured, all endpoints are open (dev mode).
chroma:
persistence_dir: /tmp/chroma_rag_db
collection_name: homelab_documents
telemetry: false
api:
host: "0.0.0.0"
port: 8000
batch_size: 100
api_keys: []
backup:
data_dir: /mnt/shared-storage/docker-volumes/chroma-prod-data
backup_root: /mnt/shared-storage/backups/chroma
keep_count: 10
monitor:
url: "http://localhost:8000"
interval: 30
latency_alert_ms: 2000
memory_alert_mb: 400
cpu_alert_pct: 80| Variable | Section.Key |
|---|---|
CHROMA_HOST |
chroma.host |
CHROMA_HTTP_PORT |
chroma.http_port |
CHROMA_PERSISTENCE_DIR |
chroma.persistence_dir |
CHROMA_COLLECTION_NAME |
chroma.collection_name |
CHROMA_STACK_API_PORT |
api.port |
CHROMA_STACK_API_HOST |
api.host |
CHROMA_BACKUP_DATA_DIR |
backup.data_dir |
CHROMA_BACKUP_ROOT |
backup.backup_root |
CHROMA_MONITOR_URL |
monitor.url |
CHROMA_MONITOR_INTERVAL |
monitor.interval |
chroma-stack --version
chroma-stack serve [--host HOST] [--port PORT]
chroma-stack backup
chroma-stack restore <archive.tar.gz> [--restore-dir DIR]
chroma-stack monitor [--url URL] [--interval SECONDS]
chroma-stack config
# Create backup
scripts/backup-chroma.sh
# Restore from backup
scripts/restore-chroma.sh /path/to/backup.tar.gz [restore_dir]
# Integration test
scripts/integration-test.shBackups are timestamped tarballs with manifests. Automatic rotation keeps the last N backups (configurable via KEEP_COUNT).
See OPERATIONS.md for the operator guide.
pip install -e ".[dev]"
pytest tests/See CONTRIBUTING.md for guidelines.
MIT