Files
superset2/docker-compose.yml
Evan Rusackas 79eb91da96 fix(docker): make docker compose up build reliably
Three interlocking fixes so the full dev stack comes up cleanly:

1. Bind-mount Python package metadata (pyproject.toml, setup.py,
   MANIFEST.in, README.md) into /app in docker-compose.yml. Without
   these mounts, docker-bootstrap.sh's `uv pip install -e .` reads the
   stale metadata baked into the image at build time. After bumping
   apache-superset-core's sqlglot pin (>=28.10.0,<29), the bind mount
   ensures the editable install always sees the host's current pins
   instead of the image's older snapshot — which had been causing
   "apache-superset==0.0.0.dev0 depends on sqlglot>=27.15.2,<28" type
   resolver failures.

2. Bump @superset-ui/glyph-core's react peer from ^17.0.2 to ^18.2.0.
   Root and every other workspace package are on react 18; the
   stranded peer caused ERESOLVE during the in-container `npm install`
   (Docker doesn't use --legacy-peer-deps).

3. Restore the legacy-plugin-chart-partition multi-file plugin
   (controlPanel.tsx, transformProps.ts, index.ts) from master. They
   were missing on our branch; webpack resolves @superset-ui/legacy-
   plugin-chart-* via the tsconfig path mapping to plugins/.../src/,
   and without index.ts the partition entrypoint was unreachable.
   MainPreset.ts imports it.

Verified: docker compose down -v && docker compose build --no-cache &&
docker compose up brings the full stack up, /health returns OK, and
nginx serves the frontend on http://localhost/ (HTTP 302 login).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 00:19:40 -05:00

276 lines
9.0 KiB
YAML

#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# -----------------------------------------------------------------------
# We don't support docker compose for production environments.
# If you choose to use this type of deployment make sure to
# create you own docker environment file (docker/.env) with your own
# unique random secure passwords and SECRET_KEY.
#
# For verbose logging during development:
# - Set SUPERSET_LOG_LEVEL=debug in docker/.env-local for detailed Superset logs
# -----------------------------------------------------------------------
x-superset-user: &superset-user root
x-superset-volumes: &superset-volumes
# /app/pythonpath_docker will be appended to the PYTHONPATH in the final container
- ./docker:/app/docker
- ./superset:/app/superset
- ./superset-core:/app/superset-core
- ./superset-frontend:/app/superset-frontend
- superset_home:/app/superset_home
- ./tests:/app/tests
- superset_data:/app/data
# Python package metadata for the editable `uv pip install -e .` that
# docker-bootstrap.sh runs at container start. Without these bind mounts
# the editable install reads stale metadata baked into the image at
# build time and may conflict with apache-superset-core's current pins.
- ./pyproject.toml:/app/pyproject.toml
- ./setup.py:/app/setup.py
- ./MANIFEST.in:/app/MANIFEST.in
- ./README.md:/app/README.md
x-common-build: &common-build
context: .
target: ${SUPERSET_BUILD_TARGET:-dev} # can use `dev` (default) or `lean`
cache_from:
- apache/superset-cache:3.10-slim-trixie
args:
DEV_MODE: "true"
INCLUDE_CHROMIUM: ${INCLUDE_CHROMIUM:-false}
INCLUDE_FIREFOX: ${INCLUDE_FIREFOX:-false}
BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false}
services:
nginx:
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
image: nginx:latest
restart: unless-stopped
ports:
- "${NGINX_PORT:-80}:80"
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./docker/nginx/templates:/etc/nginx/templates:ro
redis:
image: redis:7
restart: unless-stopped
ports:
- "127.0.0.1:${REDIS_PORT:-6379}:6379"
volumes:
- redis:/data
db:
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
image: postgres:17
restart: unless-stopped
ports:
- "127.0.0.1:${DATABASE_PORT:-5432}:5432"
volumes:
- db_home:/var/lib/postgresql/data
- ./docker/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
superset:
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
build:
<<: *common-build
command: ["/app/docker/docker-bootstrap.sh", "app"]
restart: unless-stopped
ports:
- ${SUPERSET_PORT:-8088}:8088
# When in cypress-mode ->
- ${CYPRESS_PORT:-8081}:8081
extra_hosts:
- "host.docker.internal:host-gateway"
user: *superset-user
depends_on:
superset-init:
condition: service_completed_successfully
volumes: *superset-volumes
superset-websocket:
build: ./superset-websocket
ports:
- ${WEBSOCKET_PORT:-8080}:8080
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- redis
# Mount everything in superset-websocket into container and
# then exclude node_modules and dist with bogus volume mount.
# This is necessary because host and container need to have
# their own, separate versions of these files. .dockerignore
# does not seem to work when starting the service through
# docker compose.
#
# For example, node_modules may contain libs with native bindings.
# Those bindings need to be compiled for each OS and the container
# OS is not necessarily the same as host OS.
volumes:
- ./superset-websocket:/home/superset-websocket
- /home/superset-websocket/node_modules
- /home/superset-websocket/dist
# Mount config file. Create your own docker/superset-websocket/config.json
# for custom settings, then point to it here. Do not use this example in production.
- ./docker/superset-websocket/config.example.json:/home/superset-websocket/config.json:ro
environment:
- PORT=8080
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_SSL=false
superset-init:
build:
<<: *common-build
command: ["/app/docker/docker-init.sh"]
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
depends_on:
db:
condition: service_started
redis:
condition: service_started
user: *superset-user
volumes: *superset-volumes
healthcheck:
disable: true
superset-node:
build:
context: .
target: superset-node
args:
# This prevents building the frontend bundle since we'll mount local folder
# and build it on startup while firing docker-frontend.sh in dev mode, where
# it'll mount and watch local files and rebuild as you update them
DEV_MODE: "true"
BUILD_TRANSLATIONS: ${BUILD_TRANSLATIONS:-false}
environment:
# set this to false if you have perf issues running the npm i; npm run dev in-docker
# if you do so, you have to run this manually on the host, which should perform better!
BUILD_SUPERSET_FRONTEND_IN_DOCKER: true
NPM_RUN_PRUNE: false
SCARF_ANALYTICS: "${SCARF_ANALYTICS:-}"
# configuring the dev-server to use the host.docker.internal to connect to the backend
superset: "http://superset:8088"
# Webpack dev server must bind to 0.0.0.0 to be accessible from outside the container
WEBPACK_DEVSERVER_HOST: "0.0.0.0"
ports:
- "127.0.0.1:${NODE_PORT:-9000}:9000" # exposing the dynamic webpack dev server
command: ["/app/docker/docker-frontend.sh"]
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
volumes: *superset-volumes
superset-worker:
build:
<<: *common-build
command: ["/app/docker/docker-bootstrap.sh", "worker"]
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
environment:
CELERYD_CONCURRENCY: 2
restart: unless-stopped
depends_on:
superset-init:
condition: service_completed_successfully
user: *superset-user
volumes: *superset-volumes
extra_hosts:
- "host.docker.internal:host-gateway"
healthcheck:
test: ["CMD-SHELL", "celery -A superset.tasks.celery_app:app inspect ping -d celery@$$HOSTNAME"]
# Bump memory limit if processing selenium / thumbnails on superset-worker
# mem_limit: 2038m
# mem_reservation: 128M
superset-worker-beat:
build:
<<: *common-build
command: ["/app/docker/docker-bootstrap.sh", "beat"]
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
restart: unless-stopped
depends_on:
- superset-worker
user: *superset-user
volumes: *superset-volumes
healthcheck:
disable: true
superset-tests-worker:
build:
<<: *common-build
command: ["/app/docker/docker-bootstrap.sh", "worker"]
env_file:
- path: docker/.env # default
required: true
- path: docker/.env-local # optional override
required: false
profiles:
- optional
environment:
DATABASE_HOST: localhost
DATABASE_DB: test
REDIS_CELERY_DB: 2
REDIS_RESULTS_DB: 3
REDIS_HOST: localhost
CELERYD_CONCURRENCY: 8
network_mode: host
depends_on:
superset-init:
condition: service_completed_successfully
user: *superset-user
volumes: *superset-volumes
healthcheck:
test: ["CMD-SHELL", "celery inspect ping -A superset.tasks.celery_app:app -d celery@$$HOSTNAME"]
volumes:
superset_home:
external: false
db_home:
external: false
redis:
external: false
superset_data:
external: false