distrobox Documentation

Use any linux distribution inside your terminal. Enable both backward and forward compatibility with software and freedom to use whatever distribution...

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy distrobox on any server, homelab, or cloud container platform.

File: docs/posts/distrobox_custom.md


Create a dedicated distrobox container

Distrobox wants to be as generic as possible in supporting OCI images,
but sometimes there could be some problems:

  • The image you want to use is too old and the package manager mirrors are down
  • The image you want to use has not a supported package manager or no package
    manager at all

Requirements

The only required programs that must be available in the container so that
distrobox-init won't start the installation are:

  • the $SHELL you use (bash, zsh, fish etc etc)
  • bash-completion
  • bc
  • bzip2
  • curl
  • diffutils
  • findutils
  • gnupg2
  • hostname
  • iproute
  • iputils
  • keyutils
  • krb5-libs
  • less
  • lsof
  • man-db
  • man-pages
  • ncurses
  • nss-mdns
  • openssh-clients
  • pam
  • passwd
  • pigz
  • pinentry
  • ping
  • procps-ng
  • rsync
  • shadow-utils
  • sudo
  • tcpdump
  • time
  • traceroute
  • tree
  • tzdata
  • unzip
  • util-linux
  • vte-profile
  • wget
  • which
  • whois
  • words
  • xorg-x11-xauth
  • xz
  • zip

And optionally:

  • mesa-dri-drivers
  • mesa-vulkan-drivers
  • vulkan

If all those dependencies are met, then the distrobox-init
will simply skip the installation process and work as expected.

To test if all packages requirements are met just run this in the container:

shell
dependencies="
    bc
    bzip2
    chpasswd
    curl
    diff
    find
    findmnt
    gpg
    hostname
    less
    lsof
    man
    mount
    passwd
    pigz
    pinentry
    ping
    ps
    rsync
    script
    ssh
    sudo
    time
    tree
    umount
    unzip
    useradd
    wc
    wget
    xauth
    zip
"
for dep in ${dependencies}; do
    ! command -v "${dep}" && echo "missing $dep"
done

File: docs/posts/execute_commands_on_host.md


Execute a command on the host

It may be needed to execute commands back on the host. Be it the filemanager, an
archive manager, a container manager and so on.

Here are a couple of solutions.

With distrobox-host-exec

distrobox offers the distrobox-host-exec helper, that can be used exactly for this.

See distrobox-host-exec.

console
user@fedora-distrobox:~$ which podman
/usr/bin/which: no podman in [...]
user@fedora-distrobox:~$ distrobox-host-exec podman version # <-- this is executed on host.
Client:
Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.6
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

Server:
Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.6
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

Another way to execute commands on the host, is to create executables symlinking distrobox-host-exec:

console
user@fedora-distrobox:~$ ln -s /usr/bin/distrobox-host-exec /usr/local/bin/podman
user@fedora-distrobox:~$ ls -l /usr/local/bin/podman
lrwxrwxrwx. 1 root root 51 Jul 11 19:26 /usr/local/bin/podman -> /usr/bin/distrobox-host-exec
user@fedora-distrobox:~$ podman version # <-- this is executed on host. Equivalent to "distrobox-host-exec podman version"
Client:
Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.6
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

Server:
Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.6
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

Integrate host with container seamlessly

Another cool trick we can pull, is to use the handy command_not_found_handle function
to try and execute missing commands in the container on the host.

bash or zsh

Place this in your ~/.profile:

shell
command_not_found_handle() {
# don't run if not in a container
  if [ ! -e /run/.containerenv ] && [ ! -e /.dockerenv ]; then
    exit 127
  fi
  
  distrobox-host-exec "${@}"
}
if [ -n "${ZSH_VERSION-}" ]; then
  command_not_found_handler() {
    command_not_found_handle "$@"
 }
fi

And then, run source ~/.profile to reload .profile in the current session.

fish

Place this snippet in a new fish function file (~/.config/fish/functions/fish_command_not_found.fish):

fish
function fish_command_not_found
    # "In a container" check
    if test -e /run/.containerenv -o -e /.dockerenv
        distrobox-host-exec $argv
    else
        __fish_default_command_not_found_handler $argv
    end
end

And restart your terminal. Now when a command does not exist on your container,
it will be automatically executed back on the host:

shell
user@fedora-distrobox:~$ which podman
/usr/bin/which: no podman in [...]
user@fedora-distrobox:~$ podman version # <-- this is automatically executed on host.
Client:
Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.6
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

Server:
Version:      3.4.2
API Version:  3.4.2
Go Version:   go1.16.6
Built:        Thu Jan  1 01:00:00 1970
OS/Arch:      linux/amd64

This is also useful to open code, xdg-open, or flatpak from within the container
seamlessly.


File: docs/posts/install_lilipod_static.md

Install Lilipod in a static manner

If on your distribution (eg. SteamOS) can be difficult to install something and keep it
between updates, then you could use this guide to install lilipod in your $HOME.

Lilipod is a very simple container manager with minimal features to:

  • Download and manager images
  • Create and run containers

To install lilipod:

  1. Add the Path you've chosen to install to your PATH (by default it's $HOME/.local/bin.
  2. Ensure you have /etc/subuid and /etc/subgid, if you don't do:
    • sudo touch /etc/subuid /etc/subgid
    • sudo usermod --add-subuid 100000-165535 --add-subgid 100000-165535 $USER

This is particularly indicated also for completely sudoless setups, where you don't
have any superuser access to the system, like for example company provided computers.

Download the latest release of lilipod
and put it somewhere in your $PATH

Provided the only dependency on the host (newuidmap/newgidmap, of the package uidmap or shadow),
you should be good to go.

To uninstall, just delete the binary.


File: docs/posts/install_podman_static.md

Install Podman in a static manner

If on your distribution (eg. SteamOS) can be difficult to install something and keep it
between updates, then you could use this guide to install podman in your $HOME.

  1. Add the Path you've chosen to install to your PATH (by default it's $HOME/.local/bin.
  2. Ensure you have /etc/subuid and /etc/subgid, if you don't do:
    • sudo touch /etc/subuid /etc/subgid
    • sudo usermod --add-subuid 100000-165535 --add-subgid 100000-165535 $USER

This is particularly indicated also for completely sudoless setups, where you don't
have any superuser access to the system, like for example company provided computers.

Download the latest release of podman-launcher,
make it executable and put it somewhere in your $PATH

Provided the only dependency on the host (newuidmap/newgidmap, of the package uidmap or shadow),
you should be good to go.

To uninstall, just delete the binary.


File: docs/posts/integrate_vscode_distrobox.md


Integrate VSCode and Distrobox

VScode doesn't need presentations, and it's a powerful tool for development.
You may want to use it, but how to handle the dualism between host and container?

In this experiment we will use VSCodium as an opensource
alternative to VSCode. Dev Containers extension works only
for non-opensource version of VS code. There are community made extensions like
DevPod Containers that work in VSCodium

This guide has become outdated and you will need to expect that some things broke since then.

From distrobox

Well, you could just install VSCodium in your Distrobox of choice, and export it!

For example using an Arch Linux container (We use --home so to not clutter our home directory.
You can change it if you have VSCode configuration in your home directory that you like):

shell
~$ distrobox create --image archlinux:latest --name arch-distrobox --home ./devcontainer
~$ distrobox enter --name arch-distrobox
user@arch-distrobox:~$

Download the deb file
HERE, or in Arch case just install

shell
user@arch-distrobox:~$ sudo pacman -S code

Now that we have installed it, we can export it:

shell
user@ubuntu-distrobox:~$ distrobox-export --app code

For proprietary version you need to use the binary hosted on AUR.

To enable and install from AUR do:

bash
sudo pacman -Syu git base-devel &&\
git clone https://aur.archlinux.org/yay.git &&\
cd yay &&\
makepkg -si &&\
yay -S visual-studio-code-bin &&\
distrobox-export --app code

And that's really it, you'll have VSCode in your app list, and it will run from
the Distrobox itself, so it will have access to all the software and tools inside
it without problems.

Manage podman from Distrobox

We will use the
podman-remote
to manage our containers running on host

  1. Install
    Dev Containers extension
    in VSCode
  2. Make sure that podman sockets is enabled on the host system
    ls -l /run/user/$(id -u)/podman/podman.sock
    if it isn't, enable it with:
    systemctl --user enable --now podman.socket
  3. Inside the Distrobox install podman to provide podman-remote
    sudo pacman -Syu podman
  4. Check if it's working by running:
    podman-remote info
  5. Configure Dev Containers Extension by putting podman-remote in
    vscode://settings/dev.containers.dockerPath
  6. If you click refresh in Dev Containers extension you should see your host's containers

From flatpak

Alternatively you may want to install VSCode on your host. We will explore how
to integrate VSCode installed via Flatpak with Distrobox.

For this one you'll need to use VSCode from Microsoft, and not VSCodium, in order
to have access to the remote containers extension.

First step install it

shell
~$ flatpak install --user app/com.visualstudio.code

Second step, extensions

Now we want to install VSCode Dev Containers extension

Third step podman wrapper

Being in a Flatpak, we will need access to host's podman to be
able to use the containers. Place this in your ~/.local/bin/podman-host
In case of access to host's docker to be
able to use the containers, use ~/.local/bin/docker-host

For podman:

shell
curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/extras/podman-host -o ~/.local/bin/podman-host
chmod +x ~/.local/bin/podman-host

For docker:

shell
curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/extras/docker-host -o ~/.local/bin/docker-host
chmod +x ~/.local/bin/docker-host

Open VSCode settings (Ctrl+,) and head to Remote>Containers>Docker Path and
set it to the path of /home/<your-user>/.local/bin/podman-host (or docker-host in case of docker), like in the example

This will give a way to execute host's container manager from within the
flatpak app.

Final Result

After that, we're good to go! Open VSCode and Attach to Remote Container:

And let's choose our Distrobox

And we're good to go! We have our VSCode remote session inside our Distrobox container!

Open VSCode directly attached to our Distrobox

You may want to instead have a more direct way to launch your VSCode when you're already in your project directory,
in this case you can use vscode-distrobox script:

shell
curl -s https://raw.githubusercontent.com/89luca89/distrobox/main/extras/vscode-distrobox -o ~/.local/bin/vscode-distrobox
chmod +x ~/.local/bin/vscode-distrobox

This will make it easy to launch VSCode attached to target distrobox, on a target path:

vscode-distrobox my-distrobox /path/to/project


File: docs/posts/posts.md


Latest posts


File: docs/posts/run_libvirt_in_distrobox.md

Using an immutable distribution

If you are on an immutable distribution (Silverblue/Kionite, Aeon/Kalpa) chances are that
installing lots and lots of packages on the base system is not advisable.

One way is to use a distrobox for them.

Prepare the container

To run libvirt/qemu/kvm we need a systemd container and we need a rootful container
to be able to use it, see this tip
to have a list of compatible images.
We will use in this example OpenSUSE's dedicated distrobox image:

Assembly file:

ini
[libvirt]
image=registry.opensuse.org/opensuse/distrobox:latest
pull=true
init=true
root=true
entry=true
start_now=false
unshare_all=true
additional_packages="systemd"
# Basic utilities for terminal use
init_hooks="zypper in -y --no-recommends openssh-server patterns-server-kvm_server patterns-server-kvm_tools qemu-arm qemu-ppc qemu-s390x qemu-extra qemu-linux-user qemu-hw-display-virtio-gpu-pci qemu-hw-display-virtio-gpu"
init_hooks="systemctl enable sshd.service"
init_hooks="systemctl enable virtqemud.socket virtnetworkd.socket virtstoraged.socket virtnodedevd.socket"
# Add the default user to the libvirt group
init_hooks="usermod -aG libvirt ${USER}"
# Expose container ssh on host
additional_flags="-p 2222:22"
# Export virt-manager
exported_apps="virt-manager"

Alternatively, command line:

console
distrobox create --pull --root --init --unshare-all --image registry.opensuse.org/opensuse/distrobox:latest --name libvirtd --additional-flags "-p 2222:22" \
  --init-hooks "zypper in -y --no-recommends openssh-server patterns-server-kvm_server patterns-server-kvm_tools qemu-arm qemu-ppc qemu-s390x qemu-extra qemu-linux-user qemu-hw-display-virtio-gpu-pci qemu-hw-display-virtio-gpu && systemctl enable sshd.service && systemctl enable virtqemud.socket virtnetworkd.socket virtstoraged.socket virtnodedevd.socket && usermod -aG libvirt $USER"

distrobox enter --root libvirtd -- distrobox-export --app virt-manager

Launch from the container

Simply select the Virt Manager (on libvirt) entry in your menu, entry your root password and you're done!

Connect via SSH

You can alternatively connect from an existing VirtManager

Now you will need to Add a connection:

Then set it like this:

  • Tick the "Use ssh" option
  • username: <your-user-name>
  • hostname: 127.0.0.1:2222

Optionally you can set it to autoconnect.

Now you can simply double click the connection to activate it, you'll be prompted
with your password, insert the same password as the host:

And you should be good to go!