Graphics with Xephyr fail to run on WSL2 / WSLg (read-only /tmp/.X11-unix)
Problem Description
Since WSLg mounts /tmp/.X11-unix/ as read-only, so Xephyr cannot create its UNIX domain socket /tmp/X11-unix/X*. As a result, Xephyr automatically falls back to abstract sockets @/tmp/.X11-unix/X*:
Xephyr :110 &
# _XSERVTransmkdir: Mode of /tmp/.X11-unix should be set to 1777
# _XSERVTransSocketCreateListener: failed to bind listener
# _XSERVTransSocketUNIXCreateListener: ...SocketCreateListener() failed
# _XSERVTransMakeAllCOTSServerListeners: failed to create listener for unix
ss -lx | grep X110
# u_str LISTEN 0 4096 @/tmp/.X11-unix/X110 603055 * 0
However, x11docker does not seem to detect this fallback, so:
- DISPLAY remains set to
:110 - containers cannot connect to the Xephyr server
- manual intervention is required (either TCP or socat bridging)
Workaround 1: Use --xoverip and manually fix DISPLAY
Test image:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y x11-apps
Launch Xephyr over TCP:
x11docker \
--xephyr \
--size=1280x720 \
--network \
--xoverip \
--no-entrypoint \
--display=110 \
--env=DISPLAY=host:110 \
-- --add-host=host:host-gateway -- \
ubuntu:test xeyes
This allows simple X apps (xeyes xclock icewm) to run correctly.
Workaround 2: Bridge abstract socket using socat
Start Xephyr and dump the generated environment file:
x11docker \
--xephyr \
--size=1280x720 \
--printenv=$HOME/.config/x11docker/xenv \
--display=110 \
--xonly
#Xephyr falls back to abstract unix socket: @/tmp/.X11-unix/X110
Bridge abstract socket ↔ file socket:
socat unix-listen:${HOME}/.config/x11docker/X110,fork,unlink-close \
abstract-connect:/tmp/.X11-unix/X110
Then launch the container using the bridged socket:
eval $(sed 's/\([A-Z_]*=\)/\n\1/g' ~/.config/x11docker/xenv | tail -n +2)
x11docker \
--hostdisplay \
--no-entrypoint \
-- -v ${HOME}/.config/x11docker/X110:/tmp/.X11-unix/X110 -- \
ubuntu:test xeyes
This also works reliably for simple X applications.
Desktop environments still fail (maybe due to my setup?)
Running a full desktop environment (e.g., XFCE) still fails on WSL2:
x11docker \
--xephyr \
--size=1280x720 \
--network \
--xoverip \
--desktop \
--display=110 \
--env=DISPLAY=host:110 \
-- --add-host=host:host-gateway -- \
x11docker/xfce
Typical errors:
Unable to launch "xfwm4": Failed to close file descriptor for child process (Operation not permitted)
Unable to launch "xfce4-panel": Failed to close file descriptor for child process (Operation not permitted)
Unable to launch "Thunar": Failed to close file descriptor for child process (Operation not permitted)
...
-
--debuglog is at: https://gist.github.com/eyespore/a7c95c4464de8acea9e85d089d8d873c -
--verboselog is at: https://gist.github.com/eyespore/ec3fda0a1d4b514829c77a000721505e
I'm not sure whether this is: an x11docker issue, a Xephyr limitation under WSL2 or simply my configuration problem. If you have any insight into whether full DEs are expected to work on WSL2 + Xephyr, that would be very helpful.
Summary
Since WSLg forces /tmp/.X11-unix/ into read-only mode, Xephyr always falls back to abstract sockets. At the moment, this requires manual fixes to make x11docker work.
Would it be possible for x11docker to:
- Detect WSL2 + read-only
/tmp/.X11-unix - If Xephyr falls back to abstract sockets, automatically switch to
--xoverip, or automatically adjustDISPLAY(e.g.,DISPLAY=host:110) - Optionally check if
socatis installed and automatically provide a bridged UNIX socket - Warn users when desktop environments are unlikely to work under WSL2
These adjustments might make x11docker much smoother to use on WSL2/Xephyr setups.
Thanks a lot for your work on x11docker! I'd be happy to provide more logs or test patches if needed.
Environment
- Windows 10 WSL2 with WSLg enabled
- Distribution inside WSL2: Ubuntu 20.04
- Docker version: 27.1.1, build 6312585
- x11docker version: 7.7.2-beta