Installing on Kubernetes
Liteset ships a first-party Helm chart in this repository at helm/superset/. The chart was forked from the upstream Apache Superset chart and adjusted for the Liteset runtime — Uvicorn/uvloop launcher, pydantic-settings-based configuration, and the native WebSocket server (no superset-websocket sidecar).
The Helm chart is the K8s companion to the Docker images documented in Production Docker Deployment. Read that page first for the required secrets, image targets (lean / dev / ci) and healthcheck endpoints.
Prerequisites
- A Kubernetes cluster (1.27+ recommended)
- Helm 3.10+
- A clone of the
litesetrepository — the chart is consumed locally, it is not published to a Helm registry
For single-host environments we recommend minikube or kind, both of which work well with this chart.
Running
- Clone the repository
git clone --depth=1 https://github.com/happykust/liteset.git
cd liteset
- Inspect the bundled subcharts
The Liteset Helm chart depends on the Bitnami postgresql and redis subcharts (declared in helm/superset/Chart.yaml). They are vendored under helm/superset/charts/. Run helm dependency build helm/superset if your local cache is missing them.
Recent Bitnami releases moved most container images to a paid "Bitnami Premium" registry, so a fresh helm install may pull dockerhub.io/bitnamilegacy/postgresql:... and fail to start. The chart's default values.yaml pins working tags; if you override the PostgreSQL or Redis image, validate the tag exists publicly. See the troubleshooting notes in Production Docker Deployment for the same issue at the Docker layer.
- Configure your overrides
Create a my-values.yaml and override at least the items below. Every key is documented in helm/superset/values.yaml.
# my-values.yaml
# REQUIRED: secret key used to sign session cookies and encrypt secrets.
# Generate with: openssl rand -base64 42
extraSecretEnv:
LITESET_SECRET_KEY: "CHANGE_ME_TO_A_LONG_RANDOM_STRING"
# Optional: override the image. Defaults to the lean Liteset image.
# image:
# repository: ghcr.io/happykust/liteset
# tag: "6.0.0"
# pullPolicy: IfNotPresent
# Default values.yaml already exports SUPERSET_CONFIG_PATH so the
# rendered superset_config.py is picked up by pydantic-settings.
# Only override extraEnv if you need to inject additional variables.
extraEnv:
# Example: enable proxy fix behind an ingress that does TLS offloading.
# ENABLE_PROXY_FIX: "True"
LITESET_SECRET_KEY is mandatory — Liteset's SupersetSettings will refuse to start without it. SUPERSET_CONFIG_PATH is already set in the default values.yaml (it points at /app/pythonpath/superset_config.py) and almost never needs to be changed.
- Install
helm install superset helm/superset \
--values my-values.yaml \
--create-namespace --namespace superset
After a minute or so you should see something like:
kubectl -n superset get pods
NAME READY STATUS RESTARTS AGE
superset-celerybeat-7cdcc9575f-k6xmc 1/1 Running 0 119s
superset-f5c9c667-dw9lp 1/1 Running 0 4m7s
superset-f5c9c667-fk8bk 1/1 Running 0 4m11s
superset-init-db-zlm9z 0/1 Completed 0 111s
superset-postgresql-0 1/1 Running 0 6d20h
superset-redis-master-0 1/1 Running 0 6d20h
superset-worker-75b48bbcc-jmmjr 1/1 Running 0 4m8s
superset-worker-75b48bbcc-qrq49 1/1 Running 0 4m12s
The exact list depends on your overrides; you should generally expect:
- N
superset-xxxx-yyyy(web) andsuperset-worker-xxxx-yyyy(Celery worker) pods depending onsupersetNode.replicaCountandsupersetWorker.replicaCount - 1
superset-postgresql-0(or your external PostgreSQL) - 1
superset-redis-master-0(or your external Redis) - 1
superset-celerybeat-xxxx-yyyyifsupersetCeleryBeat.enabled: true
There is no WebSocket sidecar — Liteset serves WebSockets natively from the main superset-xxxx-yyyy pods.
- Access it
The chart publishes Services to expose the Liteset UI within your cluster. To access it externally:
- Configure the Service as a
LoadBalancerorNodePort - Set up an
Ingress(the chart includes a template; you'll want to tune hostname, TLS and annotations) - Run
kubectl -n superset port-forward svc/superset 8088:8088to tunnel locally
Then log in with the default admin / admin credentials (override with init.adminUser in your values).
Important settings
Security settings
Default passwords are baked into the chart for first-boot convenience but must be rotated for any non-disposable environment:
postgresql:
postgresqlPassword: "<strong random string>"
extraSecretEnv:
LITESET_SECRET_KEY: "<strong random string, openssl rand -base64 42>"
Liteset reads LITESET_SECRET_KEY from the environment. If you previously deployed with a different key and need to rotate it without losing encrypted database credentials, set the old value as PREVIOUS_SECRET_KEY in configOverrides and run superset re-encrypt-secrets from the init pod — the same procedure as upstream Apache Superset.
External PostgreSQL / Redis
To disable the bundled subcharts and point at managed services:
postgresql:
enabled: false
redis:
enabled: false
supersetNode:
connections:
db_host: "postgres.internal"
db_port: "5432"
db_user: "liteset"
db_pass: "..." # use envFromSecrets in production
db_name: "liteset"
redis_host: "redis.internal"
redis_port: "6379"
Dependencies
Extra Python packages can be installed via bootstrapScript (sourced by every pod at startup). For production clusters we strongly recommend baking these into a custom image instead — pods start faster and don't depend on PyPI being reachable at boot:
FROM ghcr.io/happykust/liteset:6.0.0
USER root
RUN . /app/.venv/bin/activate && uv pip install \
snowflake-sqlalchemy \
redshift-connector
USER superset
See Production Docker Deployment for the full custom-image workflow.
superset_config.py
The default superset_config.py rendered by the chart is intentionally minimal; you'll extend it via configOverrides:
configOverrides:
my_override: |
# Make sure the redirect_uri is properly computed when an ingress does TLS offloading
ENABLE_PROXY_FIX = True
FEATURE_FLAGS = {
"DYNAMIC_PLUGINS": True,
}
Each entry is rendered as a Helm template, so you can reference other values.yaml variables (e.g. {{ .Values.ingress.hosts[0] }}).
The entire superset_config.py is stored as a Secret in the cluster, so it is safe to put sensitive parameters directly inside configOverrides — though extraSecretEnv plus os.environ.get("VAR") is usually cleaner.
A full Python file can be loaded with:
helm upgrade --install --values my-values.yaml \
--set-file configOverrides.oauth=set_oauth.py \
superset helm/superset
Environment variables
extraEnv (plain ConfigMap) and extraSecretEnv (Secret) are both passed into the web, worker, beat and init pods. They can be referenced from superset_config.py via os.environ.get("VAR"):
extraEnv:
SMTP_HOST: smtp.gmail.com
SMTP_USER: user@gmail.com
SMTP_PORT: "587"
SMTP_MAIL_FROM: user@gmail.com
extraSecretEnv:
SMTP_PASSWORD: xxxx
configOverrides:
smtp: |
SMTP_HOST = os.getenv("SMTP_HOST", "localhost")
SMTP_STARTTLS = os.getenv("SMTP_STARTTLS", "True").lower() == "true"
SMTP_SSL = os.getenv("SMTP_SSL", "False").lower() == "true"
SMTP_USER = os.getenv("SMTP_USER", "superset")
SMTP_PORT = int(os.getenv("SMTP_PORT", "25"))
SMTP_PASSWORD = os.getenv("SMTP_PASSWORD", "superset")
System packages
If new system packages are required, install them by overriding the container command. The same pattern works for the web, worker and beat pods:
supersetWorker:
command:
- /bin/sh
- -c
- |
apt update
apt install -y somepackage
apt autoremove -yqq --purge
apt clean
# Run celery worker
. {{ .Values.configMountPath }}/superset_bootstrap.sh
celery --app=superset.tasks.celery_app:app worker
Data sources
Database connections can be declared declaratively via extraConfigs:
extraConfigs:
import_datasources.yaml: |
databases:
- allow_file_upload: true
allow_ctas: true
allow_cvas: true
database_name: example-db
extra: "{\r\n \"metadata_params\": {},\r\n \"engine_params\": {},\r\n \"\
metadata_cache_timeout\": {},\r\n \"schemas_allowed_for_file_upload\": []\r\n\
}"
sqlalchemy_uri: example://example-db.local
tables: []
These are mounted as Secrets and may include sensitive parameters.
Configuration examples
OAuth and SSO
OAuth, LDAP and other authentication backends are configured the same way as upstream Apache Superset — by overriding AUTH_TYPE, OAUTH_PROVIDERS and friends in superset_config.py. See the OAuth section of Configuring Liteset for the full configuration surface; copy the snippet into a configOverrides entry and put any client IDs/secrets in extraSecretEnv.
Enable Alerts and Reports
Follow the platform-agnostic Alerts and Reports documentation. On Kubernetes you will typically:
- Install a Playwright/Chromium-capable image for the Celery worker (either bake it into your custom image or install via
bootstrapScript). - Enable the Celery beat:
supersetCeleryBeat:
enabled: true
- Configure SMTP/Slack via
extraEnv+extraSecretEnv(see the SMTP example above).
Load the example dashboards
init:
loadExamples: true
The superset-init-db Job will populate the metadata DB with example datasets and dashboards on first install.