DocsRun
Production
Run BBM-Atlas for a team: behind a reverse proxy on one machine, or on Kubernetes with the Helm chart, on one local store or on shared Postgres, Neo4j, Qdrant and Redis, observable throughout.
Choose a shape
| Shape | Storage | Scales to | Use it for |
|---|---|---|---|
bbm-atlas serve behind your reverse proxy | local: one file | one process | A team server on one machine |
Helm, storage.backend: local | local, on a persistent volume | one pod | Kubernetes, simplest |
Helm, storage.backend: all | Your Postgres, Neo4j, Qdrant and Redis | many pods | Kubernetes, scaled out |
Helm, ha.enabled: true | The same | many pods, kept available | High availability, with shared jobs in the Enterprise Edition |
The local store opens in one process at a time, so it never sits behind more than one replica. Whatever the shape, read Security first.
Behind a reverse proxy
Run bbm-atlas serve on the machine, still on loopback, and let a proxy - Caddy, nginx, a cloud load balancer - terminate HTTPS in front of it. Caddy, for example, obtains and renews the certificate itself:
atlas.example.com { reverse_proxy 127.0.0.1:8000}Then tell BBM-Atlas which proxy to trust, so it sees each client's real address and scheme, and the name clients use:
BBM_ATLAS_FORWARDED_ALLOW_IPS=127.0.0.1BBM_ATLAS_MCP_ALLOWED_HOSTS=atlas.example.comThe container image
- One image for both editions, for
linux/amd64andlinux/arm64, with theotelextra included. - It serves the API,
/mcpand the console on port 8000, as a non-root user (uid 10001), and checks itself through/health. - It is configured with the same
BBM_ATLAS_*variables. WithBBM_ATLAS_STORAGE_BACKEND=local, the store lives in/app/store: mount a volume there that uid 10001 can write.
Helm on Kubernetes
kubectl create secret generic atlas-credentials \ --from-literal=api_keys="$(openssl rand -hex 32)"helm install atlas oci://<registry>/charts/bbm-atlas \ --set credentials.existingSecret=atlas-credentials \ --set ingress.enabled=true --set ingress.host=atlas.example.comThe default install runs one pod on the local store, on a 5 GiB persistent volume kept when the release is uninstalled. Without a credentials Secret, the chart generates an API key and the release notes say how to read it. Credentials are mounted as files, never put in the pod's environment.
| Value | What it sets |
|---|---|
storage.backend | local (one pod) or all (your stores, through stores.* and the credentials Secret) |
credentials.existingSecret | A Secret holding api_keys, and as needed admin_api_keys, postgres_dsn, neo4j_password, qdrant_api_key, redis_url |
ingress.* | The ingress: enabled, className, host, annotations (for cert-manager), tls |
rateLimit.* | enabled, requestsPerMinute, and backend: redis across replicas |
indexRoots | The directories repositories may be indexed from, mounted with extraVolumes |
otel.enabled, otel.endpoint | Traces to your OpenTelemetry collector |
enterprise.licenseSecret | A Secret holding your licence key under license |
ha.enabled, ha.replicas | Several replicas with rolling updates, a disruption budget and spreading across nodes |
extraEnv | Any other BBM_ATLAS_* setting |
Observability
/healthsays the process is up;/health/readychecks every store and answers 503, naming the one at fault, while one is unreachable./metricsis Prometheus text: requests and their duration, indexing, agent tasks, compression savings, rate-limit rejections and oversized requests (bbm_atlas_*).- Logs are JSON lines, each request's carrying its
X-Request-ID. - With
BBM_ATLAS_OTEL_ENABLED=true, every request is an OpenTelemetry span, exported over OTLP to the endpoint inOTEL_EXPORTER_OTLP_ENDPOINT.
High availability
With ha.enabled, the chart runs several replicas on shared stores, and each picks up the repositories another indexed, told at once through Redis. With the Enterprise Edition they also share one queue of background index jobs: see High availability.