Skip to main content

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, and make the container use hardware acceleration.

Difficulty: ★★☆☆☆

📜 Table of Contents

  1. About Distrobox
  2. Accessing a Distrobox Container
  3. Enabling Hardware Acceleration for Applications on Distrobox
  4. Adding an alias to run software installed on Distrobox
  5. Running software using libraries from a Distrobox container
  6. Exporting Applications from a Container with Distrobox
  7. Enabling Hardware Acceleration for Applications on Distrobox
  8. Distrobox “rootful” containers Information
  9. Troubleshooting
    1. Fix Locale in Containers
    2. Errors with /etc/localtime on Debian-based Containers
    3. Errors when installing the NVIDIA proprietary driver on a Container
    4. Issues with PolicyKit Authentication

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.

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.

Create a Container with Distrobox

The syntax to create a new container is as follows.

distrobox-create --name CONTAINER-NAME --image OS-NAME:VERSION
  • 🔰 Information: For a complete list of operating systems and versions supported by Distrobox containers, visit the Distrobox Project page.
    • The following is a list of only some of the containers supported by Distrobox.
      • Alpine Linux
      • Arch Linux
      • CentOS
      • Debian
      • Deepin
      • EndlessOS
      • Fedora Workstation/Silverblue/Kinoite
      • Gentoo
      • Manjaro
      • NixOS
      • openSUSE
      • SUSE Linux
      • SteamOS 3
      • RedHat
      • Ubuntu
      • Void Linux

In this example, we will create a container called debian11-distrobox from a Debian 11 image.

  • 🔰 Information: The command below pulls the Debian 11 image from DockerHub and creates a container called debian11-distrobox.
distrobox-create --name debian11-distrobox --image debian:11

To list containers created with Distrobox, run the following command.

distrobox-list

Accessing a Distrobox Container

Before entering the container, 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 /

To access the shell of the newly created Linux container, run the following command.

distrobox-enter --name debian11-distrobox

We can see that we’re inside the container as our hostname has changed to the container’s name. We can continue using the container or type “exit” to quit the container.

Even inside the container, we can browse our home directory (and any directory our user can access). However, we can’t browse the root directory since we’d be browsing the container’s root.

Running Software inside a Distrobox Container from the Host

Using Distrobox is unnecessary to enter the container to install or remove software; we can run the commands directly. For example, we will install Neofetch on the container without entering the container.

To do this, run the following command.

distrobox-enter --name debian11-distrobox -- sudo apt install neofetch --no-install-recommends

As before, we can either enter the container and run the program or use the command distrobox-enter.

distrobox-enter --name debian11-distrobox -- neofetch

Exporting Applications from a Container with Distrobox

We can export software if we have installed it inside a container. Exporting a program with Distrobox will make the specified software available to the host operating system as a native application.

To export an application, we must enter the container; once inside, we can run the following command.

distrobox-export --app $APP_NAME
  • 🔰 Information: It’s worth noting that the export command works when the software utilizes a desktop launcher (.desktop). For software that doesn’t use a desktop launcher (like Neofetch, a CLI utility), we recommend entering the container or using the command distrobox-enter and creating an alias in the file ~/.zshrc.

In this example, we will use Blender and export it to be available in the host.

First, we need to install Blender.

distrobox-enter --name debian11-distrobox -- sudo apt install blender --no-install-recommends

Then, we can enter the container and run Blender to test that it works.

Once we know that it’s working, we can export the application.

distrobox-export --app blender

Once we do that, Blender will be available to launch from our application menu.

Enabling Hardware Acceleration for Applications on Distrobox

We must perform the below steps to run applications installed in a container with a Distrobox that requires hardware acceleration like Blender. Other software can run without the steps below.

  • ⚠️ Important: Future versions of Distrobox will include an option to integrate the NVIDIA proprietary driver while creating the container.

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 distribution.

If using the NVIDIA proprietary driver, we need to have matching versions of the driver on the host and the container; otherwise, we will see an error in the container when attempting to run software like Blender. So, first, we need to install the driver package; when installing the package, we will use the option –no-install-recommends to avoid installing a kernel package in the container; this way, we avoid a problem with dkms; see Troubleshooting.

    • ⚠️ Important: Replace the version of the driver from this example (nvidia-driver-525 and 525.85.05) accordingly.
#### Use a cleaner sources.list and add a repository to install the NVIDIA driver.
#### Create these files in your home.
#### The command to create the sources files is a single command, but it's multiple lines; it starts at [>>] and ends at [''].

>> sources.list printf "%s\n" \
    '########################################' \
    '#   DO NOT EDIT THIS FILE!             #' \
    '#   Your changes will be overwritten   #' \
    '########################################' \
    '' \
    '#########################' \
    '# Debian Repos Unstable #' \
    '#########################' \
    '' \
    'deb [arch=amd64] http://deb.debian.org/debian stable main non-free contrib' \
    ''

>> gpu-ppa-repo.list printf "%s\n" \
    '########################################' \
    '#   DO NOT EDIT THIS FILE!             #' \
    '#   Your changes will be overwritten   #' \
    '########################################' \
    '' \
    '#######################' \
    '# Proprietary GPU PPA #' \
    '#######################' \
    '' \
    'deb [arch=amd64] http://ppa.launchpad.net/graphics-drivers/ppa/ubuntu focal main' \
    ''

distrobox-enter --name debian11-distrobox -- sudo mv sources.list /etc/apt/sources.list

distrobox-enter --name debian11-distrobox -- sudo mv gpu-ppa-repo.list /etc/apt/sources.list.d/

distrobox-enter --name debian11-distrobox -- sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1118213C

distrobox-enter --name debian11-distrobox -- sudo apt update

distrobox-enter --name debian11-distrobox -- sudo apt install nvidia-driver-525 --no-install-recommends

If using the MESA drivers (radeon, amdgpu, i945, iris, nouveau), we only need to install the following packages if the container doesn’t already have them.

distrobox-enter --name debian11-distrobox -- sudo apt install libegl1-mesa libgl1-mesa-glx libvulkan1 mesa-vulkan-drivers

Adding an alias to run software installed on Distrobox

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 launch something. We can solve that quickly by creating an alias in ~/.zshrc.

We open the file with any text editor; for this example, we’ll use micro.

micro ~/.zshrc

Then, we type the alias we want; in this case, we’ll create an alias for Neofetch.

alias neofetch='distrobox-enter --name debian11-distrobox -- neofetch'

After doing so, we saved and sourced the file so our new alias works. So, instead of typing the full Distrobox command, we only need to type neofetch to run it.

We can create an alias for anything we want, so if, as before, we only want to type “apt” instead of the full Distrobox command, we can create an alias. So, let’s add an alias for APT.

We open the file with any text editor; for this example, we’ll use micro.

micro ~/.zshrc

Then, we type the alias we want; in this case, we’ll create an alias for APT.

  • ⚠️ Important: Please notice a space at the end, next to “apt” in our alias.
#   Add alias for using APT from Distrobox container

echo -e "\n# Alias for APT\nalias apt='distrobox-enter --name debian11-distrobox -- sudo apt '\n" >> ~/.zshrc && source ~/.zshrc

After doing so, we saved and sourced the file so our new alias works. So, instead of typing the full Distrobox command, we only need to type apt to run it.

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. The reason for that is that we’re not running an APT binary from our root to make changes to our root; we’re running the binary from the container, which is rootless.

Of course, you can do this for any other software, including other package managers you want to use.

Running software using libraries from a Distrobox container

By using aliases, we have a lot of flexibility; we can create a “dbox-run” alias to launch any binaries from within the container or external to the container (like an executable in ~/Downloads) using the libraries installed on the container.

By now, you know the gist.

# Add alias for running a binary from Distrobox container or an external binary using the libraries from Distrobox container

echo -e "\n# Alias for dbox-run\nalias dbox-run='distrobox-enter --name debian11-distrobox --'\n" >> ~/.zshrc && source ~/.zshrc

So we can use our “dbox-run” command to run an executable using the libraries from the container. For example, running any binary from a container like Neofetch or, let’s say, you want to use the version of rsync from the container because that’s patched differently.

Or, as mentioned earlier, run binaries external to the container, 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 just to install Qt Creator 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. The command below shows how this instance of Qt Creator was executed.

#   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)

distrobox-enter --name debian11-distrobox -- ~/Qt/Tools/QtCreator/bin/qtcreator

#   Or, using our "dbux-run" alias

dbox-run ~/Qt/Tools/QtCreator/bin/qtcreator

So, as before, we can create an alias called qtcreator, for example, to launch the program using the libraries and development headers we’ve installed in the container and avoid typing the whole command sequence.

We can also use it to run 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, also called an illegal 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.

However, let’s run it on a Debian 11 container (like the one in this tutorial). It will work after installing in the container the libraries not included in the AppImage; as we established earlier, this occurs because the libraries and binaries included in the AppImage were compiled against versions of libraries, like the GNU C Library, that are still compatible with those from the container since that’s what we’re using to run this particular AppImage instead of the libraries from the host, in this case, Nitrux which are newer.

We could call this container a “runtime,” similar to a “runtime” for other packaging formats like Flatpak or Snaps.

We must install the following packages to get AppImages to work when running them using a container.

  • Note: The packages below will allow us to run AppImages using a container; however, since containers are tiny root directories with few packages installed, the application inside the AppImage will require more libraries or other binaries if they were not included in the AppImage as we have said.
#   Run the command to install packages to the container without entering the container

distrobox-enter --name debian11-distrobox -- sudo apt install -y --no-install-recommends libfuse2 fuse3

#   Or, using our "APT" alias, which, as we mentioned, doesn't require sudo at the beginning

apt install -y --no-install-recommends libfuse2 fuse3

Then, run the AppImage; let’s assume it’s on the default path for AppImages in the home directory.

#   Run the command to run the external binary without entering the container

distrobox-enter --name debian11-distrobox -- ~/Applications/./MyApp.AppImage

#   Or, use our "dbux-run" alias (assuming it's the same container where the packages where installed, of course)

dbox-run ~/Applications/./MyApp.AppImage

We could then edit the desktop launcher in the applications menu to run the command above and launch the AppImage using our newfound “runtime.”

Distrobox “rootful” containers Information

Our tutorial to use 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 […]

Future versions of Distrobox will include a sandbox feature, as discussed in their bug tracker.

  • 🔰 Information: There are instances where a root container may be necessary, such as when accessing devices, i.e., USB devices, internal storage devices, etc., or otherwise accessing specific hardware features, for example, to use a hypervisor that uses libvirt within a container.
  • ⚠️ Important: Use root containers at your own risk!

Troubleshooting

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 distribution.

Fix Locale 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.

    • ⚠️ 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 --name debian11-distrobox -- sudo apt install locales
distrobox-enter --name debian11-distrobox -- sudo dpkg-reconfigure locales

We can check that the messages disappear when rerunning APT.

Errors with /etc/localtime on Debian-based Containers

When using a Debian container, it may be the case that the package tzdata is upgraded or that other packages do something regarding timezone changes, resulting in an error with dpkg. Non-Debian distributions likely do not have this problem.

  • ⚠️ Important: Because of how Distrobox works, this might create a problem; however, this is an issue that the Distrobox developer(s) should resolve; this is not a problem caused by Nitrux, introduced by Nitrux or only affecting Nitrux.
umount: /usr/share/zoneinfo/Etc/UTC: target is busy.
E: Problem executing scripts DPkg::Pre-Invoke 'if findmnt /etc/localtime >/dev/null; then umount /etc/localtime; fi'
E: Sub-process returned an error code

We can edit the file /etc/apt/apt.conf.d/00_distrobox inside the container as a workaround to avoid that problem. To do that, run the following command inside the container.

  • 🔰 Information: Many containers do not come with a text editor installed. In this example, micro was installed in the container.
sudo micro /etc/apt/apt.conf.d/00_distrobox

Then comment on the first two lines, save the file, and rerun APT.

Additionally, block upgrades to the package tzdata by adding a file to /etc/apt/preferences.d like so with the following content.

  • 🔰 Information: Adjust a=unstable and n=sid to match your image. If Debian 11 were used, it’d be a=stable and n=bullseye.
>> tzdata printf "%s\n" \
    '###############################' \
    '#   Debian Package Priority   #' \
    '###############################' \
    '' \
    'Package: tzdata' \
    'Pin: release o=Debian,a=unstable,n=sid' \
    'Pin-Priority: -1' \
    ''

distrobox-enter --name debian11-distrobox -- sudo mv tzdata /etc/apt/preferences.d/

Errors when installing the NVIDIA proprietary driver on a Container

If a kernel is installed in the container, we will see an error with dkms because it will want to build the driver for both the host and the container kernels. So, we must tell dkms to skip building the driver for the host’s kernel. We need to locate the “dkms.conf” and edit it to do this.

For example, suppose the Debian kernel was installed during the installation of the NVIDIA proprietary driver (using the container in this tutorial as an example). In that case, we need to edit the dkms.conf file that the NVIDIA driver setup creates. The change below works by adding a variable that tells dkms to limit the range of the kernel version that will be considered to build the driver to any version between 4.0 and 5.9.

So users can adjust the value to match a range, like below, or a string, like the specific kernel version installed in the container.

  • 🔰 Information: Replace the path of the dkms.conf file of the NVIDIA driver version accordingly.
#### After dkms fails to build the driver, run the following command.

printf '%s\n' BUILD_EXCLUSIVE_KERNEL="^(4\.[0-9]+\.|5\.[0-9]\.)" >> /usr/src/nvidia-525.85.05/dkms.conf

sudo apt install -f

Issues with PolicyKit Authentication

Software that uses PolicyKit for authentication will not work 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.


That’s it; this concludes today’s tutorial.