Linux - LXC; deploying images with tiniest possible X11

yes it is possible to run a complete X11 desktop environment inside a LXC container.

Right now, I do this on Arch Linux. I won't say it's "light" as I haven't gone as far as trying to strip out stuff from the standard package manager install but I can confirm that it does work very well.

You have to install any kernel drivers on the HOST as well as in the container. Such things as the graphics driver (I use nvidia). You have to make the device nodes in dev accessible inside the container by configuring your container.conf to allow it. You then need to make sure that those device nodes are created inside the container (i.e mknod).

So, to answer you question: YES it does work. If I can help any further or provide more details please do let me know.

--- additional infomation provided ---

In my container... /etc/inittab starts in run level 5 and launches "slim" Slim is configured to use vt09:

 # Path, X server and arguments (if needed)
 # Note: -xauth $authfile is automatically appended
 default_path        /bin:/usr/bin:/usr/local/bin
 default_xserver     /usr/bin/X
 xserver_arguments   -nolisten tcp vt09

I am not using a second X display on my current vt, but a completely different one (I can switch between many of thise using CTRL+ALT+Fn).

If you aren't using slim, you can use a construct like this to start X on another vt:

 /usr/bin/startx -- :10 vt10

That will start X on display :10 and put it on vt10 (CTRL+ALT+F10). These don't need to match but I think it's neater if they do.

You do need your container config to make the relevant devices available, like this:

 # XOrg Desktop
 lxc.cgroup.devices.allow = c 4:10 rwm    # /dev/tty10 X Desktop
 lxc.cgroup.devices.allow = c 195:* rwm  # /dev/nvidia Graphics card
 lxc.cgroup.devices.allow = c 13:* rwm   # /dev/input/* input devices

And you need to make the devices in your container:

 # display vt device
 mknod -m 666 /dev/tty10 c 4 10

 # NVIDIA graphics card devices
 mknod -m 666 /dev/nvidia0 c 195 0
 mknod -m 666 /dev/nvidiactl c 195 255

 # input devices
 mkdir  /dev/input           # input devices
 chmod 755 /dev/input
 mknod -m 666 /dev/input/mice c 13 63 # mice

I also manually configured input devices (since we don't have udev in container)

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

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

 Section "InputDevice"
     Identifier "Keyboard0"
     Driver "kbd"
     Option "XkbLayout" "gb"
 EndSection

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

The above going in a file /etc/X11/xorg.conf.d/10-input.conf

Not sure if any of that will help, but good luck!


Yes, you can do that. You can also use lxc.mount.entry so that you don't have to run the initialisation script inside the container with all the mknod commands. So lxc container's config should contain something like this:

lxc.cgroup.devices.allow = c 4:7 rwm
lxc.mount.entry = /dev/tty7 dev/tty7 none bind,optional,create=file
lxc.cgroup.devices.allow = c 4:8 rwm
lxc.mount.entry = /dev/tty8 dev/tty8 none bind,optional,create=file
lxc.cgroup.devices.allow = c 10:63 rwm
lxc.mount.entry = /dev/vga_arbiter dev/vga_arbiter none bind,optional,create=file
lxc.cgroup.devices.allow = c 13:* rwm
lxc.mount.entry = /dev/input dev/input none bind,optional,create=dir
lxc.cgroup.devices.allow = c 29:0 rwm
lxc.mount.entry = /dev/fb0 dev/fb0 none bind,optional,create=file
# /dev/dri/card0 AMD Graphics card
lxc.cgroup.devices.allow = c 226:0 rwm 
lxc.cgroup.devices.allow = c 226:64 rwm
lxc.cgroup.devices.allow = c 226:128 rwm
lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir
#lxc.cgroup.devices.allow = c 195:* rwm  # /dev/nvidia Graphics card
#lxc.mount.entry = /dev/nvidia0 dev/nvidia0 none bind,optional,create=file
#lxc.mount.entry = /dev/nvidiactl dev/nvidiactl none bind,optional,create=file
#lxc.cgroup.devices.allow = c 116:* rwm
#lxc.mount.entry = /dev/snd dev/snd none bind,optional,create=dir

To configure input devices for X, you can use evdev, which is especially usefull if you can't use the xf86-input-keyboard driver. Since the exact number of event* entries in the configuration file (e.g. /usr/share/X11/xorg.conf.d/10-lxc-input.conf) will depend on what is in your container's /dev/input/, you could use a script to generate one:

#!/bin/bash
cat >/usr/share/X11/xorg.conf.d/10-lxc-input.conf << _EOF_
Section "ServerFlags"
     Option "AutoAddDevices" "False"
EndSection
_EOF_

cd /dev/input
for input in event*
do
cat >> /usr/share/X11/xorg.conf.d/10-lxc-input.conf <<_EOF_
Section "InputDevice"
    Identifier "$input"
    Option "Device" "/dev/input/$input"
    Option "AutoServerLayout" "true"
    Driver "evdev"
EndSection
_EOF_
done

This should be enough for X to work:

/usr/bin/startx -- :0 vt07

You can also enable audio, either passing /dev/snd, or setting up pulseaudio via tcp or a socket.