Hand-built VM templates drift and nobody remembers exactly how they were made. Packer builds VM images from a template file: it boots a temporary VM, installs and configures software, then saves the result as an image. This guide covers the basics.
Before you start
- Packer installed from the official HashiCorp downloads (check its current licence terms).
- A target platform: local QEMU/KVM, Proxmox VE, or a cloud provider with a Packer plugin.
- Background: golden image best practices.
How Packer works
- Source/builder: creates a temporary VM from an ISO or base image.
- Provisioners: run shell scripts, Ansible or file uploads inside it.
- Post-processors: compress, upload or register the final image.
A QEMU example from a cloud image
ubuntu.pkr.hcl:
packer {
required_plugins {
qemu = {
source = "github.com/hashicorp/qemu"
version = "~> 1"
}
}
}
source "qemu" "ubuntu" {
iso_url = "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
iso_checksum = "file:https://cloud-images.ubuntu.com/noble/current/SHA256SUMS"
disk_image = true
disk_size = "10G"
format = "qcow2"
accelerator = "kvm"
headless = true
ssh_username = "packer"
ssh_private_key_file = "~/.ssh/packer"
cd_files = ["./cloud-init/*"]
cd_label = "cidata"
shutdown_command = "sudo shutdown -P now"
output_directory = "output-ubuntu"
}
build {
sources = ["source.qemu.ubuntu"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get -y upgrade",
"sudo apt-get -y install qemu-guest-agent",
"sudo cloud-init clean --logs"
]
}
}The cloud-init folder contains user-data and meta-data that create the packer user with your public key; see cloud-init user-data.
Build
packer init .packer validate .packer build .The resulting qcow2 can be used as a template on KVM or imported into Proxmox.
Other builders
- Proxmox: community/official plugins build templates directly in Proxmox VE through its API.
- Clouds: build provider images (snapshots) for many public clouds.
- Ansible provisioner: reuse your server playbooks; see Ansible.
Run it in CI
- Rebuild images on a schedule (e.g. monthly) to include security updates.
- Version images with a date tag and keep the previous one for rollback.
- Test new images automatically by booting them and running checks.
Troubleshooting
- Waiting for SSH forever: cloud-init seed not attached or wrong key; check the console with
headless = false. - KVM not available: CI runner lacks
/dev/kvm; use a runner with virtualization or nested virtualization. - Clones share machine IDs: clean
/etc/machine-idand SSH host keys at the end of the build.
Frequently asked questions
Packer or Docker?
Docker builds container images; Packer builds VM and cloud machine images.
Packer or manual templates?
Packer makes images reproducible and reviewable as code.
Can Packer build Windows images?
Yes, using WinRM and an unattended install; see Windows Sysprep templates.
