Kubernetes
Running it on a cluster.
The same containers, plus a migration job. Nothing about LensHub is Compose-specific.
Shape
| Workload | Kind | Notes |
|---|---|---|
postgres | StatefulSet | Or a managed database — see below |
api | Deployment | Scales horizontally |
web | Deployment | Scales horizontally |
worker | Deployment | Scale for indexing throughput |
embedding | Deployment | Give it a GPU node if you have one |
migrate | Job | Run on every upgrade, before the new api and worker roll out |
Migrations
The postgres image carries the migration runner. Run it as a Job (or a Helm
pre-upgrade hook) against the database, and only roll out the new api and
worker once it has succeeded:
containers:
- name: migrate
image: <registry>/postgres:<version>
command: ["bash", "/opt/lenshub/migrate.sh", "--apply"]
env: # PGHOST, PGUSER, PGPASSWORD, PGDATABASE for your databaseIt applies only what is pending and is a no-op otherwise. See Upgrades.
Use a managed database if you can
api and worker only need a DATABASE_URL. A managed PostgreSQL with the
pgvector extension available means backups, failover and upgrades stop being
yours to run.
If you run it in-cluster, use a StatefulSet with a real storage class, and make sure your backups leave the cluster.
Secrets
JWT_SECRET, ENCRYPTION_KEY, POSTGRES_PASSWORD and any provider key belong
in a Secret, not in a ConfigMap.
ENCRYPTION_KEY must survive redeployment. It decrypts your stored connector
credentials — if a pod comes back with a different one, every credential has to
be re-entered.
Health checks
| Path | For |
|---|---|
/healthz | Liveness — is the process alive |
/readyz | Readiness — can it reach the database |
Use /readyz for readiness so a pod stops taking traffic when the database is
unreachable, rather than failing every request.
Ingress
Route everything to web, except /api, /mcp, /oauth and /.well-known,
which go to api.
Set BASE_URL on the API to your public address, and TRUST_PROXY_HEADERS=true
only if your ingress overwrites X-Forwarded-For rather than appending to it.
Scaling
worker is the one to scale for indexing throughput. api and web are
stateless and scale on request volume. embedding benefits from a GPU node more
than from replicas.