██▓ █ ██ ██ ▄█▀ ███▄ ▄███▓ ▓█████▄ ▓█████ ██▒ █▓ ▓██▒ ██ ▓██▒ ██▄█▒ ▓██▒▀█▀ ██▒ ▒██▀ ██▌▓█ ▀▓██░ █▒ ▒██░ ▓██ ▒██░▓███▄░ ▓██ ▓██░ ░██ █▌▒███ ▓██ █▒░ ▒██░ ▓▓█ ░██░▓██ █▄ ▒██ ▒██ ░▓█▄ ▌▒▓█ ▄ ▒██ █░░ ░██████▒▒▒█████▓ ▒██▒ █▄▒██▒ ░██▒ ██▓ ░▒████▓ ░▒████▒ ▒▀█░ ░ ▒░▓ ░░▒▓▒ ▒ ▒ ▒ ▒▒ ▓▒░ ▒░ ░ ░ ▒▓▒ ▒▒▓ ▒ ░░ ▒░ ░ ░ ▐░ ░ ░ ▒ ░░░▒░ ░ ░ ░ ░▒ ▒░░ ░ ░ ░▒ ░ ▒ ▒ ░ ░ ░ ░ ░░ ░ ░ ░░░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
Notes on developing inside Distrobox
2025-03-13
I use a Fedora Atomic desktop, Bluefin. Because most of the operating system is read-only, I prefer to develop inside a Distrobox container. This allows me to install packages specifically for development within the Distrobox container.
How my setup works
I use Debian in Distrobox (called "Dev") on Fedora Atomic Bluefin, and install most of my packages through Homebrew. My "Dev" container shares the same home directory as the host system.
I mostly do everything out of this distrobox, including running certain commands on the host.
Tell GhosTTY to open a shell inside the box on start
First, because I can't be bothered entering the Distrobox manually each time, I have my terminal of choice setup to automatically SSH into it.
Here is the config line for GhosTTY:
# Config location: ~/.config/ghostty/config
command = /usr/bin/bash -c 'distrobox enter dev'
Now when I open GhosTTY, we know I mean business 😎
Execute certain commands on the host system
There is still a subset of things I need to do on the host system, like running
updates, interacting with systemd, and installing flatpack packages to the host.
I could open up a separate terminal for the host, but I am extremely lazy
motivated by convenience.
The following Zsh function will give me an escape hatch function called host
.
If I run it without any arguments, it opens a shell in the host system (I can
return at any time with exit
). If I add
arguments, it runs the command on the host and I get the stdout.
if [ -n "$DISTROBOX_ENTER_PATH" ]; then
# Executes a command on the host
host() {
local host_zsh
host_zsh=$(distrobox-host-exec command -v zsh)
if [[ $# -eq 0 ]]; then
distrobox-host-exec -- env NO_MOTD=true "$host_zsh"
else
distrobox-host-exec -- env NO_MOTD=true "$host_zsh" -c "$*"
fi
}
# add aliases here (see below)
fi
Then, inside the condition block, I add aliases for whatever it makes sense to execute on the host; for example, anything system related.
alias ujust='host ujust'
alias open='host xdg-open'
alias code='host code'
alias flatpak='host flatpak'
alias rpm-ostree='host rpm-ostree'
alias bootc='host bootc'
alias journalctl='host journalctl'
alias systemctl='host systemctl'
alias htop='host htop'
alias uptime='host uptime'
alias distrobox-upgrade='host distrobox-upgrade'
alias distrobox='host distrobox'
Why do I have a condition block? Because I use the same dotfiles for the host
and the distrobox container. Again, I'm lazy motivated by convenience.
Share Docker socket with the host system
To keep things simple, I install docker and docker-compose in the container and point them at the host's docker socket. This means they share access to the containers and volumes.
First, I have to install the docker-compose
plugin and configure it:
# Alias the host docker socket
sudo ln -s /var/run/docker.sock /run/host/var/run/docker.sock
brew install docker docker-compose
Then I add docker-compose
as a docker
plugin by adding the following to
~/.config/docker/config.json
:
{
"cliPluginsExtraDirs": ["/home/linuxbrew/.linuxbrew/lib/docker/cli-plugins"]
}
Share 1Password SSH daemon with host
I use the host's 1Password package (installed using rpm-ostree) to provision my SSH keys. Using the below, I can seamlessly use the host's 1Password SSH daemon:
sudo mkdir -p /opt/1Password
sudo ln -s /run/host/opt/1Password/op-ssh-sign /opt/1Password/
git config --global gpg.ssh.program "/opt/1Password/op-ssh-sign"
Share clipboard with host
xsel
is the only clipboard that I've found works within the container
if [ -n "$DISTROBOX_ENTER_PATH" ]; then
brew install xsel
fi
Set Zsh as default shell
I like to set zsh as the default shell within the container
# Choose ZSH as default shell
command -v zsh | sudo tee -a /etc/shells # Add zsh to /etc/shells
sudo chsh -s "$(command -v zsh)" "${USER}" # Set zsh as default shell