It’s no secret that the preferred way of obtaining new end-user software in Nitrux is to use AppImages, although we also support Flatpak. That is because we’d prefer to keep the root clean and without surprises; in other words, we don’t make this distribution centered around a package manager but rather applications. Nitrux has included Docker for over two years, which aligns with that concept. Indeed, we understand that some users still want to use a package manager but haven’t used a container before; thus, Distrobox makes it easier to get started.
Admittedly, before marching down with torches in anger, let’s make it clear that users can still use a package manager; in fact, users can use any package manager to install new software, just not directly to the root directory anymore; again, we can’t stress this enough.
In today’s tutorial, we will create a container using Distrobox with Podman, install an application, export it, and make the container use hardware acceleration.
Difficulty: ★★☆☆☆
📜 Table of Contents
- Containers are not Virtual Machines
- About Distrobox
- Managing Containers with Distrobox
- Accessing a Distrobox Container
- Managing Software inside a Distrobox Container
- Exporting Applications Installed on a Distrobox Container
- Enabling Hardware Acceleration for Applications on Distrobox Container
- Using aliases to run software installed on a Distrobox Container from the Host
- Running Software from the Host using Libraries from a Distrobox Container
- About “rootful” Containers in Distrobox
- Troubleshooting
Containers are not Virtual Machines
We understand that containers are a new concept to many people, and we’ve observed that they’re often confused for virtual machines; however, they’re very different. Containers and virtual machines (VMs) are both technologies used to create isolated environments for running applications, but they differ significantly in their architecture and use cases; here’s an overview.
- Hypervisor: VMs run on a hypervisor, which can be either Type 1 (bare-metal, like VMware ESXi) or Type 2 (hosted, like VirtualBox).
- Guest OS: Each VM includes an entire operating system (guest OS) with virtualized hardware resources (CPU, memory, storage).
- VMs are generally more resource-intensive because each VM runs an entire OS instance, which requires more CPU, memory, and storage.
- Isolation: VMs provide strong isolation as each VM operates independently with its own OS and resources.
- It suits scenarios requiring strong isolation, such as running different OS types on the same physical hardware.
- Performance: VMs have higher overhead due to the additional layer of virtualization and the need to run an entire OS. This can result in slower performance compared to containers. Overhead from the hypervisor can also add to resource consumption.
- Container Engine: Containers run on a container engine (like Docker or Podman), which uses the host OS’s kernel.
- Shared OS: Containers share the host OS kernel but have isolated user spaces. This means they do not require an entire OS instance for each container.
- Containers are lightweight as they share the host OS kernel and do not require an entire OS instance. This makes them more efficient in terms of resource utilization.
- Containers can start up quickly and use less memory and storage when compared to VMs.
- Isolation: Containers provide process-level isolation using namespaces and control groups (cgroups).
- Containers are frequently used for developing, testing, and deploying applications in a consistent environment.
- Performance: Containers have lower overhead and can offer near-native performance as they share the host OS kernel.
🔰 Information: For a more in-depth analysis and comparison, see Virtualization and Containerization of Application Infrastructure: A Comparison by Thijs Scheepers (2014).
About Distrobox
Distrobox is based on an OCI image and implements concepts similar to ToolBox, built on top of Podman and OCI standard container technologies. As the project describes, “Simply put, it’s a fancy wrapper around podman, docker, or lilipod to create and start containers highly integrated with the hosts.”
It has been written in POSIX shell to be as portable as possible and does not have problems with dependencies and the GNU C Library, also known as libc or glibc, version’s compatibility. It also aims to enter the container as fast as possible; every millisecond adds up if you use the container as your default environment for your terminal.
Here are some of the highlights of Distrobox.
- Provide a mutable environment on an immutable OS, like Endless OS, Fedora Silverblue, OpenSUSE MicroOS, or SteamOS3.
- Provide a locally privileged environment for sudoless setups (e.g., company-provided laptops, security reasons, etc.)
- To mix and match a stable base system (e.g., Debian Stable, Ubuntu LTS, RedHat) with a bleeding-edge environment for development or gaming (e.g., Arch, OpenSUSE Tumbleweed, or Fedora with the latest Mesa.)
- Leverage large, curated distro images for Docker/Podman to manage multiple environments.
Managing Containers with Distrobox
Before using Distrobox, we must change the root propagation to “shared.”
- 🔰 Information: Mount propagation allows for sharing volumes mounted by a container to other containers in the same pod or pods on the same node.
We can check this value by running the following command.
findmnt -o PROPAGATION /
If the output reads “private,” we cannot enter the container. To change this value, run the following command.
sudo mount --make-rshared /
The syntax to create a new container is as follows.
distrobox create -n CONTAINER-NAME -i OS-NAME:VERSION
- 🔰 Information: To display a complete list of available containers for Distrobox, run the following command.
man distrobox-compatibility
In this example, we’ll create a container using a Debian 12 image for familiarity’s sake. For simplicity, we won’t use the other features available in Distrobox when creating a container.
- 🔰 Information: The command below pulls the official Debian 12 image from DockerHub and creates a container called “debian-stable-distrobox.”
distrobox create -n debian-stable-distrobox -i debian:stable
We accept to download this container image.
To list containers created with Distrobox, run the following command.
distrobox list
Lastly, to remove a container, we must stop it first. Once they’re stopped, we can remove the containers.
- 🔰 Information: If the Distrobox commands don’t work, use Podman directly; see Forcefully Stopping all Containers and Forcefully Removing all Containers.
distrobox stop CONTAINER-NAME distrobox rm CONTAINER-NAME
Finally, to delete the unused container image, do the following: First, list the container images; each image will have an ID. Then, delete the image using the ID.
- 🔰 Information: Distrobox doesn’t have a specific command to do this, so we must use Podman directly.
podman images podman rmi CONTAINER-IMAGE-ID
Accessing a Distrobox Container
To access the newly created container, run the following command. Distrobox will do a basic setup, and as mentioned before, additional features, including packages, environment variables, drivers (NVIDIA), and even an init, can be used.
distrobox enter -n debian-stable-distrobox
- 🔰 Information: Notice that the hostname in the terminal has changed to that of the container. We can continue using the container or type “exit” to quit it.
- ⚠️ Important: Since Distrobox version 1.4.0, the login shell of the container is the same as the default user shell. To change the shell in the container, use the command
chsh
Even inside the container, we can browse our home directory (and any directory our user can access). However, we can’t browse the host’s root directory since we’ll browse the container’s root.
Managing Software inside a Distrobox Container
Using Distrobox, it is unnecessary to enter the container to manage software; we can run the commands directly from the host. The syntax is the following.
distrobox enter -n CONTAINER-NAME -- COMMAND
For example, we can update the package index and install software just like we’d do it in a conventional distribution, in this case, Debian. It’s important to note that actions that require elevated privileges require sudo.
distrobox enter -n debian-stable-distrobox -- sudo apt update
After installing our software, we can run it similarly; let’s do that with Neofetch.
distrobox enter -n debian-stable-distrobox -- neofetch
Likewise, we can remove software from the container. Let’s remove Neofetch without entering the container.
distrobox enter -n debian-stable-distrobox -- sudo apt remove -y neofetch
Of course, every other option in APT/dpkg will work, such as upgrade, autoremove, etc.
Exporting Applications Installed on a Distrobox Container
We can export software we’ve installed in a container using Distrobox. Exporting a program with Distrobox will make the specified software available to the host operating system as a native application and integrate it into the applications launcher.
We must enter the container to export an application since we can’t do this from the host; once inside, we can run the following command.
distrobox-export --app APPLICATION-EXECUTABLE
- ⚠️ Important: It’s crucial to understand that the “export” option only works when the software utilizes a desktop launcher (.desktop). Create an alias in the host’s shell configuration file for software that doesn’t use a desktop launcher (as most CLI-only utilities and tools do).
In this example, we will install and export Blender to be available in the host. As we did before, we can install software without entering the container.
distrobox enter -n debian-stable-distrobox -- sudo apt install -y --no-install-recommends blender
Then, we ran Blender to see if it worked.
Great, Blender works fine, as we’d expect. So we can export the application now.
- 🔰 Information: When exporting the application, we must use the application’s executable; this way, Distrobox will know the associated desktop launcher. Distrobox will create the desktop launcher in the directory $HOME/.local/share/applications.
distrobox-export -a blender
Once we do that, Blender will be available to launch from our application menu. Notice that the exported application launcher includes the name of the container where it is installed; this will help organize applications and make it easier to remove them when they are no longer needed.
Likewise, to delete an exported application, run the following command.
distrobox-export -a -d blender
Enabling Hardware Acceleration for Applications on a Distrobox Container
We must perform the steps below to run applications installed in a container with a Distrobox that requires hardware acceleration like Blender. These steps might not be necessary for all software, especially if it doesn’t require hardware acceleration.
⚠️ Important: Instructions below are for the container used as an example for this tutorial and using Nitrux as the host; adapt to your needs if you’re using a different container.
- MESA drivers (radeon, amdgpu, i945, etcetera). If the container doesn’t already have them, we only need to install the following packages.
distrobox enter --name debian-stable-distrobox -- sudo apt install -y --no-install-recommends libegl1-mesa libgl1-mesa-glx libvulkan1 mesa-vulkan-drivers
- NVIDIA proprietary driver. We need to have matching versions of the kernel and driver on the host and the container; otherwise, we will see an error in the container when attempting to build the driver. Nitrux uses the Liquorix kernel. To install this kernel in the container, run the following commands.
distrobox enter --name debian-stable-distrobox -- sudo wget -P /usr/bin https://liquorix.net/install-liquorix.sh distrobox enter --name debian-stable-distrobox -- sudo chmod +x /usr/bin/install-liquorix.sh distrobox enter --name debian-stable-distrobox -- sudo bash /usr/bin/install-liquorix.sh distrobox enter --name debian-stable-distrobox -- sudo rm /usr/bin/install-liquorix.sh
- 🔰 Information: For convenience, we created a script that will always install the latest NVIDIA proprietary driver.
distrobox enter --name debian-stable-distrobox -- sudo wget -P /usr/bin https://raw.githubusercontent.com/Nitrux/storage/master/Other/install-nvidia-driver-installer distrobox enter --name debian-stable-distrobox -- sudo chmod +x /usr/bin/install-nvidia-driver-installer distrobox enter --name debian-stable-distrobox -- sudo bash /usr/bin/install-nvidia-driver-installer distrobox enter --name debian-stable-distrobox -- sudo rm /usr/bin/install-nvidia-driver-installer
Using aliases to run software installed on a Distrobox Container from the Host
As we’ve seen, running software from Distrobox is super easy, but let’s say you don’t want to type all that text whenever you want to run something. We can solve that quickly by creating an alias in the shell configuration file ($HOME/.zshrc). We can create an alias for anything we want; for example, if we only want to type “apt” instead of the full Distrobox command, distrobox enter --name debian-stable-distrobox -- sudo apt
we can create one. To do this, run the following command.
- ⚠️ Important: Please notice a space at the end, next to “apt” in our alias. Adding the space allows the alias to take our input. Otherwise, it would simply run the command “apt” as-is.
echo -e "\n# Alias for APT\nalias apt='distrobox enter -n debian-stable-distrobox -- sudo apt '\n" >> ~/.zshrc && source ~/.zshrc
After doing so and sourcing the file, our new alias works. You will also notice that after adding this alias, we do not have to prepend APT with sudo; we run apt [option], for example, apt update instead of sudo apt update because we already use sudo in the alias, and if we were to prepend sudo what we’d be doing is to run “sudo distrobox-enter …”, which is not the objective.
- ⚠️ Important: When entering the container, if the alias is still active and we type “apt,” this will inevitably loop into trying to run the container inside the container, which will not work. Remove the alias or use a different name before entering the container.
Of course, you can do this for any other software in any container you create.
Running Software from the Host using Libraries from a Distrobox Container
By using aliases, we have a lot of flexibility. An interesting use case is creating “runtimes.” We can create an alias named “dbox-run” to run any binaries in the host but use the libraries of the container instead of those available in the host or as a shorthand to run the software we’ve installed on the container. For example, we can do the following to run Neofetch, which is a CLI utility that wouldn’t have a desktop launcher and, therefore, can’t be exported by default.
First, we add the alias and source of the shell configuration file. To do this, run the following command.
echo -e "\n# Alias for dbox-run\nalias dbox-run='distrobox enter -n debian-stable-distrobox --'\n" >> ~/.zshrc && source ~/.zshrc
And we can start using our new command.
dbox-run neofetch
Or, as mentioned, we can run binaries from the host, like this binary of Qt Creator (installed manually and downloaded from its official site at https://www.qt.io/download). In this example, if we were to install Qt Creator in the host and run it, it would be impossible for Qt Creator to find the many development headers and libraries it needs to compile projects.
# Running Qt Creator like this won't allow us to build projects ~/Qt/Tools/QtCreator/bin/qtcreator
However, if we run the binary on a container where we have installed the packages it needs, it can build the projects.
# Running Qt Creator like this will allow us to build projects (after installing the necessary packages on the container like qt5-default, qttools5-dev, cmake, and so on) dbox-run ~/Qt/Tools/QtCreator/bin/qtcreator
Another use case is running old binaries that do not work with newer libraries; for example, it would be in the case of unmaintained AppImages built against older versions of the GNU C Library (or other libraries included in the AppImage) that do not work with the newer versions that we include in Nitrux (primarily because of deprecated/undefined symbols or functions in newer versions of such libraries).
- 🔰 Information: It’s worth remembering that while AppImages are self-contained, whatever libraries or binaries its creator did not include in the AppImage are going to load from the root directory of the distribution where the AppImage is running; problems will occur if these libraries and binaries are incompatible; typically, the application will crash with a segmentation fault, or in the case of the AppImage of the example below, an illegal hardware instruction.
For example, this AppImage of Opera (available from AppImageHub and thus listed in the NX Software Center) does not work if we try to run it in Nitrux; it will error out.
Let’s run this unmaintained AppImage using the container we created in this tutorial. It will work once we install the missing libraries in the container because the AppImage’s libraries and binaries were compiled against versions of libraries, like the GNU C Library, which are compatible with those in the container. We’re using the container’s libraries instead of the newer libraries from the host system, Nitrux.
We could call this container a “runtime,” similar to a “runtime” for other packaging formats like Flatpak or Snaps. FUSE must be installed to get AppImages to work when running them using a container.
- 🔰 Information: The packages below will allow us to run this particular AppImage using the container we created. We can use our aliases or the complete command sequence; it doesn’t matter.
distrobox enter -n debian-stable-distrobox -- sudo apt install -y --no-install-recommends libfuse2 fuse3 libxtst6 libatk-bridge2.0-0 libgtk-3-0
Then, run the AppImage; let’s assume it’s in our Downloads directory.
dbox-run ~/Descargas/Opera-x86_64.AppImage
We could then create a desktop launcher, put it in $HOME/.local/share/applications, so it’s available in the applications menu, and have it run the command above to execute the AppImage using our newfound “runtime.”
About “rootful” Containers in Distrobox
Our tutorial on using Distrobox does not cover the use of root containers because of what the developer describes here.
⚠️ […] if you use docker, or you use podman with the –root/-r flag, the containers will run as root, so root inside the rootful container can modify system stuff outside the container […]
There are instances where a root container may be necessary, such as when an application requires accessing USB devices, modifying internal storage devices, etc., or specific hardware features, such as using a hypervisor that uses libvirt within a container.
- ⚠️ Important: Use root containers at your own risk!
Additionally, as discussed in their bug tracker, the developer doesn’t consider sandboxing within the scope of what Distrobox should be. For this reason, we recommend installing either SELinux or AppArmor within the container, as well as
Troubleshooting
⚠️ Important: Instructions below are for the container used as an example for this tutorial and using Nitrux as the host; adapt to your needs if you’re using a different container.
Fix Locale Errors in Containers
While it doesn’t affect the container’s functionality, in this Debian container’s case, do the following to eliminate those Perl warning messages. Only select the appropriate locale, and that’s it, no more errors.
- ⚠️ Important: These messages appear because the host’s locale differs from the container’s. This issue is not a bug in Nitrux or caused by Nitrux.
distrobox enter -n debian-stable-distrobox -- sudo apt install -y --no-install-recommends locales distrobox enter -n debian-stable-distrobox -- sudo dpkg-reconfigure locales
Issues with PolicyKit Authentication
Software that uses PolicyKit for authentication will not work out of the box due to issues with containers and DBus. This is a known issue with Distrobox, as noted in this comment by the developer; this is not a problem caused by Nitrux, introduced by Nitrux, or only affecting Nitrux. However, it is possible to alleviate this problem by doing the following.
distrobox enter -n debian-stable-distrobox -- sudo mkdir /run/dbus distrobox enter -n debian-stable-distrobox -- sudo ln -s /run/host/run/dbus/system_bus_socket /run/dbus/system_bus_socket
After doing this, to run software that would otherwise use pkexec
we must use sudo -E
For example, If we don’t use sudo, Synaptic will complain that it runs without elevated privileges and can’t make changes; if we run it with sudo, it will install the selected package.
Forcefully Stopping all Containers
Do the following to stop all containers created using Podman (the default in Distrobox).
podman container kill -a
Forcefully Removing all Containers
Do the following to remove all containers created using Podman (the default in Distrobox).
podman container rm -f -a
Managing Flatpaks in the Host using a Container
Nitrux includes Flatpak by default. However, we don’t include a GUI to do this as our focus is on Appimages. Nonetheless, it’s possible to use applications like Plasma Discover or GNOME Software to manage them. To install either of these applications, run the following command.
- ⚠️ Important: PackageKit will be installed on Debian as it’s marked as a dependency of Plasma Discover and GNOME Software packages. This may not be true in other distributions, such as Arch Linux. Because of this, a dialog window may appear indicating an error about PackageKit when running either of these applications within the container. However, this is irrelevant to managing Flatpaks and can be safely ignored; this is not a problem caused by Nitrux, introduced by Nitrux, or only affecting Nitrux.
distrobox enter -n debian-stable-distrobox -- sudo apt install -y --no-install-recommends plasma-discover plasma-discover-backend-flatpak plasma-integration flatpak
distrobox enter -n debian-stable-distrobox -- sudo apt install -y --no-install-recommends gnome-software gnome-software-plugin-flatpak flatpak
It may be necessary to add the remote for your Flatpaks in the container, i.e., Flathub.
distrobox enter -n debian-stable-distrobox -- flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
After installing either of these applications in the container, do the following to allow the container to access the Flatpak directory in the host.
distrobox enter -n debian-stable-distrobox -- sudo ln -s /run/host/var/lib/flatpak/ /var/lib/flatpak
That’s it; this concludes today’s tutorial.