Declaring your own personal distroboxes

Every once in a while I see someone complaining that they've lost work because their toolbox/distrobox got destroyed.

I'm going to go over how we can use declarative config to remove this bit of jank from our lives. We don't want distroboxes to be pets either! This is part of a grander infrastructure as code concept but let's apply it to our local CLI environment.

First, let's familiarize ourselves with the distrobox assemble command:

distrobox/docs/usage/distrobox-assemble.md at main · 89luca89/distrobox
Use any linux distribution inside your terminal. Enable both backward and forward compatibility with software and freedom to use whatever distribution you’re more comfortable with. Mirror available…

Bookmark this!

This lets us use a config file to create our boxes just how we want them. Here's a quick example from my distrobox.ini from Bluefin:

[ubuntu]
image=ghcr.io/ublue-os/ubuntu-toolbox:latest
#additional_packages=" " 
#export=" "
init=false
nvidia=false
pull=true
root=false
replace=true

An Ubuntu container

We can then recreate the container we want with a distrobox assemble create --replace --file ~/distrobox.ini

This is handy for when you want to be able to set up a container the same way every time. Let's add some stuff:

additional_packages="ansible lynx chromium neofetch cmus"
export="app chromium"

Adding some packages and exporting Chromium to the host system.

And now every time you run the assemble command it will recreate this for you. Just enable nvidia once and then you'll have what you need. Now let's do a workload. Here's a nice setup from @lzumot that we ship with bluefin-dx:

[mlbox]
image=nvcr.io/nvidia/pytorch:23.08-py3
additional_packages="nano git htop"
init_hooks="pip3 install huggingface_hub tokenizers transformers accelerate datasets wandb peft bitsandbytes fastcore fastprogress watermark torchmetrics deepspeed"
pre-init-hooks="/init_script.sh"
nvidia=true
pull=true
root=false
replace=false

Warning, this thing is 20+ GB, you data scientists know how to eat up disk! Nom nom.

Now let's make this easier to fit into our workflow. Toss this in your justfile and you can now do a just assemble and it will build all your distroboxes right on the spot.

Always fresh and clean, and more importantly, you don't end up in a situation where you're losing time because of a container breaking. It's up to you if you want to keep this a manual operation or you can make a service unit to do it in the background for you.

Automating it in GitHub

For more substantial customizations I recommend checking out boxkit, which is a set of GitHub actions designed to build your distrobox in CI/CD so that you don't need to build things locally. Check out obs-studio-portable and bazzite-arch for more sophisticated examples.

This is handy for a few reasons over distrobox assemble:

  • When I assemble one made in CI it just downloads the layers and recreates it, no need to wait for the hook and package manager to do this on my local machine, especially since it runs every day.
  • I'd end up having to care about that file on all my machines instead of getting the finished product right away. I have multiple machines and the value I get out of boxkit is that I get the same thing everywhere without having to build the boxes individually on each machine.
  • You can add all the packages you need that distrobox normally installs on creation, so that they always launch fast every single time.

The CI/CD approach is also nice when you want to make substantial additions to the container. This way you're not waiting for the package manager to do this on your local machines, you have GitHub do it on a cron and then all I have to do is just assemble and I download the layers from a fast mirror close to me. No waiting for dnf5, or remembering to turn on libeatmydata in apt.

Plus think of all the arguments people are having about whether or not to enable fastestmirror=1. Ain't no one got time for that.

But most of you just need assemble

Setting up CI/CD for a handful of containers is like using a rocket launcher when all you need is a taco. Keeping your ini file in a dropbox or some other lightweight syncing solution will do the trick.

The reason we do it for Universal Blue is to kick off the pattern. I don't want to maintain these things, so we all just do it together instead. Then you can start with examples and customize to your needs. Nice.

Show Comments