Skip to main content
Cluster runs Latitude on Kubernetes through a cloud-agnostic Helm chart: a Deployment per application service, a one-shot migrations job, ingress, and bundled infrastructure (Postgres, ClickHouse, Redis, Temporal, SeaweedFS) — every piece replaceable by a managed equivalent. It deploys the published Docker images.
For a simpler start on one machine, use the Single-host deployment — same images, same configuration contract, no cluster required.

Quick start

1

Get the chart

The chart lives in the Latitude repository under charts/latitude — a sparse checkout downloads just that folder:
2

Create your values file

Don’t name it values.yaml — that file already holds the chart’s defaults.
my-values.yaml
The secrets are permanent for the installation — keep this file (or move the keys into a pre-created Secret and set secrets.existingSecret). Every future helm upgrade must receive the same values.
3

Install the chart in your cluster

The install brings up the bundled infrastructure, runs database migrations and the Temporal schema setup as one-shot jobs, and starts the five application services. App pods wait in Init:0/1 until their dependencies accept connections, then start once, cleanly — the first install takes a few minutes (image pulls plus volume provisioning).
4

Verify the Latitude services are running

All pods should reach Running/Ready and the latitude-migrations, latitude-temporal-schema, and latitude-temporal-namespace jobs should show Complete.
5

Create the first account

Open the web UI (at your config.webUrl) and register. Latitude sends a magic link through the email transport you configured; click it to finish signing in and create your organization.

What gets deployed

Secrets

Optional non-secret settings (email transport, LAT_AI_* model selection, integrations) go in config.extraEnv as standard EnvVar entries; optional secret values (AI provider keys, email passwords, OAuth client secrets) go in secrets.extra, which merges them into the chart-managed Secret — never as extraEnv literals, which would sit readable in the pod spec. To manage secrets yourself (e.g. with an external secrets operator), create a Secret carrying the chart’s expected keys and set secrets.existingSecret — the chart then renders no Secret of its own. The key list is in the chart README. See the secrets reference for what each application secret does.

AI features

The stack boots and core observability (ingest + trace viewing) works without API keys. AI-dependent features stay disabled until you add credentials for the providers you configure — keys in secrets.extra, LAT_AI_* provider/model selection in config.extraEnv: Every provider and model is selectable per feature through environment variables — see the AI configuration reference.

Scaling

The five application services are stateless and scale horizontally:
Every service ships with resource requests (HPA-ready); add limits and HorizontalPodAutoscalers to taste. The bundled stateful services stay single-instance by design — for HA move them to managed equivalents (Bring your own infrastructure).

Backups

Persistent state lives in the PVCs of postgres, clickhouse, redis-bullmq, and seaweedfs. Use your storage provider’s volume snapshots, plus:
  • Postgreskubectl exec -n latitude latitude-postgres-0 -- pg_dump -U latitude latitude (the source of truth for projects, users, and metadata).
  • ClickHouse — volume snapshots or ClickHouse BACKUP (span/telemetry data).
  • Object store — volume snapshots (or rely on your managed S3’s durability).

Upgrading

The chart version tracks the Latitude release, and the images default to the chart’s appVersion — so the chart always deploys the release it shipped with. To upgrade, pull the new chart and run:
To deviate from the chart’s pinned release, set image.tag (X.Y.Z with no leading v, or latest). Migrations run as a pre-upgrade hook — the schema is upgraded before the new pods roll. Latitude migrations are backward-compatible, so the previous release keeps working during the rollout.

Health and observability

Every service exposes an HTTP health endpoint, wired as readiness and liveness probes (/health; the web app uses /api/health; workers/workflows listen on internal ports 9090/9091). OpenTelemetry export is available through the LAT_OBSERVABILITY_* variables via config.extraEnv.

TLS and reverse proxy

The chart’s Ingress routes the three public hosts (taken from config.{web,api,ingest}Url) to the web, api, and ingest Services over plain HTTP inside the cluster — terminate TLS at your ingress controller. Reference your certificate Secrets in ingress.tls, or have cert-manager issue them via ingress.annotations:
Keep the config.*Url values on https:// — they feed the LAT_*_URL and CORS/trusted-origin settings.

Custom domain

Latitude exposes three public surfaces — the web UI, the API (which also hosts the MCP server), and ingest (OTLP traces). You set them through config.webUrl, config.apiUrl, and config.ingestUrl; the Ingress derives its three hosts from those same values, and the chart wires the rest of the URL contract for you — LAT_TRUSTED_ORIGINS and LAT_CORS_ALLOWED_ORIGINS are derived from config.webUrl. So a standard three-host setup needs nothing beyond getting those three URLs right and pointing DNS at the Ingress:
Each must be the real, externally-resolvable https:// URL (scheme included): the chart feeds them into the in-cluster LAT_*_URL, CORS, and trusted-origin settings and routes the matching Ingress host to each Service. The LAT_*_PORT values stay cluster-internal — the Ingress maps your hostnames to them, so you leave them unchanged. Add the certificates as shown under TLS and reverse proxy. If you serve the web UI from more than one origin (e.g. a vanity host alongside the canonical one), override the allowlists explicitly through config.extraEnv:
MCP clients connect to ${apiUrl}/v1/mcp but sign in via OAuth against the web origin, so both config.apiUrl and config.webUrl must be correct and externally reachable (Ingress + TLS).

Bring your own infrastructure

Every bundled dependency is an independent toggle: set <dep>.enabled: false and fill its external: block, and the chart wires the right LAT_* configuration at your existing or managed instance instead of deploying the bundle.

Troubleshooting

Next steps

Configuration reference

The full Latitude configurable environment-variable reference for self-hosting.