From 5ad3b505dd6a6035d52ab2bed05068d13cbada35 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Thu, 19 Mar 2026 15:52:30 -0300 Subject: [PATCH] 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. --- AGENTS.md | 2 +- README.md | 7 ++++- make-rootfs-void.sh | 64 ++++++++++++++++++++++++++++++++++++++++++++- packages.void | 2 ++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c41e815..036e48c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,7 +36,7 @@ - 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. - 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. - 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`. diff --git a/README.md b/README.md index 4d99961..fa25fcb 100644 --- a/README.md +++ b/README.md @@ -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, but builds a lean `x86_64-glibc` Void userspace with: - `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 - 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 - a generated `/root` work-seed for fast creates It does not install the Debian-oriented extras from rebuilt default images: -- no Docker - no `mise` - no `opencode` - no tmux plugin defaults @@ -354,6 +355,10 @@ make void-register ./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: ```bash make verify-void diff --git a/make-rootfs-void.sh b/make-rootfs-void.sh index 0be5276..0056313 100755 --- a/make-rootfs-void.sh +++ b/make-rootfs-void.sh @@ -137,6 +137,52 @@ EOF 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() { if [[ ! -d "$ROOT_MOUNT/etc/sv/sshd" ]]; then 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" } +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() { local passwd="$ROOT_MOUNT/etc/passwd" local shells="$ROOT_MOUNT/etc/shells" @@ -415,18 +470,25 @@ log "preparing SSH and runit services" ensure_sshd_include enable_sshd_service install_vsock_service +configure_docker_bootstrap +enable_docker_service normalize_root_shell configure_root_bash_prompt sudo mkdir -p "$ROOT_MOUNT/root/.ssh" sudo touch "$ROOT_MOUNT/etc/fstab" "$ROOT_MOUNT/etc/hostname" 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 \ "$ROOT_MOUNT/var/cache/xbps" \ "$ROOT_MOUNT/usr/share/doc" \ "$ROOT_MOUNT/usr/share/info" \ "$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" diff --git a/packages.void b/packages.void index a64c5b8..2b3b99e 100644 --- a/packages.void +++ b/packages.void @@ -4,6 +4,8 @@ bash openssh ca-certificates curl +docker +docker-compose fd fzf git