If you google around on how to configure containers as a desktop you might notice varying opinions. From adolecent bunny trail uber complex bind mounting nonsense to sage advice on how you should immediately cease and desist your Quixotic quest. The INSECURITY! -- The HUMANITY!
For sure, by a wide margin containers are configured for cloud implementations on public servers where security is of paramount importance. The administrators of said clouds would never dream of running one as a desktop solution.
For those who can't get over their security nightmares please consider; how is it any less secure to run a desktop in a container than doing so bare naked on the host?
Surely there is a modicum of security benefit to be had by running one in a container.
Being that as it may. Security is not the driving force for wanting to consolidate my desktop usage in a container. But convevience and portability. I'm less concerned about security breaches on my local network. I just want to maintain a simplified consistant desktop experience across multiple host environments.
SlackBuilder provides several options for running a desktop in a container.
- Vnc: via vncviewer and/or NoVnc (web access). These are the best remote solutions.
- Xephyr: there are a couple of solutions utilizing this option for quick remote access. However Xephyr is buggy and has issues with fonts and displaying video. It is also painfully slow over wifi networks.
- Native X: This one allows for GLX 3d graphics support. It is meant to run on the host of the container as it is usless over wifi.
Vnc and Xephyr are not real desktop solutions. They are useful in their own right but for the purposes of this article we want to focus on running a real desktop.
These intructions assume the following...
- Container: A complete desktop installation with an xdm login manager.
- Host: A working lxc environment complete with a bridged virtual network and at least an Xorg server. A full desktop system is not required. However for audio to work pulseaudio should be present.
- Video card: The setup here is expecting the standard intel video card. Special consideration for Nvidia or ATI cards are not discussed. If you have one of these cards you will need to install the appropriate modules etc... and configure your system to use them.
Note: If using Slackbuilder as the host you can build a Slackbuilder container with a simple command that will pre-configure the container for you. The hosts pulseaudio default.pa file will still need to be edited manually though.
XIT=1 ve add cname
Where ve is a command that manages containers. XIT stands for X it and tells the lxc-slackbuilder template to insall a desktop system. And cname is the name of the container.
The environment variable XIT is used here instead of simply X because apparantly X is already defined somewhere within the official lxc scripts. Re-defining it on the command line caused intallation failure.
You can learn more about SlackBuilders virtual solutions here.
For non Slackbuilder users. Once you have your container up and running its time to edit its xdm-config and Xaccess files. On Slackware they are located in /etc/X11/xdm. On other distributions the location of these files may vary.
For xdm-config comment out the following line with an !...
! DisplayManager.requestPort: 0
And for Xaccess uncomment...
#* #any host can get a login window
* #any host can get a login window
Now start the xdm server. Additionally consider adding this service to the container bootup scripts.
To get audio working we need to edit the default.pa file as we are running pulseaudio on a per user basis not as a system service. On Slackware it will be in /etc/pulse/. Again, on other distros location may vary.
There are two ways to handle the sound.
- Redirect the container users pulseaudio server to use the hosts directly. This is the best solution for the native X implementation.
- Use RTP unicasting to the host. Good for re-routing audio to a sound server etc...
We're going to use the redirect option for our purposes. Either way both options need the following line added to the container default.pa file.
For the host add...
load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;10.0.2.0/24
The 10.0.2.0/24 is the default subnet for SlackBuilder's virtual network. Yours may be different. This tells pulseaudio to listen on the loopback and virtual networks for connection requests.
Container User setup
We need to have a user in the container to login to with the standard desktop permissions. ie: audio, video, netdev etc...
Using SlackBuilder this can be done with...
sbuser -a username
xdm looks for the file ~/.xprofile to execute. If one does not exist it just starts an xsession with an xterm terminal. If you don't already have this file create it and add the following...
This line is specifit to SlackBuilder but the concept should apply across all distros. The PULSE_SERVER variable tells pulseaudio to use the vmhost server. Which in this case is 10.0.2.1. The vmhost hostname is pre-configured on a SlackBuilder system. If using another distro just add the ip address of your bridge dnsmasq server.
SlackBuilder uses a custom configured openbox desktop and is started with the /etc/X11/xinit/xinitrc.Sbuilderbox script. You may be using something else. If so just add it here instead. It is assumed that pulseaudio is being initiated on startup with X11 modules loaded.
At this point we have configured the containers xdm server. Configured puluseaudio for both the container and the host. Added a container user and created an .xprofile script to start a desktop. All that remains is to connect to the xdm server from the host.
To do so logout of any currently running xsession. If your host is starting up in runlevel 5 you need to reconfigure your system to boot up to runlevel 3 and reboot. We need to be logged in to a regular tty virtual console. If you've had to reboot make sure that your container is up and running with xdm started.
Assuming you are now logged in to the console as a regular user with desktop appropriate permissions, issue the following commands... Consider putting them in a script for easy startup.
pulseaudio & X -once -ac -query hostname
Pulseaudio needs to be started on the host first so the container can use it. Then we start X with the -once option so that when the container desktop quits the X server stops and doesn't drop back into the xdm login prompt. -ac disables access control restrictions and -query tells X to use a remote X server where hostname is the container hostname. If you don't have a dns name assigned to the container use an ip address instead.
If all goes well you should be presented with the xdm login prompt. Login to the user you configured previouly. You now have a container desktop running with audio and GLX support. You can test if glx is working by running glxgears.
Some applications like games want to access the video card directly. warzone2100 for example requires it. To provide the container access to the the card add the following to the containers config file.
lxc.mount.entry = none dev/shm tmpfs nodev,nosuid,noexec,mode=1777,create=dir 0 0 lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir
Note: the shm line may not be absolutly necessary but some applications need it. May as well add it for good measure.
Since the container desktop is connected to the hosts pulseaudio, when quitting, it will stop the hosts pulseaudio process. So there is no need to stop it manually.
It really is simple to configure lxc container as a desktop. So many online tutorials are unecessarily complicated. Quite a few go into bizzar contortions just to get audio working. Others assume we want to start the X server from inside the container, a very messy thing to do and completely unecessary. Some go into using third party management apps that add even more complexity. It took me a while to find this simple solution from many different sources including blog comments that may have had only fragments of the idea. I couldn't find just one source that disscussed everything presented here.
Again, assuming a properly configured host, container and virtual network the extra steps to provide a working desktop are...
- Configure xdm in the container
- Configure pulseaudio in container and host
- Configure a container users ~/.xprofile to use the host pulseaudio server and start a desktop session.
- Connect to container xdm from a host user by starting pulseaudio and telling X to query the container.
- Additionally for gaming support. Add video card mount directives to the containers config file.