# docker-superset: a pinned container image for running Apache Superset

> amancevice/docker-superset packages Superset into a Docker image with fixed Python dependencies, gunicorn environment defaults and a defined volume layout. It is an unofficial packaging project, and the maintainer advises extending the published image rather than building the bundled Dockerfile.

**amancevice/docker-superset** — Docker image for Airbnb's Superset

- Repository: https://github.com/amancevice/docker-superset
- Website: https://hub.docker.com/r/amancevice/superset/
- Stars: 993 · Forks: 412
- Language: Dockerfile
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/amancevice-docker-superset

## What the image is: a Python base with gunicorn defaults baked in

This repository is not a fork of Superset and not a plugin. It is a Dockerfile that assembles the upstream project into a runnable image, and the README says so directly: this project is unofficial and not related to Superset or Apache. The repository's primary language is listed as Dockerfile, and the top-level files are a Dockerfile, a Pipfile with its lock, generated requirements files, a Makefile and an examples directory.

The build starts from a versioned Python image, with the version passed in as a build argument:

```dockerfile
ARG PYTHON_VERSION=3.12
FROM python:$PYTHON_VERSION
```

The Makefile reads the target Python version from a .python-version file and the Superset version out of the Pipfile with a grep, then passes both into a buildx build for linux/arm64. That single platform value is worth noticing: the build target in the Makefile is arm64 only, so producing an amd64 image is not something the committed build recipe does for you.

What you get as a user is a container where the application runs under gunicorn with a known set of defaults, and where the upstream dependency set has been frozen into requirements.txt. The pinned list includes apache-superset==6.1.0 along with the surrounding libraries, each pinned to an exact version.

## The gunicorn environment block is the tuning surface

The Dockerfile sets the process configuration through environment variables rather than a config file, and it sets them to the values the upstream documentation recommends for gunicorn. Reading that block tells you what the container will do before you change anything:

```dockerfile
ENV GUNICORN_BIND=0.0.0.0:8088
ENV GUNICORN_THREADS=4
ENV GUNICORN_TIMEOUT=120
ENV GUNICORN_WORKERS=10
ENV GUNICORN_WORKER_CLASS=gevent
```

Ten gevent workers with four threads each, a request timeout of 120 seconds, and a bind address on port 8088. The full command line is assembled in GUNICORN_CMD_ARGS from the same individual variables, so overriding one of the individual environment variables at run time is enough to change the corresponding part of the command.

FLASK_APP is set to superset, and the image also pins the locale to C.UTF-8. That last detail matters more than it looks: a Superset instance that renders a dashboard with non-ASCII labels needs a locale that can encode them, and the container already sets one rather than inheriting whatever the host has.

The consequence for an operator is that the image is opinionated about the serving layer, and the knobs are environment variables you pass at run time. Nothing in the README describes a gunicorn configuration file, so overriding the worker class or worker count is done through those variables.

## Configuration reaches the app through PYTHONPATH, not through a config volume alone

Superset reads a Python configuration file, and the image makes that file discoverable by directory rather than by a dedicated environment variable pointing at one file. The Dockerfile sets the search path to two directories:

```dockerfile
ENV PYTHONPATH=/etc/superset:/home/superset
```

The README's configuration section tells you to follow the upstream Apache Superset instructions for writing your own superset_config.py, then place that file in a local directory and mount it to /etc/superset inside the container. It also notes that mounting to a different location works, provided the target is on the PYTHONPATH.

That is the whole configuration model: a file, a directory, and a path list. It also means the image accepts configuration at two locations, and the README states that both /etc/superset and /home/superset are included in the PYTHONPATH of the image. In practice one of them will hold your file and the other will sit empty, and the practical risk is that a configuration file placed in the wrong directory is silently not loaded.

Examples for MySQL, PostgreSQL and SQLite live in the examples directory, along with a demo script and a celery directory, so the common database choices have worked examples you can copy rather than write from scratch.

## Two volumes: one for config, one for data under SUPERSET_HOME

The image declares three VOLUME directives but describes them as two data volumes, one for configuration and one for data. The configuration location is acceptable at either /etc/superset or /home/superset, and the data location is fixed:

```dockerfile
VOLUME /etc/superset
VOLUME /home/superset
VOLUME /var/lib/superset
```

The data volume sits at /var/lib/superset and is the value of the SUPERSET_HOME environment variable. This is where you mount the SQLite file if SQLite is your backend, and where you would mount a volume if you want logs collected there.

The three VOLUME lines create a practical trap worth calling out. Declaring both /etc/superset and /home/superset as volumes means Docker will populate each with the image's directory contents on first run, and the two directories are on the same PYTHONPATH. If you mount your configuration at /etc/superset and the container's own copy of anything in /home/superset is also present, you have two candidate configuration sources. The README does not describe a precedence rule, so mount one and leave the other alone.

The data volume matters for a different reason. If you run SQLite, the database file lives inside the container's filesystem unless you mount this path, and losing it on a container replacement means losing your dashboard definitions.

## First run: start the container, then run superset-init

The database is not initialised by starting the server. The README describes a two-step sequence, first running the container and then executing the helper script against it:

```bash
docker run --detach --name superset [options] amancevice/superset
docker exec -it superset superset-init
```

The helper script is what creates the admin user and the Superset tables. The README notes that the script is available through the bin directory, which the Dockerfile copies into /usr/local/bin, so superset-init is on the PATH inside the container rather than being a file you have to locate.

The [options] in that run command are where your own environment and volume mounts go, and the README is explicit that the correct environmental configuration has to be in place. Before the first start, decide three things: which database backend you use, where superset_config.py is mounted, and whether /var/lib/superset holds a persistent volume. Getting the mount wrong on the first run is the most common way to end up with an empty Superset that appears to have lost its configuration.

One security note that follows from the Dockerfile rather than the README: the container creates a dedicated superset user and chowns the home, config and data directories to it, so a mounted volume must be writable by that user for SQLite to work at all.

## Upgrading is a pull, a replace, and two exec commands

The upgrade path is spelled out as an ordered procedure, and it is the part of this project most likely to cost you time if you skip a step. You pull the target version, remove the old container, deploy a new one, migrate the database, and resync base permissions:

```bash
docker pull amancevice/superset
docker rm -f superset-old
docker run --detach --name superset-new [options] amancevice/superset
docker exec superset-new superset db upgrade
docker exec superset-new superset init
```

The README names the final step as syncing the base permissions, which matters after a version change because new Superset versions can add permissions that existing roles do not yet have.

Note what this procedure does not include. There is no rollback step, no backup command, and no mention of what to do if superset db upgrade fails halfway. A failed migration on a SQLite database means the schema is partially migrated and the old container is already gone, so the sensible practice is to copy the /var/lib/superset volume aside before running the sequence, even though the README does not ask you to.

Tag selection is a second decision. The README explains that this repository is tagged in parallel with Superset, so pulling amancevice/superset:0.18.5 fetches the image running Superset 0.18.5, and that the latest tag may include new features or support libraries but will usually be in sync with the latest semantic version. The recent releases in this repository follow a calendar style, with v6.1.2026.8.31 published on 2026-08-31 after v6.1.2026.6.2 and v6.0.2025.12.22, so the tag encodes both the Superset series and the build date.

## The maintainer would rather you extend the image than build it

The building section of the README carries an unusual instruction: the author does not recommend building this image directly from the Dockerfile included in the repository. The recommended path is to write your own Dockerfile that extends the published image, and the README shows the pattern:

```dockerfile
FROM amancevice/superset:<version>
USER root
# Your changes...
USER superset
```

The switch to root and back to the superset user around your changes is the part to copy carefully, because the image runs its application as a non-root user and a custom layer that stays as root would quietly change the security posture of the container.

This is a clear trade-off rather than an oversight. The Dockerfile pins an exact dependency set and includes system libraries for several database backends, including MySQL, PostgreSQL and LDAP support, so rebuilding it is work. But a project that discourages its own build path also means the reproducibility story is weaker: the committed Dockerfile is a reference, while the artefact most people run is the published one, built by someone else.

The issue policy follows the same split. The README asks that issues be filed only for Docker-related problems, that they include the Docker commands or compose configuration of the setup, and that secrets be hidden before submitting. Anything about Superset itself belongs in the upstream repository, and requests to add a Python package to the Dockerfile are directed to a pull request rather than an issue.

## Conclusion

docker-superset fits a team that wants Superset running in a container without resolving its Python dependency tree by hand, and it does not fit a team that needs image rebuilds for custom dependencies, because the maintainer states plainly that building from the bundled Dockerfile is not recommended. Verify three things before you commit: that the tag naming still matches the Superset version you need, that your own superset_config.py loads from /etc/superset where the image expects it, and that superset db upgrade and superset init both succeed against a copy of your metadata database. The repository is MIT licensed and the last push was on 2026-08-31, with tagged releases tracking upstream Superset releases through v6.1.2026.8.31.

## FAQ

### How do I pull and start the docker-superset image?

Pull a specific version with docker pull amancevice/superset:<version>, or start a container with docker run --detach --name superset [options] amancevice/superset. The README notes that the latest tag will usually be in sync with the latest Superset semantic version.

### How do I create the admin user and tables in docker-superset?

Start the server first, then run the helper script inside the container with docker exec -it superset superset-init. The bin directory is copied into /usr/local/bin by the image, so superset-init is on the PATH.

### Where do I mount superset_config.py in docker-superset?

Place your superset_config.py in a local directory and mount it to /etc/superset inside the container. Mounting elsewhere is possible, but the target directory has to be on the image's PYTHONPATH, which is set to /etc/superset:/home/superset.

### What is the difference between the configuration and data volumes?

The configuration volume at /etc/superset or /home/superset holds superset_config.py, while the data volume at /var/lib/superset is the value of SUPERSET_HOME and is where a SQLite file or collected logs belong. The image declares VOLUME for all three paths.

### How do I upgrade an existing docker-superset deployment?

The README gives the sequence: pull the desired version, remove the old container, deploy a new one with the same environmental configuration, then run superset db upgrade and superset init inside the new container. The README does not describe a rollback procedure.

## Sources

- [amancevice/docker-superset on GitHub](https://github.com/amancevice/docker-superset)
- [License: MIT](https://github.com/amancevice/docker-superset/blob/main/LICENSE)
- [Project website](https://hub.docker.com/r/amancevice/superset/)
- [README](https://github.com/amancevice/docker-superset/blob/main/README.md)
- [Releases](https://github.com/amancevice/docker-superset/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/amancevice-docker-superset
