Spyder in Docker on Wayland
This stack packages the Spyder IDE inside a Docker container and supports both native Wayland and optional X11 fallback sessions on Linux desktops. Two workflows are available:
- Normal usage – pull the published image
git.maxboeer.com/schmax/spyder-desktop-docker:latestand run it with the runtime compose file. - Development – build the image locally, tweak dependencies, and (optionally) publish your own tag.
Normal Usage (recommended)
-
Install Docker (Compose v2 included) on your Linux workstation.
-
Clone or download this repository (or just grab
compose.runtime.yamland the.envexample below). -
Create a
.envfile alongsidecompose.runtime.yamland adapt the values to your system:UID=1000 GID=1000 HOST_USER=spyder HOST_GROUP=spyder SPYDER_HOME=/home/spyder SPYDER_WORKSPACE=/home/spyder/workspace SPYDER_HOME_VOLUME=./spyder-home SPYDER_WORKSPACE_VOLUME=./spyder-workspace XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-1 DISPLAY=:0 SPYDER_IMAGE=git.maxboeer.com/schmax/spyder-desktop-docker:latest DEBUG=0Adjust
UID,GID,XDG_RUNTIME_DIR,WAYLAND_DISPLAY, andDISPLAYto match your desktop session. -
Create the bind-mount folders (only needed once):
mkdir -p spyder-home spyder-workspace -
Launch Spyder using the runtime compose file:
docker compose -f compose.runtime.yaml upSpyder will open on your desktop. Stop it with
Ctrl+Cwhen done. For an X11 fallback, add--profile x11to the command.
Example compose.runtime.yaml
services:
spyder-wayland:
image: ${SPYDER_IMAGE}
environment:
UID: "${UID}"
GID: "${GID}"
HOST_USER: "${HOST_USER}"
HOST_GROUP: "${HOST_GROUP}"
SPYDER_HOME: "${SPYDER_HOME}"
SPYDER_WORKSPACE: "${SPYDER_WORKSPACE}"
HOME: "${SPYDER_HOME}"
WAYLAND_DISPLAY: "${WAYLAND_DISPLAY}"
XDG_RUNTIME_DIR: "${XDG_RUNTIME_DIR}"
QT_QPA_PLATFORM: "wayland"
QTWEBENGINE_DISABLE_SANDBOX: "1"
QTWEBENGINE_CHROMIUM_FLAGS: "--no-sandbox"
TZ: "Europe/Berlin"
volumes:
- ${SPYDER_HOME_VOLUME}:${SPYDER_HOME}
- ${SPYDER_WORKSPACE_VOLUME}:${SPYDER_WORKSPACE}
- ${XDG_RUNTIME_DIR}:${XDG_RUNTIME_DIR}
working_dir: ${SPYDER_WORKSPACE}
devices:
- "/dev/dri:/dev/dri"
shm_size: "1gb"
restart: "no"
spyder-x11:
profiles:
- "x11"
image: ${SPYDER_IMAGE}
environment:
UID: "${UID}"
GID: "${GID}"
HOST_USER: "${HOST_USER}"
HOST_GROUP: "${HOST_GROUP}"
SPYDER_HOME: "${SPYDER_HOME}"
SPYDER_WORKSPACE: "${SPYDER_WORKSPACE}"
HOME: "${SPYDER_HOME}"
DISPLAY: "${DISPLAY}"
QT_QPA_PLATFORM: "xcb"
QT_X11_NO_MITSHM: "1"
QTWEBENGINE_DISABLE_SANDBOX: "1"
QTWEBENGINE_CHROMIUM_FLAGS: "--no-sandbox"
TZ: "Europe/Berlin"
volumes:
- ${SPYDER_HOME_VOLUME}:${SPYDER_HOME}
- ${SPYDER_WORKSPACE_VOLUME}:${SPYDER_WORKSPACE}
- /tmp/.X11-unix:/tmp/.X11-unix:ro
working_dir: ${SPYDER_WORKSPACE}
devices:
- "/dev/dri:/dev/dri"
shm_size: "1gb"
restart: "no"
Development Workflow (build locally)
Use this path if you need to modify the Docker image or publish your own tag.
-
Adjust
.envto match your host (and optionally changeLOCAL_IMAGE_NAME). -
Ensure
spyder-home/andspyder-workspace/exist. -
Build and launch Spyder directly from the source tree:
docker compose upAdd
--profile x11for the X11 fallback. -
To publish your build to a registry:
docker login git.maxboeer.com chmod +x build-and-push.sh ./build-and-push.shThe script uses Buildx to build
linux/amd64andlinux/arm64variants and pushes to theSPYDER_IMAGEdeclared in.env. You can enable non-interactive login by exportingREGISTRY_HOST,REGISTRY_USER, andREGISTRY_TOKENbefore running the script.
Environment Variables
Key settings live in .env:
UID,GID,HOST_USER,HOST_GROUP– mirror the host user to preserve file ownership.SPYDER_HOME,SPYDER_WORKSPACE– container paths for the Spyder home and project workspace.SPYDER_HOME_VOLUME,SPYDER_WORKSPACE_VOLUME– host-side bind mounts for persistence (can be absolute or relative paths).LOCAL_IMAGE_NAME– tag applied to locally built images viadocker compose build.SPYDER_IMAGE,BUILDX_PLATFORMS,BUILDX_BUILDER_NAME– registry target and buildx configuration used bybuild-and-push.sh.XDG_RUNTIME_DIR,WAYLAND_DISPLAY,DISPLAY– display/socket paths exported from the host session.DEBUG– placeholder for future debug toggles.
Update .env values to relocate persisted data or point to non-standard display sockets.
Example .env
UID=1000
GID=1000
HOST_USER=spyder
HOST_GROUP=spyder
SPYDER_HOME=/home/spyder
SPYDER_WORKSPACE=/home/spyder/workspace
SPYDER_HOME_VOLUME=./spyder-home
SPYDER_WORKSPACE_VOLUME=./spyder-workspace
XDG_RUNTIME_DIR=/run/user/1000
WAYLAND_DISPLAY=wayland-1
DISPLAY=:0
LOCAL_IMAGE_NAME=spyder-conda
SPYDER_IMAGE=gitea.example.com/max/spyder-wayland:latest
BUILDX_PLATFORMS=linux/amd64,linux/arm64
BUILDX_BUILDER_NAME=spyder-buildx
DEBUG=0
Example docker-compose.yml
services:
spyder-wayland:
image: ${SPYDER_IMAGE}
environment:
UID: "${UID}"
GID: "${GID}"
HOST_USER: "${HOST_USER}"
HOST_GROUP: "${HOST_GROUP}"
SPYDER_HOME: "${SPYDER_HOME}"
SPYDER_WORKSPACE: "${SPYDER_WORKSPACE}"
HOME: "${SPYDER_HOME}"
WAYLAND_DISPLAY: "${WAYLAND_DISPLAY}"
XDG_RUNTIME_DIR: "${XDG_RUNTIME_DIR}"
QT_QPA_PLATFORM: "wayland"
QTWEBENGINE_DISABLE_SANDBOX: "1"
QTWEBENGINE_CHROMIUM_FLAGS: "--no-sandbox"
TZ: "Europe/Berlin"
volumes:
- ${SPYDER_HOME_VOLUME}:${SPYDER_HOME}
- ${SPYDER_WORKSPACE_VOLUME}:${SPYDER_WORKSPACE}
- ${XDG_RUNTIME_DIR}:${XDG_RUNTIME_DIR}
working_dir: ${SPYDER_WORKSPACE}
devices:
- "/dev/dri:/dev/dri"
shm_size: "1gb"
spyder-x11:
profiles:
- "x11"
image: ${SPYDER_IMAGE}
environment:
UID: "${UID}"
GID: "${GID}"
HOST_USER: "${HOST_USER}"
HOST_GROUP: "${HOST_GROUP}"
SPYDER_HOME: "${SPYDER_HOME}"
SPYDER_WORKSPACE: "${SPYDER_WORKSPACE}"
HOME: "${SPYDER_HOME}"
DISPLAY: "${DISPLAY}"
QT_QPA_PLATFORM: "xcb"
QT_X11_NO_MITSHM: "1"
QTWEBENGINE_DISABLE_SANDBOX: "1"
QTWEBENGINE_CHROMIUM_FLAGS: "--no-sandbox"
TZ: "Europe/Berlin"
volumes:
- ${SPYDER_HOME_VOLUME}:${SPYDER_HOME}
- ${SPYDER_WORKSPACE_VOLUME}:${SPYDER_WORKSPACE}
- /tmp/.X11-unix:/tmp/.X11-unix:ro
working_dir: ${SPYDER_WORKSPACE}
devices:
- "/dev/dri:/dev/dri"
shm_size: "1gb"
GPU Acceleration
The configuration keeps GPU acceleration enabled. The container shares /dev/dri with the host; if you run into driver issues, temporarily comment out the device mapping and set QTWEBENGINE_CHROMIUM_FLAGS or QT_OPENGL in compose.yaml to fall back to software rendering.
Notes
- The entrypoint (
start-spyder.sh) creates a user matching the host UID/GID at runtime and cleans up stale Spyder lock files before launching the IDE. - Python dependencies are managed via
micromambausingenvironment.yml. - Shared memory is increased to 1 GB to satisfy QtWebEngine requirements.