Deploying Apache Superset on Kubernetes (Helm): From Chaos to Production
Real-world failure analysis, custom image build, and secure production deployment with flexible DB architecture.

Search for a command to run...
Real-world failure analysis, custom image build, and secure production deployment with flexible DB architecture.

No comments yet. Be the first to comment.
Real production migration and incident playbooks focused on safe execution, root cause analysis, and rollback-first DevOps practices. Each post documents how real production issues were handled and fixed without downtime.
A Practical Production Playbook (200 Instance Scenario) Amazon Linux 2 (AL2) will reach end-of-support on June 30, 2026. After that date, AWS will no longer provide security updates, patches, or new packages. Although AL2 continues to receive mainten...
This migration was performed on a production workload where cost reduction was prioritized over zone-level high availability.

1. Overview What I Designed I designed a hybrid infrastructure architecture: Terraform → Foundation Layer Crossplane → Dynamic Lifecycle Layer ArgoCD → GitOps Enforcement This created a continuou

Cross-cloud VM migration is not a disk copy task. It is: An access model transformation A replication lifecycle management exercise A downtime control operation A cost boundary decision We execu

When AWS introduced AWS DevOps Agent, I was less interested in feature lists and more interested in one practical question. Can it actually reduce investigation time during real production-style failu

Migrating object storage across cloud providers is not a copy task.It is a cost, network, and security boundary problem. We migrated 10+ TB of object data from Google Cloud Storage to Amazon S3 under

On this page
Deploying Apache Superset on Kubernetes using the official Helm chart appears straightforward when following the documentation. In real-world environments, however, production deployments often expose issues across multiple layers — Helm dependency resolution, container image integrity, Python runtime behavior, database connectivity, and secret management.
This article walks through a real-world failure analysis, explains the root causes, and documents the production-ready deployment that supports:
In-cluster PostgreSQL & Redis
External PostgreSQL (e.g., AWS RDS) & External Redis
Optional Kubernetes Secret–based credential injection
The final architecture is flexible, secure, and restart-safe.
We attempted to deploy Apache Superset on Kubernetes using the official Helm chart.
Apache Superset (Web + Celery Worker)
PostgreSQL (metadata database)
Redis (Celery broker and caching)
Kubernetes
Helm-based deployment
Custom Superset image
Optional external PostgreSQL (AWS RDS)
Optional external Redis
Superset UI accessible
Database migrations completed successfully
Celery workers start without errors
Stable across restarts
Secure credential handling
The deployment failed at multiple stages:
Dependency image pull failures
Python module errors inside the container
Runtime package installation failures
SECRET_KEY validation error
Database connectivity issues
This was a multi-layer failure — not a single misconfiguration.
ImagePullBackOff
Failed to pull image
not found
Both PostgreSQL and Redis pods failed to start.
The Helm chart referenced specific image tags that were no longer available in the container registry.
Helm does not validate tag existence.
Kubernetes only detects the failure during image pull.
Until dependencies are healthy:
Superset init job cannot complete
Application errors remain hidden
Debugging becomes misleading
Infrastructure must be stable before diagnosing application issues.
latestlatest.postgresql:
image:
tag: latest
redis:
image:
tag: latest
This confirmed:
The Helm chart’s default tags were deprecated.
The infrastructure was blocking deployment.
Superset itself was not the initial issue.
⚠ The latest tag was used only for diagnostics.
In production environments, pinned image versions are recommended for deterministic deployments.
Once dependencies were running, the real application error surfaced.
Superset failed with:
ModuleNotFoundError: No module named 'psycopg2'
This affected:
Superset Web pod
Superset Worker pod
Superset Init DB job
Superset requires a metadata database.
Dependency chain:
Superset → SQLAlchemy → psycopg2 → PostgreSQL
If psycopg2 is missing:
Superset cannot start
Database migrations fail
Celery workers fail
No fallback mode exists
Attempts included:
extraPipPackages
bootstrapScript
Installing packages inside running pods
Init container installation
All failed.
The official Superset image runs inside a prebuilt Python virtual environment:
/app/.venv/
Key details:
Superset executes strictly inside this environment.
Runtime installations either failed.
Or installed packages outside the active environment.
Container immutability was violated.
Even when psycopg2 appeared installed, it was outside Superset’s active virtual environment — making it effectively unusable.
Database drivers must be installed at image build time.
FROM apachesuperset.docker.scarf.sh/apache/superset:3.0.0
USER root
RUN apt-get update && apt-get install -y libpq-dev gcc \
&& /app/.venv/bin/python -m ensurepip --upgrade \
&& /app/.venv/bin/python -m pip install --no-cache-dir psycopg2==2.9.9
USER superset
Installs psycopg2 inside Superset’s active virtual environment
Immutable and reproducible
Restart-safe
Production aligned
Superset supports multiple ways to provide database and Redis credentials.
supersetNode:
connections:
db_type: postgresql
db_host: my-db-endpoint
db_port: "5432"
db_user: superset
db_pass: superset123
db_name: superset
Suitable for:
Local testing
Temporary debugging
Learning environments
⚠ Credentials stored in plaintext.
Instead of storing credentials in Helm values, they can be injected securely.
kubectl create secret generic superset-backend-secret \
--from-literal=DB_HOST=<db-endpoint> \
--from-literal=DB_PORT=5432 \
--from-literal=DB_USER=<db-user> \
--from-literal=DB_PASSWORD=<db-password> \
--from-literal=DB_NAME=<db-name> \
--from-literal=REDIS_HOST=<redis-endpoint> \
--from-literal=REDIS_PORT=6379
envFromSecrets:
- superset-backend-secret
Superset connections then use environment variables:
supersetNode:
connections:
db_type: postgresql
db_host: "$(DB_HOST)"
db_port: "$(DB_PORT)"
db_user: "$(DB_USER)"
db_pass: "$(DB_PASSWORD)"
db_name: "$(DB_NAME)"
redis_host: "$(REDIS_HOST)"
redis_port: "$(REDIS_PORT)"
Benefits:
No plaintext credentials in Git
Secure runtime injection
Easier rotation
Environment portability
Using Kubernetes Secrets is optional but strongly recommended for production.
Superset supports two architectural modes.
Enable Helm-managed dependencies:
postgresql:
enabled: true
redis:
enabled: true
Best for:
Development
Testing
Small internal tools
Pros:
Simple
Self-contained
Cons:
You manage backups
You manage scaling
Higher operational overhead
Disable internal services:
postgresql:
enabled: false
redis:
enabled: false
Best for:
Production
High availability needs
Managed backups
Reduced operational risk
Pros:
Managed durability
Better reliability
Clear stateless/stateful separation
External services are optional — the deployment remains flexible.
The final production architecture is designed to support both Helm-managed in-cluster stateful services and externally managed database/cache services (such as AWS RDS and ElastiCache), ensuring operational flexibility and scalability across environments.
import os
SQLALCHEMY_DATABASE_URI = (
f"postgresql+psycopg2://{os.environ['DB_USER']}:{os.environ['DB_PASSWORD']}"
f"@{os.environ['DB_HOST']}:{os.environ['DB_PORT']}/{os.environ['DB_NAME']}"
"?sslmode=require"
)
Ensures encrypted communication with PostgreSQL.
command:
- dockerize
- -wait
- tcp://$(DB_HOST):$(DB_PORT)
- -wait
- tcp://$(REDIS_HOST):$(REDIS_PORT)
- -timeout
- 120s
Prevents:
CrashLoopBackOff
Early DB connection failures
Celery startup issues
extraSecretEnv:
SUPERSET_SECRET_KEY: <strong-random-secret>
Superset refuses to start without a secure secret key.
helm upgrade --install superset apache/superset \
-f values.yaml \
--namespace superset \
--create-namespace
Deployment failed due to:
Deprecated dependency image tags
Missing psycopg2 driver in container
Runtime package installation is incompatible with Superset’s virtual environment
Missing secure SECRET_KEY
Resolution involved:
Diagnosing infrastructure image failures
Building a custom immutable Superset image
Securely injecting credentials
Supporting flexible DB/Redis architecture
Enforcing SSL
Implementing readiness checks
Apache Superset initially failed due to deprecated dependency image tags and a missing PostgreSQL driver inside the container. Runtime installation failed because the official Superset image runs inside a prebuilt Python virtual environment, making post-start package installation ineffective. The issue was resolved by building a custom immutable image with psycopg2 installed at build time, securely managing credentials, and supporting both in-cluster and external database/Redis architectures. The final deployment is stable, secure, and production-ready.
Keywords:
Apache Superset Kubernetes,
Superset Helm Chart,
Superset Production Deployment,
psycopg2 error in Superset,
Kubernetes ImagePullBackOff,
Superset with AWS RDS,
Superset External PostgreSQL,
Superset Redis configuration