Why teams build their own Apache Superset Docker image
A platform or security team that must run Superset from an image it controls needs a build it can rebuild, scan, pin and roll back without depending on whatever the upstream image happens to contain on a given day. A custom image is the artifact that answers that need. It starts from an official Superset base, adds the database drivers your analytics sources require, adds Playwright Chromium if you send alerts and reports or render dashboard thumbnails, and carries the Superset configuration and any approved extensions your standards allow. Each layer is a decision you can explain to an auditor and reproduce in a later build.
The upstream image can run unchanged when your only sources are the drivers it already includes and you do not need extra packages. Teams usually stop there and build their own when a driver is missing, when a driver version must match a warehouse, when they want a smaller attack surface by removing drivers they never use, or when their security process requires every image to come from their own registry with their own scan results. The project publishes several variants, so the first decision is which base fits your needs. The Superset Docker builds documentation describes the default, lean and development images and the Python version tags, and you should confirm the current tag set there before you choose one. Note that the reader should confirm which variant includes Chromium, since that determines whether your build starts from it or adds Chromium itself.
Apache Superset is released under the Apache License 2.0 and the project has no paid edition, so the image you build carries no license purchase. Your costs sit in the engineering work to build, test, scan and maintain the image, and in the staff time for each upgrade. Superset 6.1.0 was published on May 13, 2026, according to PyPI, and is a sensible current baseline for a new build. Check the Superset Docker builds documentation against the release you pick, and confirm with your own environment which drivers your sources need before you commit to a base.
Choosing between the default, lean and dev image variants
This table compares the default, lean and dev Superset image variants and the py311 and py312 tags. Read each row to see when the variant fits, what your team must add, and how it changes what ships in the image. The main takeaway is that the lean image moves driver choice and its security review into your build.
| Variant | When it fits | What your team must add | Size and attack surface |
|---|---|---|---|
| Default image | Fast evaluation or a first production build where PostgreSQL and MySQL are the only sources you query | Only drivers for other databases, plus your own review of bundled MCP dependencies and Playwright Chromium | Largest of the variants because it includes drivers, MCP dependencies and a headless browser |
| Lean image (-lean) | Teams that query several engines and want to control exactly which drivers enter the image | Every database driver your connections need, pinned and tested, plus Chromium only if reports or thumbnails need it | Smaller set of packages, but your Dockerfile now decides the final contents and must be scanned |
| Dev image (-dev) | Local development, debugging and building or testing Superset code | Nothing for production. Confirm with the project docs before using it as a base image | Includes development tooling, so it should not be the runtime image you deploy |
| py311 tag | Environments standardized on Python 3.11 or that must match an existing dependency set | Confirm that every driver and custom package you add supports Python 3.11 | Interpreter version changes which wheels you install, so rescan after switching |
| py312 tag | Environments standardized on Python 3.12 or newer base image policies | Confirm that every driver and custom package you add supports Python 3.12 | Interpreter version changes which wheels you install, so rescan after switching |
| Playwright Chromium present | Scheduled reports, alerts and dashboard thumbnails that render through a headless browser | Confirm the browser version works with your Superset release and your report workers | Adds a browser runtime and its system libraries, which enlarges the attack surface |
What the image must include for reports, caching and workers
Superset runs as several cooperating components, and the image you build has to serve each one that you deploy. Reports, thumbnails and async queries depend on the worker and caching layers as well as on a headless browser, so the web and worker images must agree on the same dependencies.
The Flask and React application
This is the web application that serves the UI and the API. Its image carries the Python packages Superset needs, the compiled frontend and the drivers for every database users will query. Any driver missing from this image fails at connection time for users, not at build time. Check that the web container starts with the same superset_config.py and dependency set you plan to run everywhere else.
The metadata database client
Superset stores dashboards, users, roles and permissions in a metadata database. Your image needs the client libraries for PostgreSQL or MySQL, the two databases the project tests for this role. The SQLite default is not recommended for production, so confirm the chosen metadata driver is present before you rely on a lean image for the web tier.
The caching layer
An optional caching layer, most often Redis, holds query results and other short-lived state. It is a separate service, so the image does not bundle it, but the Superset image must include the Python client that connects to it. Confirm the cache client library and the cache connection settings are identical in the web and worker images, or cache keys and locks will behave differently between them.
Celery workers and beat
Alerts, scheduled reports, async queries and thumbnail generation run in Celery worker processes, with beat scheduling the periodic jobs. The worker image must hold the same Superset code and configuration as the web image, plus any broker client. A worker built from a different tag than the web container is a common source of failed jobs that look like application bugs.
Playwright Chromium for rendering
Reports and dashboard thumbnails are rendered by a headless browser, which Superset drives through Playwright. The default image includes Playwright Chromium, while the lean image does not, so a lean base needs Chromium added deliberately. Confirm that the worker container can launch the browser and reach the web service over the internal network, because rendering fails quietly when either is missing.
Matching web and worker images
Every component that runs Superset code should come from one build with one pinned version. Tag the image once, deploy the same digest to the web, worker and beat containers, and test a scheduled report end to end before each upgrade. Record which image each process runs so that a rollback restores all of them together.
How to build the image step by step
The sequence starts from an official Superset image, adds only the drivers and browser components your deployment needs, and ends with a tagged image that has booted its web server and worker. Each step closes with a check so you know it is safe to move on.
Choose the base variant and Python version
Decide which official tag to extend before writing any Dockerfile. The Superset Docker builds documentation describes a default image with PostgreSQL and MySQL drivers, MCP dependencies and Playwright Chromium, a -lean image with no database drivers, a -dev image, and py311 and py312 variants. Pick the lean variant if you need only the drivers you install yourself, and the default if you want the bundled drivers and Chromium as a starting point. Record the exact tag and Python variant in your build notes. The check is that the tag resolves in your registry mirror and that the Python version matches what your drivers support.
Install database drivers with uv into a pinned environment
Extend the base image with a Dockerfile that installs only the drivers for your analytics databases, using uv to resolve them into the Superset environment. Pin each driver to an exact version and commit a lock file so that two builds on different days produce the same packages. Your data platform team or DeployOpen's engineers typically own this step, and the database owners should confirm the driver versions they support. The check is that a container started from the new image can import each driver and open a connection to a test database from the connection dialog or a short script.
Add Playwright Chromium only if reports need it
Alerts and reports that send screenshots of dashboards, and dashboard thumbnails where your version uses them, depend on a headless browser. If you need them, install Playwright Chromium and the system libraries it requires in the same layer order your base image expects, and confirm the version against the Superset documentation for your release. If reports are not in scope, skip this step and keep the lean path, which reduces the attack surface and image size. The check is that a rendering test inside the container produces a PNG of a sample page without missing shared library errors.
Move secrets and settings into environment variables
Do not bake the SECRET_KEY, database URIs, or OAuth credentials into the image. Superset requires a user-specified SECRET_KEY to start, so supply it at runtime from your secrets store and keep any configuration file generic. Copy superset_config.py into the image only as a template that reads environment variables. Keep PREVIOUS_SECRET_KEY in the runtime configuration for future rotation. The check is that the same image starts in two environments with different keys and database settings and that no secret value appears when you inspect the image history or run docker history.
Tag the image with the Superset version
Tag each build with the Superset version it contains, the Python variant, and the date-independent build identifier from your pipeline, such as the Git commit. Avoid relying on latest in any environment that promotes images. Keep the version tag aligned with the release notes you reviewed, so an upgrade later means building a new tag and not editing an existing one. The check is that the tag list in your registry shows one immutable tag per build and that the image digest recorded in your deployment manifest matches the one you tested.
Run a smoke test of the web server and worker
Start the image with the same environment variables production will use, then run the web server and, if reports or async queries are enabled, a Celery worker from the same image. Confirm that database migrations complete, that the login page responds, and that the worker connects to the broker and processes a test task. Use a metadata database that matches production, since the SQLite default is not recommended for production. The check is a healthy web response, a successful worker task, and no errors in the startup log about missing drivers, fonts or the browser.
Scan the image and record the result
Run a vulnerability scanner against the built image and against the base image, then review findings for the packages you added. Record which findings you accepted, which you fixed by rebuilding, and who approved each exception. Repeat the scan on a schedule because new vulnerabilities appear after a build is complete. The check is a stored scan report attached to the image tag, with no unreviewed critical findings in the packages you control and a clear owner for each accepted exception.
Pinning Superset, drivers and Python versions for repeatable builds
A production image is only repeatable if every input that can move is fixed: the base image, the Python variant, the driver packages, the Chromium build and the Superset version itself. A floating tag such as a branch name or a generic version label can resolve to different contents on the next build, so the reader should pin the base image by digest where their registry supports it and record the exact tag alongside it. Choose the Python variant deliberately. The Docker builds documentation describes py311 and py312 variants, and the choice should match the Python version your team tested in staging, not whatever the newest tag happens to be. Confirm which variants the chosen Superset release publishes before you commit to one.
Pin the packages you add yourself with a uv lockfile generated from your own requirements file, so the database drivers, Playwright and their transitive dependencies resolve to the same versions on every build. Commit the lockfile and install with the locked set rather than resolving fresh during the image build. Playwright's Chromium download is a separate version axis, so record the browser build that the pinned Playwright release expects and verify it after each build. Treat any change to these files as a reviewable change in Git, with the image digest and lockfile hash written into the build record so you can reproduce or roll back a specific image.
Rebuild on a schedule to pick up base image and operating system patches, but never let the schedule move Superset versions on its own. A scheduled job should rebuild from the same pinned inputs, scan the result and publish it only if the scan passes, and any change to the Superset version, the Python variant or a driver should arrive as a pull request. Upgrades are different. Moving to a new Superset release must follow the Superset upgrade guide and the breaking change notes in UPDATING.md, including a metadata database backup, running superset db upgrade and superset init, and testing in staging. A new tag alone is not an upgrade plan, and the pinned values should only change after those steps are complete.
Image strategy by deployment context
A team moving from a Compose stack or a virtual machine install usually wants one image that behaves like the old setup, with as few moving parts as possible. The default image already includes PostgreSQL and MySQL drivers and Playwright Chromium, so reports and dashboard thumbnails work without a second build. The -lean image is smaller, but every database driver then has to be added in your own derived layer, which adds a build step you must maintain.
- Start from the default image: Use it when your warehouses are PostgreSQL or MySQL and you want reports to work on day one.
- Move to lean only with a fixed driver list: Choose
-leanwhen the driver set is settled and you are willing to own the extra build. - Keep the metadata database outside the container: The project does not recommend the Compose PostgreSQL container for production, so point the image at an external PostgreSQL or MySQL instance.
- Pin the Python variant you tested: Select the
py311orpy312tag that matches the environment you validated, and keep it fixed between releases. - Carry configuration in mounted files: Mount
superset_config.pyand supplySECRET_KEYfrom the environment so the same image runs in every stage.
Before retiring the old install, confirm that scheduled reports, thumbnails and async queries behave the same in the container as they did on the virtual machine. The Docker builds documentation lists the tags and variants to compare against your current setup.
On Kubernetes, the image is one input among several that the cluster reconciles, so its tag, digest and dependencies need to match what the deployment manifests expect. The current development documentation marks the official Helm chart as deprecated and points new deployments to the Apache Superset Kubernetes Operator. The 6.1.0 documentation still describes the Helm chart, so confirm which document matches the Superset version you intend to run. The Operator is in alpha with a v1alpha1 API, and its custom resource schemas may change between releases, so every image change should be reviewed against the Operator version in use.
- Check the install path first: Compare the Kubernetes installation documentation for your version before choosing a tool.
- Pin the Operator version: Treat a change to the Operator as a planned change with its own test cycle, since alpha schemas may change.
- Reference images by digest: Put the tag and digest in the custom resource and avoid
latestso a rebuild cannot change a running release unnoticed. - Match cache and worker images: Redis and Celery components must run against the same Superset version as the web tier.
- Plan registry access: Confirm the cluster can pull the image from your registry and that pull secrets are managed like other credentials.
Before you build, read the Operator's release notes and confirm which image fields your version accepts. The Operator documentation is the reference for field names and upgrade notes.
In an air-gapped network, nothing can be fetched at install time or at upgrade time, so every layer of the image has to be decided in advance and carried across the boundary. The default image is convenient here because it already contains the PostgreSQL and MySQL drivers and Playwright Chromium. Any other database driver, Python wheel or browser asset has to be included in the build or mirrored separately before the transfer, because the isolated network cannot reach public package indexes later.
- Freeze the driver list before transfer: Every database connector needed for the next release must be in the image or in an internal package mirror before the build leaves the connected side.
- Bundle the browser at build time: Chromium used for reports and thumbnails must be present in the image, since the isolated network cannot download it when a report runs.
- Build on the connected side and scan there: Build and scan the image in a staging network, then move the artifact through your approved transfer process.
- Mirror the base image and dependencies: Keep a internal copy of the base image and every package the build pulls, with versions recorded.
- Plan offline upgrades: Each Superset upgrade needs a new mirrored image set and a review of breaking changes in UPDATING.md before the deployment changes.
Test the result from a machine with no route to the internet by pulling the image, starting the stack and running a scheduled report end to end. Confirm with your security team which transfer and scanning steps they require before the first build.
Scanning and hardening the image before it reaches production
A custom Superset image bundles your drivers, browser tooling and Python dependencies into one artifact, so it inherits every weakness in those layers. The cards below cover what to scan, what to strip from the runtime stage, and how the image is run and kept current. Confirm scanner choice, severity thresholds and exception handling with your security team before you set the gate.
Scan OS and Python packages
Run an image scanner against the final built image, not only the Dockerfile or requirements file. It should report operating system packages from the base image and Python packages installed by uv, including the Chromium dependencies pulled in for Playwright. Scan the default image and your lean variant separately, because they carry different package sets. Ask your security team which severities block a release, how findings in packages you do not call are handled, and who approves an exception with a dated justification. The scan result is only useful if it is tied to the exact image digest you deploy.
Strip build tools from the runtime
Use a multi-stage build so compilers, header packages and package caches stay in the builder stage. Only the virtual environment and the runtime libraries it needs should be copied into the final stage. Check the result by listing installed packages in the runtime image, looking for gcc, make or development headers that a driver install pulled in temporarily. Removing them shrinks the attack surface and keeps the scanner output focused on software you actually run.
Run as a non-root user
Create a dedicated unprivileged user in the image and set it with USER so the Superset process never starts as root. Make sure the application directory, the superset_config.py location and any writable cache paths are owned by that user, and that nothing else needs to be writable at runtime. Test this under your orchestrator's security context, such as a Kubernetes pod security setting that forbids root, because a build that works as root may fail once privileges are restricted. Verify with a running container, not just the Dockerfile.
Keep secrets out of layers
Anything written in a RUN step, including a token used to fetch a private driver package, stays in the image history even if a later step deletes it. Pass credentials as BuildKit secret mounts that are not persisted, and keep SECRET_KEY, database passwords and OAuth client secrets out of the Dockerfile and build arguments altogether. Inspect the result with docker history and a secret scanner before publishing. Load runtime secrets from the environment or a secrets manager at start, as described in the configuration guidance.
Pin versions and rebuild on schedule
Pin the Superset base tag, the Python variant, and each driver or package version in a lock file, so two builds from the same source produce the same dependency set. A pinned image still ages, so schedule rebuilds and rescans even when your code has not changed. Before adopting a new Superset release, read its upgrade notes and test the rebuilt image in staging with a backup of the metadata database. Record which digest runs in each environment so you can answer which image is exposed when a new advisory is published.
What to confirm with the Superset project and your own environment
Before you rely on any custom build, confirm the exact contents of the default image for the tag you plan to use. The current Docker builds documentation describes a default image that includes PostgreSQL and MySQL drivers, MCP dependencies and Playwright Chromium, alongside a -lean image without database drivers, a -dev image, and py311 and py312 variants. Those descriptions are the baseline, but the package set can change between tags, so read the build documentation for your exact tag rather than assuming the contents carried over from an earlier release. Record the list of drivers, Python packages and browser components in your build notes, because that list becomes the input to your own Dockerfile and to your scan policy.
Next, decide whether the MCP dependencies belong in your image at all. Confirm with the Superset project whether any feature you intend to use depends on them, and if none does, ask whether the lean or a custom base can omit them without breaking startup. Then check Chromium compatibility with your base operating system and container runtime. Reports and thumbnails rely on Playwright Chromium, so test a report render on the exact base image you will ship, including fonts and sandbox settings, rather than on a developer workstation. Confirm the Playwright and Chromium versions bundled for your tag with the project's documentation before you pin them.
Finally, check the status of the next release before planning around it. The GitHub releases page lists 7.0.0rc2 as a pre-release dated October 16, 2026. A release candidate can still change, so do not treat it as a stable target for a production image. Pin the release you have tested, subscribe to the project's release notes, and confirm with the project which final version will carry your upgrade path. Your environment questions matter as much: confirm whether your registry, scanner and CI system can reproduce the build from a pinned digest, and whether your security team accepts the browser and driver components in the scan results.
Questions teams ask before building a Superset image
How much effort does a production Superset image take to build?
Effort depends mostly on how many database drivers you need, whether you need Playwright Chromium for reports and thumbnails, and how strict your scanning policy is. A narrow image with one or two drivers and no report rendering is a small build. A wider image with several drivers, translations, fonts and a signed scan record takes more testing before it can be promoted. No duration figure is supplied for this work, so ask the partner to break the estimate into driver testing, rendering checks, scanning and documentation, and to state which of those are one-time.
What does a Superset image build cost, and who pays for what?
Your costs are the registry, build runners, scanning tooling and the staff time to review and approve each image. A partner's fee covers planning the base image choice, writing the Dockerfile and build pipeline, testing drivers and reports, and handing over the runbook. No price is published for this work, and no figure is supplied here. Ask for a written quote that lists the one-time build separately from recurring rebuilds, scans and version upgrades, and that names which driver and report tests are included.
Can an internal platform team build this image without a partner?
Yes, if your team already builds container images, manages Python dependencies and can run Superset in staging. The work that usually takes longest in-house is verifying each database driver against your real sources, confirming that Chromium renders reports correctly in your network, and setting a repeatable scan policy. Teams with no Superset experience often underestimate the upgrade work, which is covered in the project's upgrade guide and UPDATING.md notes. A partner is most useful when the team lacks capacity or needs a documented, reviewed build quickly.
What recurs after the first image is in production?
Recurring work includes rebuilding when the base image or Superset release changes, rescanning the image for new vulnerabilities, retesting drivers and reports, and updating pinned versions. Superset releases move quickly, and the project lists pre-releases alongside stable versions on its GitHub releases page, so pinning and a release-tracking routine matter. Ask any partner what retainer or support terms would cover these tasks and how they are priced, since ongoing support is offered as a retainer.
What does the client need to provide for the engagement?
You will need to name the metadata database and the analytics sources the image must reach, provide access to a staging Superset, and decide your registry and scanning policy. If the build runs on restricted networks, you must provide an internal package and image mirror, and confirm which Chromium and font sources are allowed. You also need an owner who can approve image promotion. Ask the partner to list these inputs in the written scope so gaps are visible before work starts.
How do air-gapped mirroring and scanning policy change the work?
They add steps and reviews. In an air-gapped network, every base image, Python package, driver and Chromium dependency must be mirrored and verified internally, and the build must run without outbound downloads. A scanning policy that blocks promotion on findings adds triage time, and each exception needs a recorded decision. Confirm with your security team which severity thresholds apply and who signs off exceptions before the scope is agreed.
What should we ask for in a written quote for this work?
Ask for a scope that names the base image variant, each database driver, the report and thumbnail requirements, translation or font needs, the scanning tool and policy, and the handover materials. Request a clear split between one-time build tasks and recurring rebuild, scan and upgrade tasks. Confirm which tests run in your environment, who performs them, what acceptance criteria apply, and what is excluded. Also ask how changes to the number of drivers would be handled after signing.
How DeployOpen approaches Superset image builds
DeployOpen starts every Superset image build by agreeing the scope in writing before any Dockerfile is written. The scope records which database drivers the image must carry, whether reports and thumbnails need Playwright Chromium, which translations and fonts are required, what network path the build and runtime have, and which vulnerability scanning policy the image must pass. Those decisions determine whether the base should be the default image, which includes PostgreSQL and MySQL drivers, MCP dependencies and Playwright Chromium, or the -lean image with no database drivers, and whether the Python 3.11 or 3.12 variant fits your support window. The Superset Docker builds documentation is the reference for those tags, and we confirm the exact tags against the release you plan to run before work begins.
The build happens in your container registry and your build infrastructure, so the image, its signing keys and its scan results stay under your control. We extend the chosen official base with only the drivers and packages the scope names, install Python dependencies with pinned versions, and test the result against your real metadata database, your query engines, a report run that exercises the headless browser and an upgrade rehearsal. Pins cover the base image digest, the Superset release, every added package and the Chromium build, and we document the rebuild procedure so your own engineers can repeat it. Confirm with us which registry, CI system and approval gates you require, because those choices change the handover steps.
Ongoing work is where most images drift, so DeployOpen also offers retainers for scheduled rebuilds when the base image or Superset releases, upgrade preparation against the release notes in UPDATING.md, and follow-up on scanner findings that need a patch, a version change or a documented exception. Ask for the rebuild cadence, the response expectations for critical findings and the named owner on each side in the written quote, since those terms set the recurring effort more than the first build does.
How DeployOpen works on this
DeployOpen plans, builds, documents and supports self-hosted open-source platforms inside your own infrastructure, including the Superset image work described on this page. Engagements start with a written scope, so the image contents, registry, scanning and handover are agreed before any build begins.
How we scope
- Inventory the database drivers, reporting dependencies and Python version your Superset users actually need.
- Decide with you between the default image, the lean image and a custom build, and record the reasons.
- Agree in writing the registry, tagging rules, scan gates and the version pinning policy before work starts.
How we build
- Build the image from a pinned official base with only the drivers and packages in the approved list.
- Install Python dependencies with uv from locked requirements so repeat builds resolve to the same packages.
- Test that Chromium-based reports and thumbnails run inside the image and that the metadata database connects.
How we hand over
- Deliver the Dockerfile, build pipeline, pinned version file and a short runbook for rebuilding the image.
- Document the scan results, known findings and the steps to rebuild when Superset or a driver is upgraded.
- Walk your platform and security teams through the image contents and the process for approving changes.
How we support
- Offer ongoing support, upgrades and continuous testing as a retainer, scoped separately from the build.
- Review new Superset releases and UPDATING.md breaking change notes before proposing an image update.
- Rebuild and rescan the image on a schedule you agree, and test each rebuild in staging before production.

