Skip to content

Selkies Baseimages

Repository: linuxserver/docker-baseimage-selkies ยท Registries: ghcr.io/linuxserver/baseimage-selkies, lsiobase/selkies

docker-baseimage-selkies is the packaging layer of the platform, the image every Webtop and single application container is built FROM. It assembles the whole runtime, the compositor stack, Selkies, pixelflux and pcmflux, Nginx, PulseAudio, GPU detection, hardening, and the LinuxServer.io s6 service machinery, so that a downstream image only has to install an application and say how to start it.

This page is the component overview. The Developer Guide covers building on it (Building Custom Images) and its internals in depth (Baseimage Internals).

Available distros

One branch and tag per base distribution, all for x86_64 and aarch64:

Distro Tag
Alpine alpine324
Arch arch
Debian debiantrixie
Fedora fedora44
Kali kali
Ubuntu ubunturesolute

There is deliberately no latest tag for base images. Downstream images pin a distro tag, for example FROM ghcr.io/linuxserver/baseimage-selkies:debiantrixie.

What is inside

  • The LSIO foundation: each tag builds on the corresponding LinuxServer.io distro baseimage, inheriting s6-overlay init, the abc user with PUID and PGID remapping, TZ, Docker mods, and the /custom-cont-init.d and /custom-services.d hooks.
  • Selkies (pinned commit) installed into the /lsiopy virtualenv, with pixelflux 2.x and pcmflux 2.x, plus Pelorus preinstalled.
  • The web client: prebuilt dashboards under /usr/share/selkies/, selected at runtime by the DASHBOARD variable.
  • Display servers for both stacks: labwc (built from source with a small IPC patch that adds the window query socket Pelorus uses) for Wayland, and an XLibre Xvfb built with glamor and DRI3 plus Openbox for X11. The Xvfb carries a LinuxServer patch that keeps the screen pixmap on the GPU and lets the framebuffer follow RandR resizes, which is what makes zero copy capture possible on X11. Both are prebuilt per distro in selkies-layers and copied into the image. A patched wlroots build makes the compositor survive pixman rendering faults instead of crashing.
  • Selkies Desktop at /usr/bin/selkies-desktop, activated by env var.
  • Nginx with the fancyindex module, serving the client, proxying the WebSocket, handling basic auth, subfolder support, and the /files download index.
  • PulseAudio with null sinks (output and input) wired for stream audio and microphone return.
  • Gamepad plumbing: the input interposer and fake udev libraries, preloaded globally, with device nodes created at init.
  • Quality of life: passwordless sudo for the desktop user, all system locales prebuilt for LC_ALL, proot-apps synced into the user home for persistent app installs, Docker in Docker support for privileged containers, and notification support.

The runtime in one diagram

graph TD
    subgraph s6 services
        NGINX[svc-nginx]
        PULSE[svc-pulseaudio]
        SELKIES[svc-selkies: the selkies server]
        DE[svc-de: startwm script]
        WD[svc-watchdog: RESTART_APP]
    end
    SELKIES -->|starts in process| PF[pixelflux Wayland compositor, socket wayland-1]
    DE -->|waits for wayland-1| LABWC[labwc or a full DE, exposes wayland-0]
    LABWC --> APP[autostart application]
    NGINX -->|3000 / 3001| WEB[web client, /api proxy, /pelorus]

At startup a chain of one shot init scripts configures everything from environment variables: Nginx substitution (ports, auth, subfolder, title), Wayland or X11 mode selection, first run copy of the autostart and menu defaults into /config, hardening (the HARDEN_* and DISABLE_* family), GPU detection and permission fixes, and gamepad device setup. Then the long running services above come up in dependency order.

The two session modes

  • Wayland: pixelflux hosts the virtual compositor; labwc (single apps) or a full desktop (Webtop flavors) nests on it. PIXELFLUX_WAYLAND=true is baked into images whose application or desktop runs on Wayland.
  • X11: XLibre Xvfb with glamor and DRI3 on :1, Openbox for single apps or the desktop's own window manager, and pixelflux capturing the GPU resident screen through DRI3. Selected with PIXELFLUX_WAYLAND=false, and the stack for applications and desktops that run best on X11.

Both stacks encode with zero copy on a GPU and share the same CPU encoders without one.

The downstream contract

A downstream image customizes the base by providing a handful of well known files:

File Purpose
/defaults/autostart_wayland and /defaults/autostart The command that launches your app (Wayland and X11 variants)
/defaults/menu_wayland.xml and /defaults/menu.xml The right click root menu
/defaults/startwm_wayland.sh and /defaults/startwm.sh Replace the whole session for full desktop images
/usr/share/selkies/www/icon.png The app icon used for the PWA and favicon

Plus ENV TITLE, and whatever packages the app needs. That is the entire interface, Building Custom Images walks through real examples.

Versioning and builds

Images rebuild on a weekly package check cadence and on baseimage changes, through the standard LinuxServer.io Jenkins pipeline. Each downstream repository (chromium, webtop, and the rest of the fleet) is triggered from its own upstream signal, app version bumps or OS package updates, so the whole catalog stays current without manual intervention.