# banger golden image — Debian bookworm sandbox for development + testing. # # Two sections: # 1. ESSENTIAL — what banger's lifecycle requires to boot the guest. # 2. OPINION — developer conveniences curated for banger sandboxes. # # Banger's guest agents (vsock agent, network bootstrap, first-boot unit) # are injected at `banger image pull` time, not baked here. Keeping them # out means this image stays portable enough to run in other contexts. FROM debian:bookworm-slim ENV DEBIAN_FRONTEND=noninteractive \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 # -------- 1. ESSENTIAL -------- # Banger needs: an init (systemd), sshd (the only control channel), # TLS roots + curl (first-boot installs + mise installer), iproute2 # (debugging; `ip` is still useful even when the kernel sets IP via cmdline). RUN apt-get update \ && apt-get install -y --no-install-recommends \ systemd systemd-sysv \ openssh-server \ ca-certificates \ curl \ iproute2 \ && rm -rf /var/lib/apt/lists/* # -------- 2. OPINION -------- # Developer sandbox conveniences. Language runtimes are deliberately # absent — `mise` (below) handles per-repo `.mise.toml`/`.tool-versions` # on first `vm run`. # Core CLI + search/nav + build toolchain + lint/debug + editor/session. RUN apt-get update \ && apt-get install -y --no-install-recommends \ git jq less tree file unzip zip rsync \ ripgrep fd-find \ build-essential pkg-config make \ shellcheck sqlite3 \ iputils-ping dnsutils \ vim-tiny tmux htop \ && rm -rf /var/lib/apt/lists/* # Docker CE (with Compose v2 + buildx) from the official apt repo. # Nested-VM docker gives Compose workflows hostname/port isolation # per banger VM, which is a big part of the sandbox story. RUN install -m 0755 -d /etc/apt/keyrings \ && curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \ && chmod a+r /etc/apt/keyrings/docker.asc \ && printf 'deb [arch=%s signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian bookworm stable\n' \ "$(dpkg --print-architecture)" > /etc/apt/sources.list.d/docker.list \ && apt-get update \ && apt-get install -y --no-install-recommends \ docker-ce docker-ce-cli containerd.io \ docker-buildx-plugin docker-compose-plugin \ && rm -rf /var/lib/apt/lists/* # mise — per-repo version manager. Installed system-wide so the # bashrc activation reaches every shell. RUN curl -fsSL https://mise.run | MISE_INSTALL_PATH=/usr/local/bin/mise sh \ && chmod 0755 /usr/local/bin/mise \ && install -d /etc/profile.d \ && printf '%s\n' 'if [ -x /usr/local/bin/mise ]; then eval "$(/usr/local/bin/mise activate bash)"; fi' \ > /etc/profile.d/mise.sh \ && chmod 0644 /etc/profile.d/mise.sh # Git default branch — matches the old customize.sh opinion. RUN git config --system init.defaultBranch main # `fd-find` installs as `fdfind` on Debian to avoid a long-standing name # clash. Expose the ergonomic name for interactive use. RUN ln -s /usr/bin/fdfind /usr/local/bin/fd # Strip per-image identity so every banger VM gets its own. # - /etc/machine-id: systemd-firstboot regenerates at boot when empty. # - SSH host keys: removed here; a ssh.service drop-in (below) runs # `ssh-keygen -A` before sshd so the VM's first boot generates a # unique set. RUN : > /etc/machine-id \ && rm -f /etc/ssh/ssh_host_*_key /etc/ssh/ssh_host_*_key.pub \ && install -d /etc/systemd/system/ssh.service.d \ && printf '[Service]\nExecStartPre=-/usr/bin/ssh-keygen -A\n' \ > /etc/systemd/system/ssh.service.d/regen-host-keys.conf # No CMD / ENTRYPOINT: banger boots this via systemd as PID 1 after # first-boot, not via `docker run`.