Install Docker in experimental Void images

Make the local-only void-exp rootfs useful as a dev VM baseline by baking Docker and Compose into the XBPS package set instead of leaving container setup to manual follow-up.

Enable the docker runit service during image assembly, add a small boot preflight that loads the needed netfilter/overlay modules and applies the Docker sysctl file before dockerd starts, and keep the Void cleanup path removing caches, docs, and stale get-docker artifacts.

Refresh the README and repo guidance to describe Docker as part of the current Void image contract and to remind users that they need to rebuild and recreate Void VMs to pick it up.

Verified with bash -n make-rootfs-void.sh and git diff --check for the touched files. I did not run a live make rootfs-void or boot a fresh Void VM in this pass.
This commit is contained in:
Thales Maciel 2026-03-19 15:52:30 -03:00
parent c298ed2fc1
commit 5ad3b505dd
No known key found for this signature in database
GPG key ID: 33112E6833C34679
4 changed files with 72 additions and 3 deletions

View file

@ -36,7 +36,7 @@
- Manual verification for VM lifecycle changes: `./banger vm create`, confirm SSH access, then stop/delete the VM. - Manual verification for VM lifecycle changes: `./banger vm create`, confirm SSH access, then stop/delete the VM.
- For host-integration changes, run `./banger doctor` as a quick readiness check before the live VM smoke. - For host-integration changes, run `./banger doctor` as a quick readiness check before the live VM smoke.
- Rebuilt images now include `mise`, `opencode`, `tmux-resurrect`/`tmux-continuum` defaults for `root`, and the `banger-vsock-agent` service used by the SSH reminder and guest health-check path; if you change guest provisioning, document whether users need to rebuild `./runtime/rootfs-docker.ext4` or another base image to pick it up. - Rebuilt images now include `mise`, `opencode`, `tmux-resurrect`/`tmux-continuum` defaults for `root`, and the `banger-vsock-agent` service used by the SSH reminder and guest health-check path; if you change guest provisioning, document whether users need to rebuild `./runtime/rootfs-docker.ext4` or another base image to pick it up.
- The experimental Void rootfs path is intentionally lean: keep it limited to boot, SSH, the vsock HTTP health agent, a `bash` root shell while leaving `/bin/sh` alone, and the `/root` work-seed unless the user explicitly wants more baked in. - The experimental Void rootfs path now includes the repo's basic dev baseline plus Docker and Compose, alongside boot, SSH, the vsock HTTP health agent, a `bash` root shell while leaving `/bin/sh` alone, and the `/root` work-seed. Keep further baked-in tooling deliberate and user-driven.
- Rebuilt images also emit a `work-seed.ext4` sidecar used to speed up future VM creates. If you touch `/root` provisioning, verify both the rootfs and the work-seed output. - Rebuilt images also emit a `work-seed.ext4` sidecar used to speed up future VM creates. If you touch `/root` provisioning, verify both the rootfs and the work-seed output.
- The daemon may keep idle TAP devices in a pool for faster creates. Smoke tests should treat `tap-pool-*` devices as reusable capacity, not cleanup leaks. - The daemon may keep idle TAP devices in a pool for faster creates. Smoke tests should treat `tap-pool-*` devices as reusable capacity, not cleanup leaks.
- If you add a new operational workflow, document how to exercise it in `README.md`. - If you add a new operational workflow, document how to exercise it in `README.md`.

View file

@ -325,13 +325,14 @@ This path is intentionally local-only and does not change the default Debian
image flow. It reuses the current runtime bundle kernel, initrd, and modules, image flow. It reuses the current runtime bundle kernel, initrd, and modules,
but builds a lean `x86_64-glibc` Void userspace with: but builds a lean `x86_64-glibc` Void userspace with:
- `bash` installed for interactive/admin use - `bash` installed for interactive/admin use
- `docker` plus `docker-compose` installed from Void packages
- the `docker` runit service enabled, with Docker netfilter/forwarding kernel prep
- `openssh` enabled under runit - `openssh` enabled under runit
- the bundled `banger-vsock-agent` health agent enabled under runit - the bundled `banger-vsock-agent` health agent enabled under runit
- `root` normalized to `/bin/bash` while keeping `/bin/sh` as the distro's system shell - `root` normalized to `/bin/bash` while keeping `/bin/sh` as the distro's system shell
- a generated `/root` work-seed for fast creates - a generated `/root` work-seed for fast creates
It does not install the Debian-oriented extras from rebuilt default images: It does not install the Debian-oriented extras from rebuilt default images:
- no Docker
- no `mise` - no `mise`
- no `opencode` - no `opencode`
- no tmux plugin defaults - no tmux plugin defaults
@ -354,6 +355,10 @@ make void-register
./banger vm ssh void-dev ./banger vm ssh void-dev
``` ```
Rebuild the Void rootfs and recreate existing `void-exp` VMs after changing the
package set or guest provisioning; restart alone will not update the image
contents or `/root` work-seed.
There is also a smoke path for the experimental image: There is also a smoke path for the experimental image:
```bash ```bash
make verify-void make verify-void

View file

@ -137,6 +137,52 @@ EOF
sudo ln -snf /etc/sv/banger-vsock-agent "$ROOT_MOUNT/etc/runit/runsvdir/default/banger-vsock-agent" sudo ln -snf /etc/sv/banger-vsock-agent "$ROOT_MOUNT/etc/runit/runsvdir/default/banger-vsock-agent"
} }
configure_docker_bootstrap() {
local modules_conf="$ROOT_MOUNT/etc/modules-load.d/docker-netfilter.conf"
local sysctl_conf="$ROOT_MOUNT/etc/sysctl.d/99-docker.conf"
local service_dir="$ROOT_MOUNT/etc/sv/docker"
local run_path="$service_dir/run"
local orig_run_path="$service_dir/run.orig"
local preflight_path="$ROOT_MOUNT/usr/local/bin/banger-docker-preflight"
sudo mkdir -p "$ROOT_MOUNT/etc/modules-load.d" "$ROOT_MOUNT/etc/sysctl.d" "$ROOT_MOUNT/usr/local/bin"
cat <<'EOF' | sudo tee "$modules_conf" >/dev/null
nf_tables
nft_chain_nat
veth
br_netfilter
overlay
EOF
cat <<'EOF' | sudo tee "$sysctl_conf" >/dev/null
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
cat <<'EOF' | sudo tee "$preflight_path" >/dev/null
#!/bin/sh
for module in nf_tables nft_chain_nat veth br_netfilter overlay; do
modprobe "$module" 2>/dev/null || true
done
if command -v sysctl >/dev/null 2>&1; then
sysctl --load /etc/sysctl.d/99-docker.conf >/dev/null 2>&1 || true
fi
EOF
if [[ ! -f "$run_path" ]]; then
log "Void rootfs is missing /etc/sv/docker/run after docker install"
exit 1
fi
sudo install -m 0755 "$run_path" "$orig_run_path"
cat <<'EOF' | sudo tee "$run_path" >/dev/null
#!/bin/sh
set -e
/usr/local/bin/banger-docker-preflight
exec /etc/sv/docker/run.orig
EOF
sudo chmod 0644 "$modules_conf" "$sysctl_conf"
sudo chmod 0755 "$preflight_path" "$run_path" "$orig_run_path"
}
enable_sshd_service() { enable_sshd_service() {
if [[ ! -d "$ROOT_MOUNT/etc/sv/sshd" ]]; then if [[ ! -d "$ROOT_MOUNT/etc/sv/sshd" ]]; then
log "Void rootfs is missing /etc/sv/sshd after openssh install" log "Void rootfs is missing /etc/sv/sshd after openssh install"
@ -146,6 +192,15 @@ enable_sshd_service() {
sudo ln -snf /etc/sv/sshd "$ROOT_MOUNT/etc/runit/runsvdir/default/sshd" sudo ln -snf /etc/sv/sshd "$ROOT_MOUNT/etc/runit/runsvdir/default/sshd"
} }
enable_docker_service() {
if [[ ! -d "$ROOT_MOUNT/etc/sv/docker" ]]; then
log "Void rootfs is missing /etc/sv/docker after docker install"
exit 1
fi
sudo mkdir -p "$ROOT_MOUNT/etc/runit/runsvdir/default"
sudo ln -snf /etc/sv/docker "$ROOT_MOUNT/etc/runit/runsvdir/default/docker"
}
normalize_root_shell() { normalize_root_shell() {
local passwd="$ROOT_MOUNT/etc/passwd" local passwd="$ROOT_MOUNT/etc/passwd"
local shells="$ROOT_MOUNT/etc/shells" local shells="$ROOT_MOUNT/etc/shells"
@ -415,18 +470,25 @@ log "preparing SSH and runit services"
ensure_sshd_include ensure_sshd_include
enable_sshd_service enable_sshd_service
install_vsock_service install_vsock_service
configure_docker_bootstrap
enable_docker_service
normalize_root_shell normalize_root_shell
configure_root_bash_prompt configure_root_bash_prompt
sudo mkdir -p "$ROOT_MOUNT/root/.ssh" sudo mkdir -p "$ROOT_MOUNT/root/.ssh"
sudo touch "$ROOT_MOUNT/etc/fstab" "$ROOT_MOUNT/etc/hostname" sudo touch "$ROOT_MOUNT/etc/fstab" "$ROOT_MOUNT/etc/hostname"
sudo chroot "$ROOT_MOUNT" /usr/bin/ssh-keygen -A sudo chroot "$ROOT_MOUNT" /usr/bin/ssh-keygen -A
log "removing bulky caches and docs from the experimental image" log "removing bulky caches, docs, and stale installer artifacts from the experimental image"
sudo rm -rf \ sudo rm -rf \
"$ROOT_MOUNT/var/cache/xbps" \ "$ROOT_MOUNT/var/cache/xbps" \
"$ROOT_MOUNT/usr/share/doc" \ "$ROOT_MOUNT/usr/share/doc" \
"$ROOT_MOUNT/usr/share/info" \ "$ROOT_MOUNT/usr/share/info" \
"$ROOT_MOUNT/usr/share/man" "$ROOT_MOUNT/usr/share/man"
sudo rm -f \
"$ROOT_MOUNT/root/get-docker" \
"$ROOT_MOUNT/root/get-docker.sh" \
"$ROOT_MOUNT/tmp/get-docker" \
"$ROOT_MOUNT/tmp/get-docker.sh"
sudo umount "$ROOT_MOUNT" sudo umount "$ROOT_MOUNT"

View file

@ -4,6 +4,8 @@ bash
openssh openssh
ca-certificates ca-certificates
curl curl
docker
docker-compose
fd fd
fzf fzf
git git