Tier 1: Evaluation Deployment
Follow the self-hosting guide (or docker compose for a local spin-up) for a minimum production setup suitable for evaluating Lightdash. Prerequisites- External PostgreSQL —
postgresql.enabled: falseeven for a PoC; a small managed instance is fine, no HA or backup requirements yet - S3-compatible object storage — required regardless; Lightdash fails to start without it
- Enterprise license key if you’re evaluating Enterprise features — needs outbound access to
https://api.keygen.sh
- Deploy with the self-hosting guide
- Pin an image version - pin
image.tagto the latest version - Set
SITE_URLto your finalhttps://URL before first boot - Generate a strong
LIGHTDASH_SECRETand store it somewhere durable - losing it means losing access to encrypted data SECURE_COOKIESandTRUST_PROXYboth"true"behind your TLS-terminating load balancer- Headless browser enabled (the chart default) - image previews, PDF exports, Slack unfurls
- HTTPS end-to-end via your ingress or load balancer
- AI Analyst — model provider key +
pgvectorin Postgres
Tier 2: Scalable deployment
None of these steps are required but are recommended for running Lightdash beyond a PoC.Operations
- Choose upgrade strategy — pinned image tag, at least monthly cadence
- Monitor security advisories — poll the GitHub advisory API and alert on anything that matches your deployed version
Workers and scaling
- Data apps — sandboxes runtime, apps bucket, and a separate preview origin
- Dedicated workers -
scheduler.enabled: trueto enable scalable scheduled deliveries - NATS + warehouse workers -
nats.enabled: trueandwarehouseNatsWorker.enabled: truefor handling large volumes of warehouse queries - ≥ 2 backend replicas with pod anti-affinity and a pod disruption budget
- Size resource requests
- Configure health probes - readiness on
/api/v1/readyz, not/api/v1/health, so a migrating pod leaves the load balancer without being restarted
Infrastructure dependencies
- Postgres HA, backups and point-in-time recovery on the external database from Tier 1, plus the
pgvectorextension if you use Enterprise AI features - Bucket strategy and lifecycle rules - a dedicated bucket per purpose, with a 1-day lifecycle delete on the results bucket
- SMTP email
- Email deliverability - transactional provider, SPF/DKIM on the sender domain
- Load balancer settings - timeout ≥ 300s, health check on
/api/v1/health, request body limit ≥LIGHTDASH_MAX_PAYLOAD
Security and authentication
- SSO (Okta / Azure AD / Google / generic OIDC) with password authentication disabled
- Account linking and personal access token policy
- CSP enforcement and explicit CORS
Tier 3: Optional features and observability
Enterprise features
- Pre-aggregations — pre-aggregate NATS workers + a dedicated S3 bucket
- SCIM provisioning from your IdP
- Results caching, embedding, service accounts, custom roles
Integrations (enable what you use)
- Slack — scheduled deliveries, unfurls, AI agents in Slack
- GitHub or GitLab — dbt repo write-back
- Google Sheets sync
Observability
- Prometheus metrics enabled, and scraped on every pod
- Structured JSON logging shipped to your log platform
- Alerts on HTTP error rate/latency, queue depth, and Postgres pool saturation
Architecture: what you’re deploying
The chart wires up environment variables for you in three buckets:
configMap.*— non-sensitive env vars, applied to backend and all workerssecrets.*— sensitive env vars, rendered into a Kubernetes Secret (or bring your own viaexistingSecret)extraEnv/schedulerExtraEnv— raw env entries, includingvalueFrom.secretKeyRef
Core configuration
The chart’s essential first-boot values —SITE_URL and LIGHTDASH_SECRET are the two to get right before you start:
SITE_URLsigns invite emails, OAuth redirect URIs, Slack unfurls, and delivery links — set the finalhttps://URL before first boot.LIGHTDASH_SECRETsigns session cookies and encrypts data at rest in Postgres. Set it and store it durably; losing it means losing access to encrypted data.SECURE_COOKIESandTRUST_PROXYmust both be"true"behind a TLS-terminating proxy, andCOOKIES_MAX_AGE_HOURSsets session length — see Secure Lightdash with HTTPS.- Every variable is documented in the environment variables reference.
existingSecret populated by External Secrets Operator or a CSI driver so credentials stay out of Helm values and git.
Headless browser
Enabled by default in the chart — keep it on, and tune the browserless timeouts and memory guards for large dashboards. The browser renders dashboards by callingSITE_URL, so it must reach that URL from inside the cluster (use INTERNAL_LIGHTDASH_HOST if it can’t). See Headless browser for the container and backend variables, and Resource recommendations for sizing.
Upgrades and operations
Pinimage.tag, upgrade at least monthly, rehearse each upgrade in a UAT instance that mirrors production, take the database backup before you start, and enable the migration job for multi-replica deployments. Versioning policy, upgrade cadence, and advisory monitoring are in Upgrading Lightdash; the upgrade runbook has the per-deployment sequence, the migration commands, recovery, and rollback.
Scheduler worker
Run a dedicated scheduler worker so a heavy dashboard export can’t starve the API — see Scheduler worker. For async warehouse queries, see the NATS workers overview and warehouse workers, including the critical rule: never enablenats.enabled without warehouseNatsWorker.enabled.
Sizing and availability
Size per-component resource requests and run 2+ backend replicas with pod anti-affinity and a pod disruption budget — the full component table and availability settings are in Resource recommendations.PostgreSQL
Run external managed Postgres with high availability, backups, theuuid-ossp and pgvector extensions, and a connection budget — setup and production guidance are in Configure Lightdash to use an external database.
Object storage
Use a dedicated bucket per purpose with lifecycle rules, blocked public access, and scoped credentials — setup and the full bucket strategy are in Configure Lightdash to use external object storage.Email deliverability
Env vars are in the SMTP reference. Best practice on top:- Use a transactional provider (SES, Postmark, SendGrid) — Lightdash Cloud sends through Postmark.
- Set up SPF/DKIM for the sender domain so scheduled deliveries don’t land in spam.
Load balancer and networking
HTTPS end-to-end, a load-balancer timeout ≥ 300s, a health check onGET /api/v1/health, and a request body limit ≥ LIGHTDASH_MAX_PAYLOAD — covered in Secure Lightdash with HTTPS.
Health probes
Lightdash serves three health endpoints, and they are not interchangeable:
Avoid
/api/v1/health for any of the three. It queries the database on every request, which is fine for a manual curl after a deploy but means a brief database blip fails every pod’s check at the same time.
The chart already points startupProbe and livenessProbe at /api/v1/livez by default. Set the readiness path explicitly:
1.169.1 and later. Setting it explicitly is always supported, and an explicit value always wins.
Leave worker probes alone. Worker pods serve their own handler at /api/v1/health (in-memory state, no database query) and do not serve /api/v1/readyz at all.
Authentication policy
Enterprise deployments should be SSO-only, with password authentication disabled and account linking enabled — per-provider setup is in use SSO login for self-hosted Lightdash. Also set a personal access token policy (PAT_ALLOWED_ORG_ROLES, PAT_MAX_EXPIRATION_TIME_IN_DAYS, or DISABLE_PAT), and keep ALLOW_MULTIPLE_ORGS: "false" (default) for a single-company instance.
Security hardening
- CSP enforcement:
LIGHTDASH_CSP_REPORT_ONLY: "false"(default is report-only; enforce in production), plusLIGHTDASH_CSP_ALLOWED_DOMAINSfor any extra origins you load from. - CORS: leave disabled unless embedding; if embedding,
LIGHTDASH_CORS_ENABLED: "true"with an explicitLIGHTDASH_CORS_ALLOWED_DOMAINSlist — never*. - Egress policy: Lightdash needs your warehouse, S3, SMTP,
api.keygen.sh(license), your IdP, and any AI provider endpoints — plusroadmap.lightdash.comif you enable the organization roadmap. RudderStack product telemetry toanalytics.lightdash.comis on by default and can be disabled or redirected. See Data flows and telemetry for the full egress matrix and controls. - NetworkPolicies: the chart only ships one for NATS (keep
nats.networkPolicy.enabled: true, the default); add your own default-deny + allow rules for backend ↔ postgres/browserless/S3 if your cluster uses them. - Pod security: the chart sets no
podSecurityContext/securityContextby default — addrunAsNonRootand drop capabilities per your Pod Security Standards baseline. - Soft delete for content recovery:
SOFT_DELETE_ENABLED: "true"(plusSOFT_DELETE_RETENTION_DAYS, default 30).
Enterprise features
License key setup and validation is covered in enterprise license keys — the key is validated againsthttps://api.keygen.sh on every server start, so allowlist that domain in your egress policy.
Enterprise feature flags
Enable the Enterprise features you use throughconfigMap — each is documented in the environment variables reference:
- Caching:
RESULTS_CACHE_ENABLED,AUTOCOMPLETE_CACHE_ENABLED,CACHE_STALE_TIME_SECONDS. - Governance:
SERVICE_ACCOUNT_ENABLED,CUSTOM_ROLES_ENABLED. - Embedding:
EMBEDDING_ENABLEDwithLIGHTDASH_IFRAME_EMBEDDING_DOMAINS.
AI Analyst
SetAI_COPILOT_ENABLED: "true", choose AI_DEFAULT_PROVIDER (openai, azure, anthropic, openrouter, or bedrock) with the matching API key, and AI_EMBEDDING_ENABLED: "true" for verified answers (requires pgvector). See AI agents for provider setup and LLM-gateway routing, and the environment variables reference for guardrails such as AI_COPILOT_MAX_QUERY_LIMIT and AI_COPILOT_ALLOWED_PROJECT_UUID. For the MCP endpoint, see MCP.
Data apps
Serve app previews from a separate domain (APP_RUNTIME_PREVIEW_ORIGIN) so untrusted app content never shares an origin with your Lightdash session cookies, and use a persistent apps bucket with no delete lifecycle. Sandbox providers and their security model are in sandboxes; configuration in self-hosting data apps.
Observability
Enable Prometheus metrics and structured JSON logging on every pod, and scrape them from your monitoring stack:- Metrics and alerting guidance: Prometheus metrics. Scrape port 9090 on all pods labelled
app.kubernetes.io/name=lightdash(the chart ships no ServiceMonitor/PodMonitoring — create one; Lightdash Cloud scrapes at a 30s interval). If you run NATS, its Prometheus exporter is on port 7777 (nats.promExporter.enabled: true). - Log configuration: Configure logging. Ship
LIGHTDASH_LOG_FORMAT: jsonto your log platform;LIGHTDASH_LOG_LEVEL: auditadds an audit trail of user actions. - Alert on HTTP p95/error rate (
http_server_request_duration_seconds), queue depth / scheduler job failures, Postgres pool saturation, and event-loop lag.