May 20, 2026
Running a Docker container with GUI on Fedora
A practical Fedora setup for running X11 GUI apps from a Docker container, including a working ROS Humble example and quick validation steps.
Running GUI apps from Docker on Fedora can be annoying because you usually need more than just -e DISPLAY=$DISPLAY.
For me, the following command worked with a ros:humble container:
docker run -it --rm \
--privileged \
--net=host \
--ipc=host \
-e DISPLAY=$DISPLAY \
-e QT_QPA_PLATFORM=xcb \
-e XAUTHORITY=/root/.Xauthority \
-v $HOME/.Xauthority:/root/.Xauthority:ro \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
ros:humble
What this setup is doing
-itkeeps the container interactive and attaches a TTY, which is useful when you want a shell and want to run test commands manually.--rmremoves the container after exit so you do not keep around disposable test containers.--privilegedgives the container broad access to host devices and kernel capabilities. It is much less restrictive than a normal container and can help when GUI, device, or shared-memory related permissions get in the way.--net=hostputs the container on the host network stack instead of an isolated Docker network. For desktop and ROS tooling, this can remove a whole class of networking issues.--ipc=hostshares the host IPC namespace with the container. Some GUI apps and ROS-related tools behave better with this because they can use the host shared-memory setup directly.-e DISPLAY=$DISPLAYtells GUI apps which X server display to connect to.-e QT_QPA_PLATFORM=xcbforces Qt apps to use the X11 backend through XCB. If you skip this, some Qt applications may pick an unsuitable platform plugin and fail to start correctly.-e XAUTHORITY=/root/.Xauthoritytells X11 clients inside the container where to find the authority file with the authentication cookie.-v $HOME/.Xauthority:/root/.Xauthority:romounts your host X11 authority file into the container so the root user inside the container can present the same cookie to the X server.-v /tmp/.X11-unix:/tmp/.X11-unix:rwshares the X11 Unix domain socket directory with the container so GUI apps can actually connect to the host X server.
This is not the most locked-down setup, but it is a practical one when the goal is simply to get a Linux GUI app running inside the container on Fedora.
What .Xauthority is
The .Xauthority file stores X11 authentication cookies.
When a GUI app wants to connect to your display, the X server does not just trust any local process automatically. It expects the client to present a matching cookie. That is why simply mounting /tmp/.X11-unix is often not enough on its own: the socket gives the container a path to the server, but .Xauthority gives it the credentials.
In this setup:
- the host file is
$HOME/.Xauthority, - it gets mounted into the container at
/root/.Xauthority, - and
XAUTHORITY=/root/.Xauthoritytells programs inside the container where to look.
That combination matters because the container is running as root, not as your host user.
One extra step I needed on Fedora
I also had to run this on the host:
xhost +SI:localuser:root
This command tells the X server:
allow the local user
rootto connect
The important part is SI:localuser:root:
SImeans server interpreted address,localuser:rootmeans the local Unix user namedroot.
This helped because the process inside the container was running as root, and from the X server’s point of view that local user access still mattered.
Even with .Xauthority mounted, X11 access control can still be the piece that blocks the connection. xhost +SI:localuser:root relaxes that policy specifically for the local root user, which is narrower and safer than something broad like xhost +.
If you want to remove that permission later, use:
xhost -SI:localuser:root
Test a simple GUI first
Before debugging your real app, test X11 itself.
If needed, run the xhost command on the host first:
xhost +SI:localuser:root
Inside the container:
apt update
apt install -y x11-apps
xclock
If xclock opens, the basic X11 path is working.
You can also try:
xeyes
That is a good sanity check before moving on to bigger GUI applications such as ROS tools.
If xclock or xeyes fails with an error like “Can’t open display” or an authorization error, the problem is usually one of these:
DISPLAYis wrong,.Xauthorityis missing or mounted to the wrong path,- or the X server is still denying access and needs the
xhost +SI:localuser:rootstep.
Why this is useful
When you are trying to run tools like rviz2, simulator frontends, or other desktop applications from a container, it helps to separate the problem into two parts:
- Can the container talk to the host display server?
- Does the actual application start once basic X11 access works?
That is why starting with xclock or xeyes is worth it. If those do not open, the issue is usually the display bridge, not the application itself.
Security note
This setup is useful for local development and testing, but it is intentionally permissive:
--privilegedgreatly expands what the container can do,--net=hostremoves network isolation,- and
xhost +SI:localuser:rootexplicitly grants X server access to local root.
That can be fine for a trusted local container you are debugging, but it should not be your default pattern for arbitrary images.
Final thought
If you are on Fedora and need a quick working baseline for Docker GUI apps, this command is a good starting point. It is especially useful when a plain docker run -e DISPLAY=$DISPLAY ... setup is not enough and you just want a containerized GUI to appear on screen first.