Distrobox: your distro, somebody else's packages
/ 8 min read
Table of Contents
There is a familiar little Linux ritual. You choose a distribution, get everything the way you like it, and eventually need one application whose download page has decided that Linux means Ubuntu.
One button. One .deb. Best of luck with your other life choices.
You can spend the evening repackaging it, looking for somebody else’s repackaging of it, or wondering whether this is sufficient grounds to reinstall the laptop. There is also a pleasantly lazy option: give the application a small Ubuntu to live in and carry on using your own distro.
That is the bit of Distrobox I want to talk about. The excuse is Signal, prompted by gesslar’s wonderfully exasperated Fedora post and Claire Rosario’s Fedora 44 walkthrough. The trick applies to plenty of other software whose packaging has opinions about your operating system.
Give the package the distro it expects
Distrobox wraps a container manager such as Podman or Docker and sets up another distribution’s userspace. It also handles the plumbing that makes ordinary desktop use practical: your home directory, display through Wayland or X11, audio, and other host integration. The official overview describes what gets shared.
So you can have Fedora on the laptop, Ubuntu inside the container, and an Ubuntu application opening windows on your Fedora desktop. Its libraries and package database live in the container. Your host package manager doesn’t have to develop a sudden interest in .deb files.
Your desktop launcher ↓ Distrobox ↓Ubuntu container → application + Ubuntu libraries ↓Your existing Linux kernelThat last line matters. This is a container, so it uses the host kernel. There’s no second kernel booting in the background, and no second desktop to log into.
The direction is your choice, too. A Fedora container gives you dnf and RPMs on an Ubuntu host; an Arch container gives you pacman. Pick the userspace the package expects.
First, somewhere to put Ubuntu
Install Distrobox and a container manager on the host. I’ll use rootless Podman. Pick the command for your distribution:
# Fedorasudo dnf install distrobox podman
# Arch Linuxsudo pacman -S distrobox podman
# Recent Debian / Ubuntusudo apt updatesudo apt install distrobox podmanThe compatibility documentation covers many more hosts, including openSUSE, NixOS and immutable desktops. Some already include Distrobox; check before installing things you already own. For a host without a packaged version, there are also official installation methods.
Run distrobox as your normal user. If Podman complains about missing subordinate UID or GID ranges, follow its rootless setup documentation; reaching for sudo distrobox is not the fix.
Now create the container:
distrobox create \ --name deb-land \ --image docker.io/library/ubuntu:24.04
distrobox enter deb-landThe first entry takes a little while: Distrobox installs the bits needed to integrate the container with your machine. Later entries reuse the same container, including everything you’ve installed in it.
I’ve chosen an explicit Ubuntu release so the environment stays predictable. For a different application, choose the distribution and release its vendor actually targets. A .deb suffix alone doesn’t promise that a Debian package will work on every Ubuntu release, or vice versa.
The available options are in the create documentation.
Signal, as a real example
Signal is useful here because we can use its official APT repository, which also gives us an update path.
One detail has changed since some older guides: Signal now also publishes an official AppImage. Its Linux download page offers both. Distrobox is still useful if you want the Debian package and APT-managed updates, and the same method works for applications that haven’t discovered portable packaging yet.
This example assumes an x86_64 host; check with uname -m. Signal currently lists Linux support for amd64/x86_64 only in its system requirements.
Still inside deb-land, install the repository setup tools:
sudo apt updatesudo apt install ca-certificates curl gnupgThen add the signing key and repository, following Signal’s official Debian instructions:
curl -fsSL https://updates.signal.org/desktop/apt/keys.asc \ -o /tmp/signal-desktop-keyring.asc
gpg --dearmor --yes \ --output /tmp/signal-desktop-keyring.gpg \ /tmp/signal-desktop-keyring.asc
sudo install -o root -g root -m 0644 \ /tmp/signal-desktop-keyring.gpg \ /usr/share/keyrings/signal-desktop-keyring.gpg
curl -fsSL https://updates.signal.org/static/desktop/apt/signal-desktop.sources \ -o /tmp/signal-desktop.sources
sudo install -o root -g root -m 0644 \ /tmp/signal-desktop.sources \ /etc/apt/sources.list.d/signal-desktop.sources
sudo apt updatesudo apt install signal-desktopThe .sources file comes from Signal itself. That saves us copying an ancient repository line from a blog post and wondering why it still mentions a distribution release old enough to have a mortgage.
Run apt policy signal-desktop if you want to check where the package comes from: the candidate should point to updates.signal.org.
Put it in the application menu
From the container shell, run signal-desktop once to check that it opens. Close the window, then export its desktop entry and leave the container:
distrobox-export --app signal-desktopexitSignal should now appear in your normal application launcher. The shortcut enters the container and runs the application there; the executable and its libraries stay in Ubuntu. Distrobox’s export documentation explains the wrapper it creates.
For another graphical application, use its name instead, or pass the full path to its .desktop file inside the container.
You can also launch Signal directly from a host terminal:
distrobox enter deb-land -- signal-desktopNo need to open a container shell first. The enter command accepts a command after --.
For Signal’s account setup, follow the QR-code linking process with Signal on your phone, as described in its installation guide.
Command-line tools can come too
For a CLI example, re-enter the box with distrobox enter deb-land, install jq, and export a wrapper into a dedicated directory in the shared home:
sudo apt install jqmkdir -p "$HOME/.local/bin/deb-tools"distrobox-export --bin /usr/bin/jq --export-path "$HOME/.local/bin/deb-tools"exitBack on the host, ~/.local/bin/deb-tools/jq --version runs Ubuntu’s copy. You can add that directory to your host’s PATH if you want the shorter command. Keeping these wrappers together also makes it easier to remember which distro is supplying a tool when future-you starts investigating.
A container with quite a lot of house keys
Distrobox’s integration is the reason this works so comfortably. It also means the application can access your shared files. The project’s security notes explicitly say that sandboxing is not its main aim. Treat software installed here with the same trust you would give an ordinary desktop application.
If you’d prefer to keep container configuration files out of your usual home, create a directory and pass --home /path/to/that/directory when creating the box. This is a documented option, and a useful way to avoid applications from two distros arguing over the same dotfiles. A custom home doesn’t turn the container into a security boundary; other host access remains.
The walkthrough above uses the default shared home, so application settings and the exported CLI wrapper are visible on both sides.
Feed it occasionally
Your host’s package updates don’t update the packages inside the box. From the host, run:
distrobox upgrade deb-landThat invokes the container’s package manager. Use distrobox upgrade --all if you’ve acquired several boxes, which is suspiciously easy to do. The upgrade documentation also shows how to schedule it.
Signal updates come through its APT repository. A downloaded .deb only receives newer versions through APT if a suitable repository is configured; otherwise you’ll need to download and install newer versions yourself. Putting it in a container hasn’t hired somebody to maintain it.
To remove Signal’s launcher, re-enter with distrobox enter deb-land and run:
distrobox-export --app signal-desktop --deleteIf you exported the jq wrapper too, remove it with the same binary export command plus --delete. When you’re finished with the whole environment, close its applications, leave the shell, and run:
distrobox stop deb-landdistrobox rm deb-landDeleting the container removes its installed packages. Files in your shared home remain, including application data. A custom home also remains by default; see the removal options before assuming that deleting a box deletes everything it touched.
How far does “practically every distro” stretch?
A long way for ordinary userspace applications, provided the host can run a supported container manager. The package gets the libraries and package manager it expects, even when its vendor doesn’t offer packages for your host distro. That doesn’t extend the vendor’s support policy to your setup.
There are a few physical laws left in the room:
- CPU architecture still matters. An
amd64package doesn’t become an ARM package by moving into Ubuntu. Cross-architecture execution needs separate emulation setup. - The kernel belongs to the host. Kernel modules, hardware drivers and packages meant to reconfigure the host’s boot process need a different approach.
- Desktop integration has limits. GPU drivers and applications that depend heavily on host system services can need extra work. The official tips cover GPU integration and other special cases.
For the fairly common problem of “I need this application, and its developer only shipped packages for another distro”, though, it is a remarkably comfortable arrangement.
Ubuntu gets one application. You get to keep your laptop the way you like it. The .deb button has finally become somebody else’s problem.