Container-based development with toolboxcutter
4 min read
Toolbx is a tool for Linux systems, specifically Fedora, that creates and manages development environment containers. Its purpose is to group development dependencies in a mutable container separate from the base operating system both for the benefit of separating concerns and allowing dev. environments to be reused and shared.
The toolbx project was originally named toolbox and the command reflects this.
Typical usage might look like this:
[user@hostname ~]$ toolbox create Created container: fedora-toolbox-36 Enter with: toolbox enter [user@hostname ~]$ toolbox enter
While this may provide the foundation of a compelling development workflow, I felt something was missing. From my perspective, a development environment is specific to the project being developed.
So, you could use toolbox like this:
[user@hostname ~]$ cd my-project [user@hostname my-project]$ toolbox create my-project-toolbox [user@hostname my-project]$ toolbox enter my-project-toolbox
And proceed to install dev. dependencies in your container, but I want a toolbox that can be created and recreated on-demand, from a
Dockerfile, for example. It then makes sense to commit this dev. environment manifest to your project so that your environment's specifications follow your project's development. Ultimately, what I sought was a means to more easily manage per-project toolboxes, which prompted the creation of toolboxcutter.
toolboxcutter (invoked as
tb) is a script that manages the lifecycle of per-project development containers using
It began life as a zsh function, but as its feature set expanded, I realized it had become a project of its own, so I ported it to a standalone bash script.
It's designed to be easy to use. Within a directory containing a toolbox-based
Dockerfile, simply run
tb and your toolbox will be entered, creating the container if necessary.
Install it on Fedora with these commands:
dnf copr enable jcrd/toolboxcutter dnf install toolboxcutter
A complete overview of its functionality is given in its command-line usage message:
usage: tb [command] With no command, enter toolbox. commands: init IMAGE Initialize Dockerfile based on IMAGE create [IMAGE] Create container (from IMAGE if provided) recreate Remove and recreate container build Build image options: -n NAME Name of image -c Build without cache rebuild Remove container and rebuild image options: -n NAME Name of image -c Build without cache stop Stop container rm Remove container rmi Remove image rpkg Build rpm via rpkg options: -n NAME rpkg spec template name -e EXT rpkg spec template extension rpkg-install Build and install rpm via rpkg options: -n NAME rpkg spec template name -e EXT rpkg spec template extension -r NAME Name of produced rpm to install run COMMAND Run COMMAND in toolbox version Show version
tb is largely a wrapper around toolbox, most of its commands translate directly to their toolbox equivalents. These are supplemented with image and container management commands that would otherwise require invoking podman.
Building RPM packages
Unique to toolboxcutter is its ability to build RPM packages from rpkg SPEC template files. This feature has been instrumental in the development, testing, and dogfooding of my own projects while using Fedora. I believe it elevates
tb to a truly powerful developer tool for these reasons:
Build dependencies need only exist in your project's container, minimizing pollution of your workstation's environment;
Most importantly, the development-packaging cycle is combined into a single fluid process, providing interactivity benefits similar to that of a read-eval-print loop.
This functionality depends on the availability of rpkg in the toolbox container itself, so your project's
Dockerfile should install it. This is the
Dockerfile for the base image I use:
FROM registry.fedoraproject.org/fedora-toolbox:36 RUN dnf install -y git-subtree RUN dnf install -y make RUN dnf install -y neovim RUN dnf install -y rpkg # Install rpkg RUN dnf install -y rpmdevtools RUN dnf install -y zsh CMD /usr/bin/zsh
Any images or containers derived from this can be used to build RPM packages provided a SPEC template. By default,
tb looks for this file at
spec/*.rpkg.spec in your project's root directory.
Here is toolboxcutter's own SPEC template file:
Documentation about the format of these templates is sparse and much of my knowledge was gleaned from existing files. Nevertheless—perhaps with a bit of trial and error—it is possible to run
tb rpkg-install in your project's directory to produce an installable RPM package with your latest changes!