Toolbx is a tool for Linux, which allows the use of interactive command line environments for software development and troubleshooting the host operating system, without having to install software on the host. It is built on top of Podman and other standard container technologies from OCI.
Toolbx environments have seamless access to the user’s home directory, the Wayland and X11 sockets, networking (including Avahi and CA certificates), removable devices (like USB sticks), systemd journal, SSH agent, D-Bus, ulimits, /dev and the udev database, etc.. The host file system can be accessed at /run/host
.
This is particularly useful on OSTree based operating systems like Fedora CoreOS and Silverblue. The intention of these systems is to discourage installation of software on the host, and instead install software as (or in) containers — they mostly don’t even have package managers like DNF or YUM. This makes it difficult to set up a development environment or troubleshoot the operating system in the usual way.
Toolbx solves this problem by providing a fully mutable container within which one can install their favourite development and troubleshooting tools, editors and SDKs. For example, it’s possible to do yum install ansible
without affecting the base operating system.
However, this tool doesn’t require using an OSTree based system. It works equally well on Fedora Workstation and Server, and that’s a useful way to incrementally adopt containerization.
The Toolbx environment is based on an OCI image. On Fedora this is the fedora-toolbox
image. This image is used to create a Toolbx container that offers the interactive command line environment.
Note that Toolbx makes no promise about security beyond what’s already available in the usual command line environment on the host that everybody is familiar with.
Examples of use cases that fit this description can be found here.
Welcome to the world of this powerful command line utility. No longer will project environments clash with your host operating system, nor will you be limited to a single OS version.
Dive into this manual and unlock the potential to seamlessly switch between versions, isolate projects, and avoid software conflicts on your host system. Prepare to embark on a journey of efficient development and testing with Toolbx as your trusty companion.
toolbox(1)
command.toolbox.conf(5)
file format.Toolbx environments have seamless access to the user’s home directory, the Wayland and X11 sockets, networking (including Avahi and CA certificates), removable devices (like USB sticks), systemd journal, SSH agent, D-Bus, ulimits, /dev and the udev database, etc.. The host file system can be accessed at /run/host
.
Note that Toolbx makes no promise about security beyond what’s already available in the usual command line environment on the host that everybody is familiar with.
The user ID and account details from the host operating system are propagated into the Toolbx containers, SELinux label separation is disabled, and the containers have access to the host’s Kerberos credentials cache if it’s configured to use KCM caches. Crucial configuration files, such as /etc/host.conf
, /etc/hosts
, /etc/localtime
, /etc/machine-id
, /etc/resolv.conf
and /etc/timezone
, inside the containers are kept synchronized with the host.
Toolbx containers can be identified by the com.github.containers.toolbox
label with various Podman commands (like inspect) or by the presence of the /run/.toolboxenv
file. The /run/.containerenv
file contains some metadata about the containers.
The entry point of the containers is the toolbox init-container command. It plays a role in setting up the container and mitigating the immutable nature of the configuration of OCI containers.
Toolbx has built-in support for images corresponding to different operating system distributions. It’s also possible to create custom Toolbx images, and use them with the image
command line and configuration file options.
Custom Toolbx images can be created in different ways and they need to satisfy the requirements listed below.
One way of creating a custom Toolbx image is to define its contents in a Containerfile and then use podman build --squash
to build the image. The easiest is to base the custom image on one of the built-in images, instead of any OCI image or starting from scratch.
Here’s a Containerfile for a custom image that adds Emacs, GCC and GDB to the built-in fedora-toolbox:42
image available from registry.fedoraproject.org
.
FROM registry.fedoraproject.org/fedora-toolbox:42
RUN dnf --assumeyes install emacs gdb gcc
RUN dnf clean all
The Containerfile can then be built to create a my-fedora-toolbox:42
image:
[user@hostname ~]$ podman build \
--squash \
--tag localhost/my-fedora-toolbox:42 \
/path/to/Containerfile/dir
Another possibility is to create a custom Toolbx image from an existing container by using podman commit --squash
. The easiest is to use a Toolbx container, instead of any OCI container.
Here’s how to create a custom image similar to the one above, but based on a Toolbx container created from the built-in ubuntu-toolbox:22.04
image available from quay.io/toolbx
.
Create the Toolbx container:
[user@hostname ~]$ toolbox create --distro ubuntu --release 22.04
Created container: ubuntu-toolbox-22.04
Enter with: toolbox enter ubuntu-toolbox-22.04
Alter it by installing Emacs, GCC and GDB:
[user@hostname ~]$ toolbox enter ubuntu-toolbox-22.04
⬢[user@toolbox ~]$ sudo apt update
Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Get:3 http://security.ubuntu.com/ubuntu jammy-security/main amd64 Packages [1208 kB]
…
…
…
⬢[user@toolbox ~]$ sudo apt --yes install emacs gcc gdb
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
…
…
…
⬢[user@toolbox ~]$ exit
A my-ubuntu-toolbox:22.04
image can then be created from the altered container:
[user@hostname ~]$ podman commit \
--squash \
ubuntu-toolbox-22.04 \
localhost/my-ubuntu-toolbox:22.04
Toolbx environments are very specifically configured OCI containers. Therefore, the OCI images from which these containers are created need to satisfy some requirements.
The key words “MUST”, “MUST NOT”, and “SHOULD” are to be interpreted as described in RFC 2119.
Images MUST NOT specify any entry point. This can be checked with:
[user@hostname ~]$ podman inspect \
--format '{{ .Config.Entrypoint }}' \
--type image \
quay.io/toolbx/arch-toolbox:latest
[]
Images created from base images with entry points can remove them through a Containerfile:
ENTRYPOINT []
Toolbx specifies the entry points of containers in a certain way. If images specify their own entry points then it will prevent the toolbox enter and toolbox run commands from working.
Images MUST have an empty /home
directory to be used on host operating systems (like Fedora Silverblue) where /home
is a symbolic link to the /var/home
directory. Otherwise, it will prevent the toolbox enter and toolbox run commands from working.
Images either MUST NOT have these files or they MUST be regular files:
/etc/host.conf
/etc/hosts
/etc/resolv.conf
Otherwise, it can prevent the toolbox enter and toolbox run commands from working, or the files won’t be kept synchronized with the host operating system inside containers created from those images.
Images SHOULD have the nss-myhostname or libnss_myhostname.so.2
plugin for the Name Service Switch (or NSS) functionality of the GNU C Library.
Images SHOULD prioritize this myhostname
service sufficiently high for the hosts
database in the NSS configuration file, nsswitch.conf(5). Otherwise, it can cause timeouts or errors when resolving the hostnames of containers created from those images.
For example, this is a valid configuration:
hosts: files myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns
… and this is not:
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] myhostname dns
Images SHOULD use the /etc/krb5.conf.d
directory to configure Kerberos, and the directory SHOULD be present. If the directory is present then it MUST be possible for the containers’ root
user to create a regular file inside it.
Otherwise, the Kerberos credential cache from the host operating system won’t be available inside containers created from those images. File an issue if support for a different path is needed.
Images SHOULD have the com.github.containers.toolbox="true"
label, if they fulfill these requirements.
This can be achieved through a Containerfile:
LABEL com.github.containers.toolbox="true"
… or podman commit
:
[user@hostname ~]$ podman commit \
--change 'LABEL com.github.containers.toolbox="true"' \
…
The label is meant to be used by maintainers of images to indicate that they have read this document and tested that their images work with Toolbx. Otherwise, the images won’t be fully recognized by Toolbx.
Images MUST have ldconfig(8)
to be used on host operating systems with the proprietary NVIDIA driver. Otherwise, it will prevent toolbox enter and toolbox run commands from working.
Images SHOULD have the dynamic linker cache at /etc/ld.so.cache
.
Images SHOULD use the /etc/ld.so.conf.d
directory to configure the dynamic linker cache, and the directory SHOULD be present. If the directory is present then it MUST be possible for the containers’ root user to create a regular file inside it.
File an issue if support for a different path is needed.
Images SHOULD be uniquely named so that they don’t collide with those created by others, and their names should reflect their purpose. For example, ubuntu-toolbox
is a better name than toolbox
because the ubuntu-
prefix uniquely identifies it and states its purpose.
By default, Toolbx containers are named after their corresponding images. If the image has a tag, then the tag is included in the name of the container, but it’s separated by a hyphen, not a colon. For example, the default name for containers created from the arch-toolbox:latest
images will be arch-toolbox-latest
and those from the fedora-toolbox:42
images will be fedora-toolbox-42
.
Images SHOULD use the /etc/pkcs11/modules
directory to configure PKCS #11 modules, and the directory SHOULD be present. If the directory is present then it MUST be possible for the containers’ root
user to create a regular file inside it.
Images SHOULD have the p11-kit-client.so PKCS #11 module at one of these paths:
/usr/lib/pkcs11/p11-kit-client.so
/usr/lib/aarch64-linux-gnu/pkcs11/p11-kit-client.so
/usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-client.so
/usr/lib64/pkcs11/p11-kit-client.so
Otherwise, certificates from certificate authorities (or CAs) that are available inside containers created from those images won’t be kept synchronized with the host operating system. File an issue if support for a different path is needed.
Images that include content managed by the RPM Package Manager (or RPM) SHOULD use the /usr/lib/rpm/macros.d
directory for RPM macros, and the directory SHOULD be present. If the directory is present then it MUST be possible for the containers’ root
user to create a regular file inside it.
The location of the directory for RPM macros can be checked with:
⬢[user@toolbox ~]$ rpm --eval '%_rpmmacrodir'
/usr/lib/rpm/macros.d
Otherwise, some RPM transactions can fail inside containers created from those images. File an issue if support for a different path is needed.
Images SHOULD contain the following start-up snippets for Bash, C shell and Z shell provided by VTE:
/etc/profile.d/vte.csh
/etc/profile.d/vte.sh
Otherwise, VTE-based terminal emulators will lack some features like remembering the current working directory.
Images MUST have sudo(8)
enabled for users belonging to either the sudo
or wheel
groups, and the group itself MUST exist.
Otherwise, it will prevent the toolbox enter and toolbox run commands from working. File an issue if support for a different group is really needed. However, it’s preferable to keep this list as short as possible.
Images SHOULD allow empty passwords for sudo(8)
. This can be achieved by either adding the nullok
option to the PAM(8)
configuration, or by adding the NOPASSWD
tag to the sudoers(5)
configuration.
For example, if sudo(8)
is enabled for the wheel
group, then this is a valid sudoers(5)
configuration to allow empty passwords:
%wheel ALL=(ALL) NOPASSWD: ALL
Images either MUST NOT have /etc/localtime
or it MUST be a symbolic link to a file inside the images’ /usr/share/zoneinfo
.
Images either MUST NOT have /etc/timezone
or it MUST be a regular file.
Otherwise, it can prevent the toolbox enter and toolbox run commands from working, or the files won’t be kept synchronized with the host operating system inside containers created from those images.
Images SHOULD have an empty /usr/share/empty
directory. Otherwise, depending on Podman, an instance of selinuxfs
can get mounted inside containers created from those images at /sys/fs/selinux
, and it can cause various components (like RPM) inside the containers to misbehave by tricking them into trying to use SELinux.
Images MUST have these commands:
capsh(1)
mount(8)
passwd(1)
test(1)
useradd(8)
usermod(8)
Images either MUST NOT have /etc/machine-id
or it MUST be a regular file.
Otherwise, it can prevent the toolbox enter and toolbox run commands from working.
Images SHOULD have the flatpak-spawn(1)
command. Otherwise, it won’t be possible to use toolbox(1)
inside containers created from those images.