devbox
Ubuntu and Alpine images for interactive development and CI jobs, built on
core in three tiers. Each image runs a Zsh login shell as
sysadmin (UID and GID 1000) with passwordless sudo. The AI images
build FROM devbox.
- Images
- GHCR
ghcr.io/hambn/devbox - Docker Hub
docker.io/hambn/devbox
- GHCR
Images
ubuntu-lite: Ubuntu 24.04 with a Zsh shell, Git, editors, and search tools.- Base:
core:ubuntu - Tags:
ubuntu-lite - Included software: the lite tier
- Base:
alpine-lite: Alpine 3.24 with the same shell and tools.- Base:
core:alpine - Tags:
alpine-lite - Included software: the lite tier
- Base:
ubuntu-full: Ubuntu 24.04 with language toolchains, the Docker CLI, and Kubernetes and forge CLIs.- Base:
core:ubuntu - Tags:
ubuntu-full - Included software: the full tier
- Base:
alpine-full: Alpine 3.24 with the same toolchains and OpenRC in place of systemd.- Base:
core:alpine - Tags:
alpine-full - Included software: the full tier
- Base:
ubuntu-browser:ubuntu-fullplus chromedp headless-shell (opens in new tab).- Base:
core:ubuntu - Tags:
ubuntu-browser,latest - Included software: the browser tier
- Base:
alpine-browser:alpine-fullplus Chromium.- Base:
core:alpine - Tags:
alpine-browser - Included software: the browser tier
- Base:
Pull ghcr.io/hambn/devbox:<tag> or docker.io/hambn/devbox:<tag>. Every tag moves
when the image is rebuilt; pin a digest to keep one build. Tool versions are pinned as
ARG defaults in the Dockerfile (opens in new tab).
Tiers
| Tier | Use it for |
|---|---|
| lite | Quick interactive work, or a small CI base when you install your own tools. |
| full | Development and CI with Python, Node.js, Go, and the Docker, Kubernetes, and forge CLIs. |
| browser | Agents and tests that drive a headless browser, found at $BROWSER_BIN. Run it with --shm-size=1g. |
Every tier starts in /home/sysadmin with /bin/zsh -l. /home/sysadmin also holds
the Zsh configuration. A bind mount or Kubernetes volume over the whole directory hides
it, so mount subdirectories such as ~/.cache instead. A new Docker named volume is
safe, because Docker copies the image's files into it on first use.
npm install -g installs into /home/sysadmin/.local, which comes first on PATH. An
agent can therefore update itself without sudo, and its newer version takes
precedence over the pinned one in /usr/local/bin. The update lives in the
container's home directory, so a new container starts with the pinned version again.
Included software
Each tier contains everything in the tier before it.
lite
- Shell
- Zsh with the Oh My Zsh libraries and its
gitandkubectlplugins - zsh-autosuggestions and zsh-syntax-highlighting
- Zsh with the Oh My Zsh libraries and its
- Version control: Git and Git LFS
- Editors and terminal: Neovim (
$EDITOR), tmux, and Ghostty terminfo - Search and text: fzf, ripgrep, fd, jq, and less
- Network: the OpenSSH client and
pingwithcap_net_raw
full
- Languages
- Python 3 with pip, pipx, and uv
- Node.js with npm, pnpm, and Yarn
- Go
- Build toolchain: build-essential on Ubuntu or alpine-sdk on Alpine, CMake, Ninja, and Autotools
- Containers
- Docker CLI with Buildx and Compose;
sysadminis in thedockergroup - Ubuntu also installs the Docker Engine and containerd, disabled by default
- Docker CLI with Buildx and Compose;
- Kubernetes: kubectl with Zsh completion, Helm, Kustomize, and yq
- Forges and networking: GitHub CLI, GitLab CLI, and Tailscale
- Linters: ShellCheck, shfmt, and yamllint
- Network tools: HTTPie, mitmproxy, nginx, nmap, tcpdump, mtr, and iperf3
- Other: archive, media, and process tools, and a
/workspacedirectory owned bysysadmin
browser
- Ubuntu:
chromedp/headless-shellat/headless-shell/headless-shell - Alpine: the
chromiumpackage at/usr/bin/chromium-browser
$BROWSER_BIN points to the browser on both.
Running systemd
No daemon starts with the default command. For container builds, mount the host's
Docker socket or set DOCKER_HOST.
On ubuntu-full and ubuntu-browser, a privileged container started as root with
/sbin/init boots systemd with a container profile:
multi-user.targetas the default target- Logs on the console and a volatile journal
/tmpkept across the boot, with 30-day cleanup- Lingering enabled for
sysadmin - Hardware, getty, and apt update units masked
- Docker, containerd, nginx, and SSH installed but disabled; enable the ones you need
The Alpine images use OpenRC and install no Docker daemon.
Use cases
- Interactive development shell on a checkout with Docker, optionally using the host Docker daemon.
- Reusable shell with a persistent home with Docker Compose.
- Rootless development shell or Quadlet service with Podman.
- Disposable cluster development pod with Kubernetes.
- Long-running cluster pod with a persistent workspace with Helm.
- Editor-attached development container with Dev Container.
- CI job with the full toolchain with GitHub Actions or GitLab CI.
Sources
- Ubuntu container image (opens in new tab) and Alpine Linux container image (opens in new tab)
- chromedp/headless-shell (opens in new tab)
- Oh My Zsh (opens in new tab), zsh-autosuggestions (opens in new tab), zsh-syntax-highlighting (opens in new tab)
- Go downloads (opens in new tab), Node.js downloads (opens in new tab), Node.js unofficial musl builds (opens in new tab), uv (opens in new tab)
- kubectl (opens in new tab), Helm (opens in new tab), Kustomize (opens in new tab), yq (opens in new tab)
- GitHub CLI (opens in new tab), GitLab CLI (opens in new tab), Tailscale static binaries (opens in new tab)