I’m trying to run a distro with a Desktop Environment in a container and let it render on DISPLAY :1. Basically the same thing @simossuggested here.
However, I don’t seem to be able to get it working. Any chance you can point me towards the right direction? I’m using the following profile and user-data:
When I now login to the container as root and then run gdm3 (to start GNOME) it does not output any error and keeps running - but Ctrl + Alt + F8 is still empty (black screen).
What I’m missing here?
UPDATE: I’m on elementary 5.1 Hera - which is based on Ubuntu 18.04 LTS. LXD v3.0.3
tldr:
Take a look at a comparison of methods for using X-Servers in container by @simos:
Well I am not the expert here,
but I think the main point is, simos method (there are other methods, see below) you try to use, is (as far as I know) for running applications, not the whole desktop.
Some more specific problems of your setup:
As far as I can see you use the X0-Socket and that means you should use Display :0.
Maybe you can try to do it vice versa, and use “X1” for Display :1.
But at least I only have one socket.
Note that the bold text below (i.e. X1 ) should be adapted for your case; the number is derived from the environment variable $DISPLAY on the host. If the value is :1, use X1 (as it already is below). If the value is :0, change the profile to X0 instead.
You are using an outdated method of simos with disk-devices, he now recommends using proxy-devices.
(Personal note: I still use disk-devices, because I could not get proxy-devices to work, but that should not prevent you from trying)
@toby63 thank you so much for putting this information together - lots of good stuff there! Will need play around with this a bit. What i already figured out is, it appears we need to be root in order to be able to execute gdm - so probably the uid mapping works a bit different.
What kind of Desktop graphics/video do you require?
There are several great approaches for Remote Desktop use of LXD containers to host the Desktops including x2go (www.x2go.org), using X redirection via ssh, my project CIAB (cloud in a box) Remote Desktop system (https://github.com/bmullan/ciab-remote-desktop ) and others.
I‘d love an LXD based desktop solution which runs locally, is as performant as possible and easily reproduceable.
The goal is to integrate it into my Tins app to allow users setting up a desktop environment in a container on their local host with just a few clicks. It’s for developers and curious people alike - who want to tinker with stuff, get near native performance (incl. GPU acceleration) but don‘t break their stable every day system:
EDIT: Added the following clarifications:
… want to tinker on their local host …
… near native performance (incl. GPU acceleration) …
The ideal solution would be to render the containerized desktop environment in a window, on top of the currently running desktop environment (within the current X session).
@marbetschar
For xpra you might take a look at lxc or docker stuff.
I once searched for that too (never really tried that though), and there are some Howtos and Repos with scripts and profiles existing, maybe you can modify them for the use with LXD.
so it remains unclear if this solution provides GPU acceleration.
I got some sort of working solution now - unfortunately it seems to be highly unstable (see below for further information on this):
How it (sort of) works as of now:
After the user made their choice, Tins creates a new container given the selected criteria and applies the generic X11 and the specific Desktop Environment profile (e.g: for X11 this, and for GNOME this one)
The container creation process of LXD downloads the latest available, matching image from images.linuxcontainers.org (e.g.: images:ubuntu/bionic/cloud)
The desktop specific profile provides a cloud-init script, so this gets executed upon container start which downloads, installs and configures the desktop environment (e.g.: for GNOME this one).
If the user wants to open a desktop enabled container, Xephyr is started at an available $DISPLAY number
In the container systemctl start display-manager is executed and LightDM forwards its output to Xephyr
… overall it seems we have to be rather lucky if everything goes well. Which leads me to the problems I encounter:
Problems with this approach:
The images from images.linuxcontainers.org seem to be highly unstable. Sometimes networking does not work, at other times apt is broken, etc…
cloud-init takes very long to complete the initial setup because it needs to download all desktop packages
cloud-init often fails to install the needed packages due to various reasons (e.g. failed to unpack package, connectivity issues, …)
I was not able to find a good way to monitor cloud-init's progress and exit status - so as of now it is impossible to say when it is finished which leads to a bad user experience
Xephyr runs completely independent from Tins so its just fire and forget - hoping everything goes well
Any help to mitigate these issues and/or improve the overall process would be highly appreciated
I’m also wondering if it is possible to build and publish out-of-the-box, desktop environment enabled images to images.linuxcontainers.org (or some other public mirror)? This would save a ton of bandwith, and would probably dramatically improve the success rate of setting such a container up.
In case you want to experiment yourself
Feel free to clone the project from GitHub, as of now Ubuntu Focal and Ubuntu Bionic are the only two Desktop Environment enriched Distro flavours.
I was not able to find a good way to monitor cloud-init 's progress and exit status - so as of now it is impossible to say when it is finished which leads to a bad user experience
Though thats not perfect. I guess I will write a feature request for this.
Update: I opened an issue report for this: https://github.com/lxc/lxd/issues/7364
You might want to add info, suggestions or changes to it .
@Manishfoodtechs the goal is to provide a general purpose solution which allows to run any combination of desktop environment and distribution in a container - whether a particular desktop is too resource heavy or not is up to the end user to decide.
Thanks for pointing me towards Xrdp, I’ll check it out! Although I’m not sure what it implies in terms of performance: Does the container need to run its own X server for this to work? If so, is GPU acceleration available to it? Why/when should one choose Xrdp over Xephyr and vice versa?
Another example of an applet to launch systems can be found in multipass (available as a snap package). multipass creates VMs and is sort of similar to LXD VMs. They have created an applet to launch terminal windows into the VMs. No GUI support to run applications from within the VM, just a nice applet to launch a terminal windows in the VM. It is written in C++.
Yet another option is to get GNOME Boxes to support LXD containers. This will be more involved though, since GNOME Boxes currently interfaces with the VM over libvirt only (last checked over a year ago).
Linux offers too many ways to run GUI programs on some other computer/VM/container and get the output on your local X11 session. You can just pick the easiest for you for now, just to get something working.
I have tried to use tins in a LXD container, that supports nested containers.
$ lxc launch ubuntu:18.04 tins --profile default --profile x11 -c security.nesting=true
Creating tins
Starting tins
$
The ubuntu user may not be a member of the lxd group, so add them manually.
The PulseAudio socket location is hard-coded, so the container will fail to start. The code should look for PULSE_SERVER, if it exists, and use that location instead of the default.
By having a reproducible environment, it should be easier to develop.
It is great work and I love reading this thread.
@simos thanks for your kind words! For now I’m primarily focus on getting the graphical environment up & running and had success so far for starting and configuring weston and Xwayland (Audio support should follow as soon as the GUI works).
I followed your instructions from your blog, and with Xephyr it worked - but now there seems something wrong. Any chance you can point me towards the right direction?
You’ll find the complete details with config outputs etc. in this GitHub issue: