Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@fpauser
Forked from sham1/x11_container_tutorial.md
Created September 11, 2020 07:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fpauser/cc96507709fd935cb6e28d1cc9477540 to your computer and use it in GitHub Desktop.
Save fpauser/cc96507709fd935cb6e28d1cc9477540 to your computer and use it in GitHub Desktop.

Running X11 applications using Podman

This is a short tutorial on using podman to run X11 applications. This need often arises when one has to run X11 applications on distros such as Silverblue, when the application for instance has no Flatpak and one doesn't want to install the particular app on their host OS (for instance for Silverblue this process would result in the need to layer a package and then reboot, something which understandably would get quite irritating after a while).

For this tutorial, I will use the game Xonotic as the application to run inside the container. While there really is no need for this (with it having a Flatpak and all that) it's a good way of illustrating some things needed to run graphical applications, especially those that need hardware acceleration, from within a container.

The usual disclaimers about the insecurity of the X protocol apply. User caution is expected.

(The steps in this tutorial will work with rootless containers)

Step 1. Building the image

Now while the title of this tutorial doesn't mention it, we will need another tool for this part. Say hello to buildah! We will use buildah to build our Xonotic-playing container.

Step 1.1. Create a new image

This is done with the following command. For this tutorial, I'll be basing the container image on Fedora 29.

$ buildah from --name xonotic-container fedora:29

Now, there is something to pack on this. The --name-switch allows us to name this container image whatever we want. We could go without it, in which case buildah would give us a name to use, and print it to stdout where we could assign it to a shell variable, but I did it like this for my own convenience.

fedora:29 here tells us the container image we will be basing our image on. In this case that image happens to be Fedora 29.

Step 1.2. Installing packages

Now that we have an image we can play around with, it's time to install whatever we want on this container image.

$ buildah run xonotic-container -- /usr/bin/dnf install xonotic mesa-libGL mesa-dri-drivers

This command ought to be obvious, but if it's not, what we're doing is that we're installing some packages to our container image. In our case they're Xonotic, for fairly obvious reasons, and two mesa packages. These are so that we can run Xonotic later. More specifically, they're needed so that Xonotic can use our GPUs to display the carnage of this arena-shooting action.

This step can be extended so that user can install or pretty much do any preparations before the container is to be used. For instance they can create users, copy files from the host, et cetera.

Step 1.3. Committing the image

After you've done all of the modifications your specific graphical app needs, it's time to commit your changes.

Now, some might tell you to delete files such as package manager metadata at this point, and I'm inclined to do the same, but this step is optional and depends on one's workflow and usage more than anything.

$ buildah run xonotic-container -- /usr/bin/dnf clean all

Now we're ready to commit the image.

$ buildah commit xonotic-container xonotic-container

The first argument is the container we've been working on at this point, and the second is the container image we're going to commit, and the name doesn't need to be the same as the first one. This commit-command will make our image available to podman.

Now one could remove the image we've been working on by doing buildah rm xonotic-container, but this again is optional. I personally like to leave the container be so I can update the image later. To update the image, one uses the package manager within the container like above, and then recommits the image.

Step 2. Running the application

Now we have our image. It's time to go to podman. This step will not take as long as the last step. To run Xonotic in our new fancy container, all one has to do is the following.

$ podman run --rm -v /tmp/.X11-unix:/tmp/.X11-unix -v /dev/dri:/dev/dri --security-opt=label=type:container_runtime_t -e DISPLAY localhost/xonotic-container xonotic-glx

Phew. There is something to be unpacked here. So let's go from left to right.

  • --rm tells podman to remove this container once it closes. This means that every time this command is ran, the container will be minty fresh.
  • -v tells podman to make a directory tree accessible inside the container instance. In this case we're making the /tmp/.X11-unix and /dev/dri accessible. The first one is to share the X11 socket with the container so we can run our app, and the second is to give our app access to the graphics card, which is needed for graphically accelerated graphics.
  • --security-opt=label=type:container_runtime_t tells podman to set the SELinux label of the container to be container_runtime_t. This is needed so that our app can access the insides of /tmp/.X11-unix and whatnot.
  • -e tells podman to set an environment variable for the process we're running. In this case we're setting the $DISPLAY-variable so that the app inside the container can connect to our current X session.
  • localhost/xonotic-container is our container from earlier. This name can be checked by doing podman images.
  • xonotic-glx is our graphical app we want to run inside our container. In this case it's Xonotic.

Now as far as the performance of this example application inside the container is concerned, it's totally playable like it would be if we were using it on the host. Since we're not virtualising anything but simply imposing some limits on what our app can see, we get the same performance as "native".


I hope this small, two-step tutorial has helped some of you to understand how container tools such as buildah and podman work and how they can be used to run graphical applications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment