Skip to content

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

ShapeStorageScales toUse it for
bbm-atlas serve behind your reverse proxylocal: one fileone processA team server on one machine
Helm, storage.backend: locallocal, on a persistent volumeone podKubernetes, simplest
Helm, storage.backend: allYour Postgres, Neo4j, Qdrant and Redismany podsKubernetes, scaled out
Helm, ha.enabled: trueThe samemany pods, kept availableHigh 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:

Caddyfile
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:

terminal
BBM_ATLAS_FORWARDED_ALLOW_IPS=127.0.0.1BBM_ATLAS_MCP_ALLOWED_HOSTS=atlas.example.com

Shared stores

To share state between replicas, or keep it in databases you already run, point BBM-Atlas at Postgres (metadata, memory, chunks), Neo4j (the graph), Qdrant (vectors) and Redis (the cache):

terminal
BBM_ATLAS_STORAGE_BACKEND=allBBM_ATLAS_POSTGRES_DSN_FILE=/run/secrets/postgres_dsn   # postgresql+psycopg://…BBM_ATLAS_NEO4J_URI=bolt://graph:7687BBM_ATLAS_NEO4J_PASSWORD_FILE=/run/secrets/neo4j_passwordBBM_ATLAS_QDRANT_URL=http://vectors:6333BBM_ATLAS_REDIS_URL_FILE=/run/secrets/redis_url

With more than one replica, keep every shared piece of state in Redis too: BBM_ATLAS_RATE_LIMIT_BACKEND=redis and BBM_ATLAS_MEMORY_FACTS_BACKEND=redis. At start-up BBM-Atlas warns, naming anything still kept per process.

The container image

  • One image for both editions, for linux/amd64 and linux/arm64, with the otel extra included.
  • It serves the API, /mcp and 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. With BBM_ATLAS_STORAGE_BACKEND=local, the store lives in /app/store: mount a volume there that uid 10001 can write.

Helm on Kubernetes

terminal
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.com

The 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.

ValueWhat it sets
storage.backendlocal (one pod) or all (your stores, through stores.* and the credentials Secret)
credentials.existingSecretA 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
indexRootsThe directories repositories may be indexed from, mounted with extraVolumes
otel.enabled, otel.endpointTraces to your OpenTelemetry collector
enterprise.licenseSecretA Secret holding your licence key under license
ha.enabled, ha.replicasSeveral replicas with rolling updates, a disruption budget and spreading across nodes
extraEnvAny other BBM_ATLAS_* setting

Observability

  • /health says the process is up; /health/ready checks every store and answers 503, naming the one at fault, while one is unreachable.
  • /metrics is 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 in OTEL_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.