TROMjaro Forum

Distrobox (/APX) vs. Nix vs. Flatpak

TLDR result highlights:

__

Introduction

I thought it might be nice to be able to more cleanly isolate some of my application installations from one another or the underlying system so as to:

(a) Reduce the risk of dependency conflicts, and make it easier to work around them if required.

and

(b) Be able to separate out certain software updates from others, or from the base system. This can help to reduce both unnecessary complications from having too many things changing (and potentially breaking) at once. And also reduces time/energy/resource requirements by allowing e.g. networked apps like web browsers etc. to be more regularly updated, without having to also update other system components unnecessarily.
_

Note that I’m not so interested here in sandboxing or immutability, though obviously anyone running an immutable base system immediately has much the same kinds of interest in this topic.

In any case, I thought I would do a little testing project to compare the following package management and container options: Distrobox, APX, Nix and Flatpak
I will comment on each of these in more detail and how the testing was done below.

The parameters I was interested to see were the download/installation requirements, storage space, launch times, memory usage, and theming support. You can see the full set of results here: https://files.trom.tf/s/WcqYwaa86oWyttJ
__

Results Overview

  • If everything is working correctly, then there is not much performance difference to be seen in terms of launch times or memory usage. At least on average. Note that there are some small differences in package versions across some of these different solutions, some of them received updates over the course of the six days of testing, and there was in any case some variability from run to run. I also suspect that the particular choice of apps here could have an important impact on the results. So don’t take small difference of a few percent to be particularly meaningful.

  • Compared to native packages, total storage requirements were ~60% higher for Nix, and ~twice as high for Distrobox and Flatpak.

  • Download and install times were ~40–60% higher than native for Nix and Distrobox, but 3.4 times higher for Flatpak. This for me was the most surprising result (and thus was repeated to be sure). Note that on my modest bandwidth ADSL connection this should mainly be a measure of the download size. Flatpak does not report this, but given that the final storage requirements for it are similar to Nix and Distrobox as in the point above, it makes me wonder if Flatpak is using much less efficient file compression on its downloads.

At least as important to me as these numerical results, was discovering how easy and reliable to use these different systems are. So I will discuss that below, but first a few quick comments on how I carried out the testing:
__

Test Methodology

I ran these tests in a cloned TROMjaro VM assigned 2 threads of a 4790k processor and 8 GB of RAM. In each case I tested installing a bundle of 24 apps that I could find to be available across all systems (see ‘Packages’ worksheet), and then I paired that down slightly to a list of 20 to execute simultaneously for each launch time or memory test.

Download and installation times were measured using the time command. So for example, with pacman:
time sudo pacman -S <list of packages>

Timing the total launch time was done using the approach suggested here:
https://stackoverflow.com/a/52033580
So for pacman that becomes:
time (trap 'kill 0' SIGINT; app1 & app2 & app3... ...& app20)

Note that here I have to wait until all 20 windows successfully launch, and then hit CTRL-C in the terminal to exit them all and get the output result of the time command.

I am using the Quake style drop down overlay available in Tilix* for the terminal, which helps to keep it on top and separated from the test programs. I can then easily see in my double-row task bar setup once there are 10 pairs of windows open. They are also ordered alphabetically and it is usually the same one or two apps that always open last, so it was fairly easy to keep track of. But there is still inevitably a bit of my own response time variability with this approach.

(* – I have subsequently discovered that you also can get a dropdown mode with the default XFCE terminal by changing the run command for that to: xfce4-terminal --drop-down )

Here is an example screenshot from a Flatpak launch:

It did vary a little from system to system but the slowest apps to start were typically: Signal Desktop, GIMP, LibreOffice, Firefox and Dino

You can find all the main run commands used, as well as some additional tips and required steps in the Commands worksheet. And for full transparency you can find my log of personal notes to myself over the course of testing as a Zim wiki text file in the Log worksheet (but as long as I am still available, it is probably a lot easier just to ask me any questions you have rather than trying to look through that yourself).

Total system storage usage was kept track of throughout using Baobab. Memory usage was tracked with System Monitoring Centre. I found all the usual GUI task managers to give close to the same results, whereas htop showed consistently lower figures.

__

Discussion

Distrobox

https://distrobox.privatedns.org/

Pros: Conceptually the simplest and easy to use

Cons: Largest storage requirements at ~10% higher than Flatpak

Distrobox creates Linux containers using either Podman or Docker. I installed from the repositories in Pamac and it give you the choice of which to use at the start of the install. The concept is easy to understand I think as you are just creating another more minimal (e.g. no GUI) Linux system install within your own. There is no sandboxing or virtualisation here.
_

I would highly recommend using Podman to start which runs without root privileges and stores the containers in:
~/.local/share/containers

Aside for advanced users

Within the containers directory you can find the standard Linux filesystem for the container under:
/storage/overlay/<long string of character>/diff/

Running with Docker adds some additional steps and requires running as root. Containers in that case go to:
var/lib/containers/

All we need to do after installation with the Podman route is to create the container, e.g. here an Arch Linux one I have called ‘Arch’
distrobox-create -n Arch -i archlinux

Then enter it:
distrobox enter Arch
(note the first time you do this it will take a little time to install some base packages, but thereafter is very quick).

And then, since we are now in Arch, we can do things there with pacman just the same as in TROMjaro, such as checking for system updates with:
sudo pacman -Syu

You can then exit back out of it, and stop with:
distrobox stop Arch

All very simple and intuitive I think. The main issue that crops up here is getting confused about whether you are working in the host system or the container in any given moment. I found it helped to first always install neofetch:
sudo pacman -S neofetch
And then I would regularly run neofetch as a sanity check to remind myself where I am :grin:

The main advantage that Distrobox brings over just using Podman is that it better integrates everything with your host system. E.g. when you first load into the command prompt you are already working in your normal host home directory with all your personal files. You can also export app launchers to integrate with your main host system and run from them as you would any native program:
distrobox-export -a appname

These launchers nicely display that they are running from the container – e.g. in our example they show “(on Arch)” after the app name, and any app with a proper window header will also display it in the header. So you could even have the same app installed on both the host and container respectively, and still easily distinguish between them.
The container apps will use your same .config files from your host system, so they will use all your same user settings, though as a result it is probably inadvisable to try to run two copies of the same app simultaneously.

If you wish to launch GUI apps from the terminal within Distrobox, then you first need to run:
xhost +si:localuser:$USER in the host system.
_

Compared to what we are blessed with in TROMjaro, system theming support does take a noticeable step down. Though compared to the other options here I guess it should be easier to fix if you were so inclined to get into it, since you are just working on the common problem of getting theming working on a fairly standard Linux system.

The second most surprising result to me in all the testing was that particularly the Docker variant of Distrobox seemed to have slightly better launch times and noticeably lower memory usage compared to running the apps from the native host system. As mentioned above, there are a lot of variables here which are difficult to pin down which throw some doubt over how meaningful this result is, but maybe it is related to differences between the Arch and Manjaro environments, or because it is running from a more stripped down system? I would be interested to hear what others make of this.

In any case, there is potentially quite a lot more testing one could do with Distrobox, such as trying out different Linux distributions instead of Arch. E.g. Alpine Linux is a more lightweight option that is a popular choice for containers. I only chose Arch mainly for ease of use in using pacman the same as on the native TROMjaro system, and for having all the packages in their repositories that I needed for this testing.

Advanced aside

If you wanted to have a number of different containers running (with all the additional overhead that would entail), then maybe this GUI interface for Podman could be of interest:
https://github.com/marhkb/pods

__

APX

https://documentation.vanillaos.org/docs/apx/

TLDR – skip it! :sweat_smile:

APX takes Distrobox, and wraps it up to work like a standalone package manager, mainly for VanillaOS, but can also be installed in any Linux system (I installed it from the AUR).

I was curious to have a look at how it would compare, but quickly gave up on it and thus it is not part of the results. I assume if you can get it working, the best case results should be the same a Distrobox. But I had a lot of trouble with it.

The one advantage it does seem to have is that at the end of installing an app with it, it prompts you as to whether you wish to integrate a launcher into your host system for it, rather than having to run the distrobox-export command yourself. But otherwise I found it to be extremely buggy and opaque.

It tries to simplify things by hiding from the user what it is doing under the hood, but as a result it is very difficult to understand or control what it is really doing with underlying containers. E.g. I couldn’t even work out how to replicate the Distrobox setup above and just install packages from the Arch repositories. It seems to think that you would only want Arch to access the AUR (it appeared to be trying to use yay for this).

I don’t know if the documentation is just lacking, or there is just a lot of basic functionality missing, but I got the impression that it is not well tested to work in environments outside of VanillaOS or Ubuntu in general (e.g. some of the numerous error messages I had suggested it was trying to run apt commands inside the Arch container).

Maybe some of my issues were related to using the AUR package for APX, but the lack of needed details in the documentation didn’t encourage me to persevere further with it. There also seems to be some risk that it will create multiple containers if you are not careful in how you use it. Distrobox just seems a lot easier to use overall and understand what you are doing.
__

Nix

https://nixos.org/download.html

Pros: The smallest install footprint of the lot. No possibility for dependency conflicts, and very quick and easy to roll back changes or switch between different generations of changes. Most complete repository available outside of the Arch ecosystem.

Cons: By far the most complicated ecosystem to get to grips with.

Firstly, the most important tip I learnt the hard way:
DO NOT install Nix from the repositories, it will not configure it correctly and leave things in a state that interferes with trying to reinstall it again. Instead install it with the script given by Nix themselves in the link above:
bash <(curl -L https://nixos.org/nix/install) –daemon

I think I said previously on this forum that dependency conflicts really cry out to me for a proper version control system. Well, Nix is a package manager that would seem to be exactly the kind of version control system I had in mind. All dependency versions are kept track of for each package build, but rather than bundling them all together for each package in the overkill approach of Flatpak, they are simply symlinked to with unique paths for each version.

So the basic idea I really like, but despite having been around for a long time, the implementation as it exists today is rather a confusing mess. It is aimed more at developers than regular users, and the various bits of documentation and information around are unnecessarily convoluted, opaque, often at odds with one another, outdated, or just plain wrong.

As an example, one bit of functionality I was keen to take advantage of was the ability to manage installed packages in a declarative fashion. I.e. you have a file with your list of packages which you can keep nicely organised yourself, and then tell Nix to update based on any changes you make to it. Since I typically have a lot of software that I only use very rarely, it would be nice to be able to leave them commented out to be left uninstalled until I need them (and Nix is very fast at switching between different configurations as it doesn’t delete files unless you clean up the store with the Nix garbage collector command: nix-store –gc ). However I couldn’t get this type of setup working. The ‘official’ documented approach is apparently deprecated and I couldn’t work out what the recommended approach now actually is if just using Nix, and not the full NixOS operating system.

Anyway, having said all that, it actually isn’t too difficult to use it in a very basic way to simply install/uninstall packages or roll back/switch generations. You can find a useful cheat sheet of basic commands here:
https://christitus.com/nix-package-manager/

And you can find the package names you need with a search here:
https://search.nixos.org/packages

Click on the title of the result you want, scroll down and select the nix-env tab, and then copy the second install command given for On Non NixOS. E.g. to install hello, run:
nix-env -iA nixpkgs.hello

To install multiple packages at once I used a .nix file as described here:
https://stackoverflow.com/a/59460487

So, for example, I made a file ~/.config/nixpkg/packages.nix with a list of the packages I wanted in it as follows:

with import <nixpkgs>{}; [
package 1
package 2
package 3
]

And then installed them all at once with:
nix-env -if ~/.config/nixpkg/packages.nix

To get launchers integrated with the system you can just make a symlink as suggested in the guide above from Chris Titus:
ln -s /home/$USER/.nix-profile/share/applications/* /home/$USER/.local/share/applications/
_

Using Nix packages does seem to lead to some complications however. For example, I found that some apps that have particular graphical library API requirements (e.g. Shotcut, Kdenlive, OBS Studio, Krita and possibly Blender(?) – the typical error message you might see in the terminal log is Could not initialize GLX) would not launch without also installing nixGL:

nix-channel --add https://github.com/guibou/nixGL/archive/main.tar.gz nixgl && nix-channel --update
nix-env -iA nixgl.auto.nixGLDefault

…and then running them prefixed with that (e.g instead of running shotcut, you run nixGL shotcut).

Theming results were very similar to the Distrobox Arch install, but I got the impression that improving matters here would be a lot more tricky. I couldn’t find any good resources on this, and the one set of config setting suggestions I did find didn’t make any difference.
__

Flatpak

  • Pros: The most popular solution. GUI integration with Pamac.
  • Cons: Worst performing with launch times and memory usage ~15% higher than the average of others. Smallest selection of packages. Large downloads.

I guess most people are familiar with Flatpak such that I don’t need to introduce it. It is mostly easy to use, one notable exception for this testing being that it is more difficult to launch apps from the command line as you need to know the exact and somewhat more long winded package names that Flatpak uses. E.g. instead of running strawberry, you have to run flatpak run org.strawberrymusicplayer.strawberry

So it was a bit of a pain to go look up all the 20 full package names I needed on Flathub before I could put together the final launch command.

Some other issues I encountered with Flatpak included:

That would appear to be a bug originating from GNOME, rather than Flatpak itself, but I did not do any system updates in between the 1st and 2nd Flatpak runs at which point it appeared. So I can only conclude that it was introduced by Flatpak, presumably via their implementation from here.
https://github.com/flatpak/xdg-desktop-portal

So I had to discount all of those test runs from the final results, and in the end, Flatpak was the only one that managed to interfere with and break the underlying system (I even managed to render that VM completely unbootable in the end in the quest to understand which elements of the solution I used were truly necessary). I thought the whole point of Flatpak was that it shouldn’t mess with the base system :confused:
_

Flatpak is the worst for following the system theme by default, however it can easily be significantly improved in this regard by setting an environment variable as follows:
flatpak override --user --env=GTK_THEME=$("gsettings get org.gnome.desktop.interface gtk-theme")

This is referred to in the results as Flatpak (fixed system theme)

__

Closing thoughts

  • Don’t bother with APX
  • Distrobox is fun to play with and easy to use. Certainly worth having a look at if you are curious.
  • Nix brings some particular unique advantages, but also challenges, and so is more difficult to recommend.
  • Flatpak is the worst performing but is well established – any issues you face are likely to be encountered by others and get addressed. And in TROMjaro it comes integrated by default into Pamac.

For the time being, I’m happy enough sticking to the standard range of options provided in TROMjaro (especially having the Chaotic AUR configured out of the box which I find to be most useful). I was already inclined to avoid Flatpaks as much as possible, which these results have only reinforced my opinion of.

In the longer term I might do more focussed testing on the apps I use in Distrobox and Nix.

I feel that Nix could potentially be good for certain tools like desktop utilities (things like Variety, CopyQ, Ulauncher, Radiotray-NG) which don’t have enough of a GUI to them to be worried about theming, and which I want good reliability from and the ease to quickly roll back if anything goes wrong with them (I recall both the latter two breaking a few months ago due to dependency conflicts).

Perhaps Distrobox might be better for larger and more graphically intensive apps with its greater ease of tweaking things. It’s certainly a nice way of quickly playing with different Linux sub-systems that are well integrated with your main system. It’s a different set of pros and cons compared to running virtual machines, but certainly a useful way of running things natively that you want to keep separately installed from, or aren’t available or working properly on your main host system.
_

In the end, it is certainly nice to have all these different options available to try to help get different software working :slight_smile:

1 Like