6

I want to create a docker image for a GUI application (e.g. Chrome) and I hope this GUI app could run at a bare Linux server without X server installed.

I know it is very easy to create and run a docker image just for X Window Client (The GUI application itself). This needs X server be installed and run at host.

sudo docker run -ti -v /tmp/.X11-unix:/tmp/.X11-unix xorg xterm -display :0

But for me, I need both X client and server run in docker container.

Here's my dockerfile:

FROM ubuntu:14.04
RUN apt-get update && apt-get install -y xorg

And I run the image by command:

sudo docker run -i -t --rm -e DISPLAY=:0 --privileged xorg xinit

The X server could be started and my screen turns black, after a few seconds, the xterm window displays. BUT, I can't use keyboard and mouse. The screen seems like freezen

I have searched and tried many solutions but no one could fix this problem. (the virtual x-server is not I needed)

Kriss
  • 111
  • 1
  • 5
  • Possible duplicate of [can you run GUI apps in a docker container?](http://stackoverflow.com/questions/16296753/can-you-run-gui-apps-in-a-docker-container) – Mark O'Connor Nov 07 '15 at 17:29
  • 1
    Thanks Mark! But I don't need either run a GUI app in docker container connected with host x-server, or a virtual x-server in container. – Kriss Nov 07 '15 at 17:46
  • I want the GUI app display on host's physical monitor, and both GUI app and x-server in docker container – Kriss Nov 07 '15 at 17:47
  • Don't know how possible that would be. It would certainly require you to run the container in privileged mode, which sort of defeats the entire purpose. What's wrong with installing a desktop distribution of linux instead? Back in the day when Linux didn't support a lot of the available video cards I used to run VNC to avoid the hassle of installing X. I then used the vnc client on my windoze machine (or the webclient within a browser). It really was a compelling virtual desktop setup that was ahead of its time. – Mark O'Connor Nov 07 '15 at 17:57
  • 1
    Docker is the easiest way of deploying a complex system on linux I've ever met. If the whole x system including client and server are in same docker image, then any user has any linux distribution with docker installed should run the GUI application very easily. I know someone has successfully done this by LXC. So why can't it be done by docker? Now the x server in docker container works well with video card in privileged mode, just need one more thing, the input devices - keyboard and mouse. – Kriss Nov 07 '15 at 18:26
  • Interesting. I'm surprised it gets that far. Linking up input might be tricky, but it could just be a case of mounting the right files and devices. – Adrian Mouat Nov 07 '15 at 21:06
  • I did find this: https://unix.stackexchange.com/questions/191289/docker-how-to-run-x-desktop-in-a-container. I don't think this will be easy, if it is possible. – Adrian Mouat Nov 07 '15 at 21:11
  • succeed :) just modify x-org conf – Kriss Nov 09 '15 at 16:24

2 Answers2

5

I have resolved this problem.

At first, I thought maybe x server in docker container cannot access host devices, and I spent much time on LXC/cgroup. For example, I changed the docker exec engine to LXC, and I added option '--lxc-conf='lxc.cgroup.devices.allow = c 13:* rwm', and I also created /dev/input/* in container.

All of these operations are unnecessary.

If we run docker container in privileged mode, all host devices will be added automatically. Or we can use options like '--device=/dev/input/mice' to share host device.

The real problem is that x server could not discovery and add device automatically. I don't know why. But we could modify x server's configuration and customize the device.

add file /etc/X11/xorg.conf.d/10-input.conf

 Section "ServerFlags"
     Option "AutoAddDevices" "False"  
 EndSection

 Section "ServerLayout"
     Identifier     "Desktop"
     InputDevice    "Mouse0" "CorePointer"
     InputDevice    "Keyboard0" "CoreKeyboard"  
 EndSection

 Section "InputDevice"
     Identifier "Keyboard0"
     Driver "kbd"
     Option "Device" "/dev/input/event2" 
 EndSection

 Section "InputDevice"
     Identifier "Mouse0"
     Driver "mouse"
     Option "Protocol" "auto"
     Option "Device" "/dev/input/mice"
     Option "ZAxisMapping" "4 5 6 7"  
 EndSection

and run docker container:

docker run -i -t -v /tmp/.X11-unix:/tmp/.X11-unix --rm --privileged ubuntu startx
c4pQ
  • 884
  • 8
  • 28
Kriss
  • 111
  • 1
  • 5
2

At first make sure that proper input modules are installed:

RUN DEBIAN_FRONTEND='noninteractive' apt-get install -y --no-install-recommends xserver-xorg-input-evdev xserver-xorg-input-all

In modern Linux udev is responsible for managing device nodes (including USB keyboards) in the /dev tree. It uses /run/udev/data which isn't available inside your container even with -privileged option.

So you need to mount that folder explicitly using -v /run/udev/data:/run/udev/data like this:

docker run -i -t -v /tmp/.X11-unix:/tmp/.X11-unix --rm --privileged  -v /run/udev/data:/run/udev/data ubuntu startx
bedrin
  • 4,458
  • 32
  • 53
  • I've been stuck on this for over an hour, the only thing I had to do was add `-v /run/udev/data:/run/udev/data` to the `extra parameters` in my unraid docker container to fix it. Thanks! – xorinzor Dec 18 '21 at 10:05
  • 1
    Instead of `--privileged` use `--cap-add SYS_TTY_CONFIG --device /dev/input --device /dev/dri --device $(tty)` – mviereck Jun 08 '22 at 18:40