DEV Community

Charles Hartmann
Charles Hartmann

Posted on

Build a Proxmox cloud-init template from the official Debian 13 image (and clone VMs that configure themselves)

Every VM in a rebuildable lab starts from the same place: a template made from a distribution's official cloud image. Cloud images are small, minimal installs built to be configured on first boot by cloud-init, which reads its settings from a little drive that Proxmox attaches to the VM. That is how a fresh clone wakes up with the right hostname, your user, your SSH key and its address, without anyone touching a console.

Pick the image

Debian publishes cloud images at cloud.debian.org. At the time of writing (October 2026) the latest folder for trixie (Debian 13) holds, among others:

  • debian-13-genericcloud-amd64.qcow2: for cloud and virtual machines, with a smaller set of hardware drivers. This is the one for Proxmox VMs.
  • debian-13-generic-amd64.qcow2: the same system with a wider set of drivers, for odd hardware.

Ubuntu publishes its own cloud images at cloud-images.ubuntu.com, and the Proxmox documentation uses one in its example. The commands below are the same for either.

Build the template by hand, once

Run these on the Proxmox host. The steps follow the Proxmox VE Cloud-Init Support documentation; VM ID 9000 and the storage names are examples.

cd /var/lib/vz/template/iso
wget https://cloud.debian.org/images/cloud/trixie/latest/\
debian-13-genericcloud-amd64.qcow2

qm create 9000 --name debian13-tmpl --memory 2048 \
  --cores 2 --net0 virtio,bridge=vmbr0 \
  --scsihw virtio-scsi-pci --ostype l26 --agent enabled=1
qm set 9000 --scsi0 local-lvm:0,import-from=\
/var/lib/vz/template/iso/debian-13-genericcloud-amd64.qcow2
qm set 9000 --ide2 local-lvm:cloudinit
qm set 9000 --boot order=scsi0
qm set 9000 --serial0 socket --vga serial0
Enter fullscreen mode Exit fullscreen mode

What each step does:

  • qm create makes an empty VM with a VirtIO network card on bridge vmbr0 and the VirtIO SCSI controller that cloud images expect.
  • import-from copies the downloaded image into a new disk on local-lvm and attaches it as scsi0.
  • --ide2 ...:cloudinit adds the small cloud-init drive. Proxmox writes the user, network and SSH settings onto it.
  • --boot order=scsi0 boots straight from the disk, skipping the CD-ROM check.
  • The serial console is what many cloud images expect as their display. The Proxmox docs note that if a particular image does not work with it, you switch back to the default display.

Set the cloud-init defaults

Settings made on the template are inherited by every clone, so put the parts that are the same everywhere here:

qm set 9000 --ciuser admin
qm set 9000 --sshkeys /root/admin_ed25519.pub
qm set 9000 --ipconfig0 ip=dhcp
qm set 9000 --searchdomain home.example.com \
  --nameserver 192.168.20.1
Enter fullscreen mode Exit fullscreen mode

--sshkeys takes a file with one public key per line. Use keys, not --cipassword; the Proxmox documentation itself says passwords are generally not recommended here.

Add your own first-boot steps

The most common extra is the QEMU guest agent: the Debian cloud image does not include it, and without it Proxmox (and any tooling that asks Proxmox) cannot read the VM's address or shut it down cleanly.

The --cicustom option lets you supply your own files in place of the generated ones. It accepts user, network, meta and vendor files. Replacing user throws away the user and SSH key settings above, so add a vendor file instead: cloud-init merges it with the generated user data.

Custom files must live on a storage that allows the snippets content type. On the default local storage that is /var/lib/vz/snippets/. Enable the content type under Datacenter > Storage > local > Content, then create the file:

#cloud-config
# /var/lib/vz/snippets/debian-vendor.yaml
package_update: true
packages:
  - qemu-guest-agent
runcmd:
  - systemctl enable --now qemu-guest-agent
Enter fullscreen mode Exit fullscreen mode

Attach it to the template and look at what a clone will receive:

qm set 9000 --cicustom "vendor=local:snippets/debian-vendor.yaml"
qm cloudinit dump 9000 user
Enter fullscreen mode Exit fullscreen mode

Watch out: the Proxmox docs point out that custom cloud-init files must be available on every node a VM may migrate to, or the VM will not start there. In a cluster, use shared storage for snippets or copy the file to every node.

Turn it into a template

qm template 9000
Enter fullscreen mode Exit fullscreen mode

A template cannot be started; it can only be cloned. That is the point: nobody logs into it, so it never drifts.

Clone and personalize

qm clone 9000 120 --name docker01
qm set 120 --ipconfig0 ip=192.168.20.120/24,gw=192.168.20.1
qm disk resize 120 scsi0 20G
qm start 120
Enter fullscreen mode Exit fullscreen mode

After a minute, ssh admin@192.168.20.120 should work with your key. The cloud image's disk is small, which is why the clone's disk is grown with qm disk resize; cloud-init grows the root filesystem to fill it on boot.

Linked or full clones

When you clone a template, Proxmox tries to make a linked clone by default: the new disk only stores the differences from the template's disk. It is fast and small. The catch is that the clone depends on the template; you cannot delete the template while linked clones exist, and not every storage type supports them. Pass --full to get an independent copy.

For a rebuildable lab, full clones are usually the better default. The template will be rebuilt whenever a new Debian point release arrives, and full clones do not care.

Checklist

  • Debian 13 genericcloud image imported, cloud-init drive added, serial console set.
  • User, SSH key, DNS and search domain set on the template, not on each clone.
  • A vendor snippet installs qemu-guest-agent; qm cloudinit dump shows it merged in.
  • qm template run; clones made with --full.
  • The snippet is kept in your repository; the copy on the Proxmox host is just a deployment of it.

This is adapted from my book Automate Your Homelab (Homelab the Right Way, Book 9). The free sample is here and the full book is here.

Want the week's homelab articles, videos and one tip from the books in your inbox every Sunday? Get the free weekly email.

Drafted with AI help and edited by the author; based on his book.

Top comments (0)