Packer template that builds a base Ubuntu 24.04 developer VM as a qcow2 image.
| Tool | Details |
|---|---|
| Docker Engine | CE, CLI, Buildx, Compose plugin |
| QEMU/KVM + libvirt | For running nested VMs |
| GitHub CLI | gh via official apt repo |
| Rust | Stable toolchain via rustup |
| Python tools | uv, ruff, ty via Astral installers |
| Claude Code | CLI via official installer |
| Build dependencies | build-essential, pkg-config, libssl-dev, libvirt-dev, etc. |
The default user is sherpa. It is pre-added to the docker, libvirt, and kvm groups. Cloud-init runs on first boot so SSH keys, passwords, and any further configuration are set by the user.
- QEMU/KVM (
qemu-system-x86_64,/dev/kvm) - Packer ≥ 1.10
ssh-keygen
Clone the repo with submodules:
git clone --recurse-submodules https://github.com/bwks/packer-devbox.git
cd packer-devboxInstall the QEMU plugin (one-time):
packer init devbox.pkr.hclGenerate a temporary build keypair and run Packer:
ssh-keygen -t ed25519 -f /tmp/packer_key -N "" -C "packer-build"
packer build \
-var "ssh_public_key=$(cat /tmp/packer_key.pub)" \
-var "ssh_private_key_file=/tmp/packer_key" \
devbox.pkr.hclThe Ubuntu 24.04 cloud image is downloaded and cached in packer_cache/ on first run.
Output: output/devbox.qcow2 (~20 GB sparse qcow2)
Boot with your own cloud-init user-data to configure the sherpa user:
#cloud-config
users:
- name: sherpa
ssh_authorized_keys:
- ssh-ed25519 AAAA...yourkey
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bashPass it as a seed ISO:
cloud-localds seed.iso user-data
qemu-system-x86_64 \
-enable-kvm -m 4096 -smp 4 \
-drive file=output/devbox.qcow2,if=virtio \
-drive file=seed.iso,if=virtio,format=raw,readonly=on \
-netdev user,id=net0,hostfwd=tcp::2222-:22 \
-device virtio-net-pci,netdev=net0Then SSH in:
ssh -p 2222 sherpa@localhostThe installer scripts are a git submodule. To pull the latest:
git submodule update --remote installer-scripts
git add installer-scripts
git commit -m "bump installer-scripts"