Play with Distrobox!
Distrobox is a powerful tool which enables us to run multiple linux distributions and versions simultaneously, and switch among them seemlessly. In addition to the basic features provided by distrobox, I write some more scripts to make it easier to use.
Basic usage
Create a container(distrobox)
See the official repository to install and use it. For example, I can use
1 | [rijuyuezhu@rjyz-linux:~] |
And now I get into the container.
Some properties to notice:
- Many parts of the filesystem are shared between the container(u22)
and host, including
/dev
,/tmp
,/home
, etc. However, Some other places, such as/etc
,/usr
,/opt
are not shared. Hence, some programs can be effortlessly run in the container (those installed locally, e.g. anaconda), but some cannot (those installed by system-wide package manager like apt). - To access the host's filesystem from containers, use the
/run/host
directory, which mounts the host's root directory.
Export apps & bins to outside
Use distrobox export
to export an app (*.desktop
file) or a binary file from a
container out to the host. The
tutorial is clear enough, so I won't repeat it here. An example of
using this command could be find at another blog of mine.
The official tutorial is quite useful and I recommend you to read it. Also, it provides some useful tips to play with distrobox.
My advanced configurations
Distinguish in/out prompt
It could be quite confusing to distinguish between host and container, since we are using the same username, the same hostname, the same shell and the same configuration file, and sadly, the same shell prompt between them. It's necessary to make some changes to the prompt.
Since I prefer using oh my zsh, I try
to modify its theme. A tutorial to modify zsh theme could be found here.
Previously, I use the omz theme kphoen
, and I create my own
theme kphoen-my
on its basis. Firstly copy the
kphoen
theme to kphoen-my
:
1 | [rijuyuezhu@rjyz-linux:~] |
Then I modify kphoen-my.zsh-theme
as follows
1 | # kphoen-my.zsh-theme |
To view its effect, when at host the prompt is 1
2[rijuyuezhu@rjyz-linux:~ on main]
rjyz-linux
is the hostname. When in the container the
prompt is 1
2[rijuyuezhu@u22:~]
u22
is the container id. And
I give container id and hostname different colors.
The crux to manage to do this modification is to notice that, when
inside a container, the environment variable CONTAINER_ID
is set to be the container id.
Seemlessly switch
When using distrobox enter
to go from host to container,
$PWD
will be preserved; however, when using
exit
to go from container to host, it rewinds to the
directory where you entered the container. To make it seemlessly switch,
I write a script. Put the following script in ~/.zshrc
or
~/.bashrc
and ensure that your host and container share
that.
1 | # distrobox |
This enables us to use de
to switch between host and
container seemlessly1 , and it will preserve
$PWD
if $PWD
is a subdirectory of
/home
. This requirement prohibits confusing
situations where you are in a directory that is not shared between host
and container.
An example:
1 | [rijuyuezhu@rjyz-linux:~/Playground] |
Execute host commands directly in container
Distrobox provides an interesting mechanism to run host commands from
container. The official tutorial lies here.
Firstly, install flatpak on the
host. Then, when inside container, and you want to run
host commands, simply run distrobox-host-exec <cmd>
.
For example,
1 | [rijuyuezhu@u22:~] |
EXTREMELY IMPORTANT thing to notice: the command runs on the host system directly, instead of "borrowing" binary from the host. Hence, as you see, the command above prints my host's information(Ubuntu 24.04), instead of the container's(Ubuntu 22.04). However, in most cases, this is not a problem: the host and container share the same
/home
directory. But remember this to avoid unexpected results.Also, notice that environment variables are not preserved in most cases.
The official
tutorial also provides an interesting method to run host commands
seemlessly in container. It uses the
command_not_found_handle(r?)
(zsh has one more
r
) mechanism in bash/zsh. When the command is not found in
container, bash/zsh will call the function
command_not_found_handle(r?)
. Hence we can use it to
forward the corresponding command to host, as shown in the commented
part in above script. The complement part is as follows:
1 | # distrobox |
Now you can use dh
to run host commands in container.
Also, when the command cannot be found in container, it will be
forwarded to the host. For example, 1
2
3
4
5
6
7
8[rijuyuezhu@u22:~]
env node
env: ‘node’: No such file or directory
[rijuyuezhu@u22:~]
node
Welcome to Node.js v18.19.1.
Type ".help" for more information.node
installed in the container, but I can use
node
command in the container to make it run at host.
Some may argue that this is not good - we do not know which command
is run in the container and which is run at host. However, this is not a
problem, since we can use tools like zsh-syntax-highlighting
to distinguish those commands that can be found in the container and
those cannot. Also, this mechanism is only used for interactive shells
(since we put it in ~/.zshrc
or ~/.bashrc
),
and it has no effect on shell scripts.
When entering a container from host, you can use one argument to indicate which container to use. Otherwise the script uses the default, hardcoded in the script(
u22
here)↩︎