How To

Create Proxmox VM Templates from Cloud Images

Cloning a VM from a template takes under a minute. Installing from an ISO takes 20 minutes of clicking through an installer and then manually configuring cloud-init, SSH keys, and networking. If you deploy more than one or two VMs a month on Proxmox, templates pay for themselves immediately.

Original content from computingforgeeks.com - post 164534

This guide walks through building reusable Proxmox VM templates from official cloud images for Rocky Linux, Arch Linux, Ubuntu, and Debian. Cloud images are pre-built, minimal OS images designed for automated deployment with cloud-init. You download the qcow2 file, import it into Proxmox, configure cloud-init settings (user, SSH keys, networking), and convert to a template. Every clone gets a fresh machine ID, a unique SSH host key, and your SSH public key injected automatically.

Tested March 2026 on Proxmox VE 8.4 (QEMU 9.2.0) with Rocky Linux 10.1, Arch Linux (kernel 6.19.8), Ubuntu 24.04, and Debian 13

What You Need

  • A Proxmox VE 8 server with SSH access as root
  • At least 20 GB free space on your storage (local-lvm or ZFS)
  • An SSH public key to inject into templates (for passwordless access to cloned VMs)

Cloud Image Sources

Every major distribution publishes official cloud images in qcow2 format. These are minimal installs (no GUI, no unnecessary packages) with cloud-init pre-configured:

DistributionCloud Image URLFormat
Rocky Linux 10https://dl.rockylinux.org/pub/rocky/10/images/x86_64/qcow2
Arch Linuxhttps://geo.mirror.pkgbuild.com/images/latest/qcow2
Ubuntu 24.04https://cloud-images.ubuntu.com/noble/current/img (qcow2)
Debian 13https://cloud.debian.org/images/cloud/trixie/latest/qcow2
Fedora 42https://download.fedoraproject.org/pub/fedora/linux/releases/42/Cloud/x86_64/images/qcow2
AlmaLinux 10https://repo.almalinux.org/almalinux/10/cloud/x86_64/images/qcow2

Create an Arch Linux Template

This section builds a complete template from the Arch Linux cloud image. The same process applies to any distribution, just swap the download URL and adjust the cloud-init username.

Download the Cloud Image

SSH into your Proxmox node and download the image to /tmp:

wget -q https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2 -O /tmp/arch-cloud.qcow2

Verify the download completed (the Arch cloud image is roughly 500 MB):

ls -lh /tmp/arch-cloud.qcow2
-rw-r--r-- 1 root root 519M Mar 15 15:10 /tmp/arch-cloud.qcow2

Create the VM Shell

Create an empty VM with the hardware configuration you want as the default for clones. Pick a VMID that you will remember as a template (700-799 is a good range):

qm create 797 --name arch-linux-template \
  --memory 2048 --cores 2 \
  --net0 virtio,bridge=vmbr0 \
  --ostype l26 --agent 1 \
  --scsihw virtio-scsi-single

The --agent 1 flag enables the QEMU guest agent, which allows Proxmox to query the VM’s IP address and perform clean shutdowns. The --scsihw virtio-scsi-single controller gives better I/O performance than the default LSI controller.

Import the Cloud Image as a Disk

Import the qcow2 file as a virtual disk into your storage backend:

qm importdisk 797 /tmp/arch-cloud.qcow2 local-lvm

The import converts the qcow2 to a raw LVM thin volume. It takes a minute or two depending on disk speed:

transferred 2.0 GiB of 2.0 GiB (100.00%)
unused0: successfully imported disk 'local-lvm:vm-797-disk-0'

The disk is imported but not yet attached to the VM. Attach it as the boot disk:

qm set 797 --scsi0 local-lvm:vm-797-disk-0,discard=on

Set the boot order to use this disk:

qm set 797 --boot order=scsi0

Add a Cloud-Init Drive

Cloud-init reads its configuration from a special drive attached to the VM. Proxmox generates this drive automatically from the settings you configure:

qm set 797 --ide2 local-lvm:cloudinit

Configure Cloud-Init Settings

Set the default user, SSH keys, and networking. These settings apply to every VM cloned from this template:

qm set 797 --ciuser arch \
  --sshkeys ~/.ssh/authorized_keys \
  --ipconfig0 ip=dhcp \
  --nameserver 8.8.8.8

The --ciuser sets the default login username. Use rocky for Rocky Linux, ubuntu for Ubuntu, debian for Debian, or arch for Arch. The --sshkeys flag accepts a file containing public keys (one per line). Every clone will have these keys injected into the user’s ~/.ssh/authorized_keys.

For static IP assignment instead of DHCP:

qm set 797 --ipconfig0 ip=192.168.1.100/24,gw=192.168.1.1

Resize the Disk

Cloud images ship with small disks (2 GB for Arch, 10 GB for Rocky). Resize to a reasonable default. You can always expand clones later, but shrinking is not supported:

qm resize 797 scsi0 20G

Convert to Template

This is the final step. Converting to a template locks the VM so it cannot be started or modified accidentally. It can only be cloned:

qm template 797

Clean up the downloaded image:

rm -f /tmp/arch-cloud.qcow2

The template now appears in the Proxmox sidebar with a lock icon, indicating it cannot be started directly.

Create a Rocky Linux 10 Template

The process is identical. Download the Rocky 10 GenericCloud image and follow the same steps:

wget -q https://dl.rockylinux.org/pub/rocky/10/images/x86_64/Rocky-10-GenericCloud-Base.latest.x86_64.qcow2 -O /tmp/rocky-cloud.qcow2

qm create 799 --name rocky-10-template \
  --memory 2048 --cores 2 \
  --net0 virtio,bridge=vmbr0 \
  --ostype l26 --agent 1 \
  --scsihw virtio-scsi-single

qm importdisk 799 /tmp/rocky-cloud.qcow2 local-lvm
qm set 799 --scsi0 local-lvm:vm-799-disk-0,discard=on
qm set 799 --boot order=scsi0
qm set 799 --ide2 local-lvm:cloudinit
qm set 799 --ciuser rocky \
  --sshkeys ~/.ssh/authorized_keys \
  --ipconfig0 ip=dhcp \
  --nameserver 8.8.8.8
qm resize 799 scsi0 20G
qm template 799

rm -f /tmp/rocky-cloud.qcow2

For Ubuntu 24.04 and Debian 13, use the same workflow with their respective cloud image URLs from the table above. Set --ciuser ubuntu for Ubuntu and --ciuser debian for Debian.

Clone and Deploy a VM from a Template

Once a template exists, deploying a new VM takes one command. Clone with a full copy (each clone gets its own independent disk):

qm clone 797 950 --name arch-webserver --full true

Proxmox copies the template disk to the new VM:

create full clone of drive ide2 (local-lvm:vm-797-cloudinit)
create full clone of drive scsi0 (local-lvm:base-797-disk-0)
transferred 20.0 GiB of 20.0 GiB (100.00%)

Customize the clone if needed (more RAM, more CPUs, static IP):

qm set 950 --memory 4096 --cores 4
qm set 950 --ipconfig0 ip=192.168.1.50/24,gw=192.168.1.1

Start the VM:

qm start 950

Wait about 20 seconds for cloud-init to finish, then get the IP address via the guest agent:

qm agent 950 network-get-interfaces

SSH in using the cloud-init username and the key you injected into the template:

ssh [email protected]
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
6.19.8-arch1-1

The clone is running with your SSH key, the correct hostname, a unique machine ID, and fresh SSH host keys. No manual installation, no clicking through installers.

Full Clone vs Linked Clone

Proxmox supports two cloning modes:

ModeCommandDisk UsagePerformanceBest For
Full cloneqm clone 797 950 --full trueComplete copy of diskFull speed (independent)Production VMs, long-lived servers
Linked cloneqm clone 797 950Only changes stored (CoW)Slightly slower readsTesting, temporary VMs, labs

Linked clones are faster to create and use less disk space because they share the template’s base image. The tradeoff: if you delete the template, all linked clones break. Use full clones for anything that needs to persist independently.

Cloud-Init Reference

Key cloud-init options you can set on templates or individual clones:

OptionPurposeExample
--ciuserDefault login username--ciuser rocky
--cipasswordSet a password (prefer SSH keys)--cipassword 'secret'
--sshkeysFile with public SSH keys--sshkeys ~/.ssh/authorized_keys
--ipconfig0Network configuration--ipconfig0 ip=dhcp
--nameserverDNS server--nameserver 8.8.8.8
--searchdomainDNS search domain--searchdomain example.com
--ciupgradeRun package upgrade on first boot--ciupgrade 0 (disable)

You can override any cloud-init setting on individual clones without changing the template. For example, to give a clone a static IP after cloning:

qm set 950 --ipconfig0 ip=192.168.1.50/24,gw=192.168.1.1 --nameserver 192.168.1.1

Regenerate the cloud-init ISO after changes:

qm cloudinit update 950

Automating Template Creation

If you manage multiple Proxmox nodes or want to keep templates current, wrap the process in a script. Here is a reusable example that accepts the distro name as an argument:

#!/bin/bash
# create-template.sh - Build a Proxmox VM template from a cloud image
# Usage: ./create-template.sh rocky|arch|ubuntu|debian VMID

DISTRO=$1
VMID=$2
STORAGE="local-lvm"

case $DISTRO in
  rocky)
    URL="https://dl.rockylinux.org/pub/rocky/10/images/x86_64/Rocky-10-GenericCloud-Base.latest.x86_64.qcow2"
    USER="rocky"
    NAME="rocky-10-template"
    ;;
  arch)
    URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
    USER="arch"
    NAME="arch-linux-template"
    ;;
  ubuntu)
    URL="https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
    USER="ubuntu"
    NAME="ubuntu-2404-template"
    ;;
  debian)
    URL="https://cloud.debian.org/images/cloud/trixie/latest/debian-13-genericcloud-amd64.qcow2"
    USER="debian"
    NAME="debian-13-template"
    ;;
  *)
    echo "Usage: $0 rocky|arch|ubuntu|debian VMID"
    exit 1
    ;;
esac

echo "Creating $DISTRO template as VMID $VMID..."
wget -q "$URL" -O /tmp/cloud.qcow2
qm create $VMID --name $NAME --memory 2048 --cores 2 \
  --net0 virtio,bridge=vmbr0 --ostype l26 --agent 1 --scsihw virtio-scsi-single
qm importdisk $VMID /tmp/cloud.qcow2 $STORAGE
qm set $VMID --scsi0 $STORAGE:vm-${VMID}-disk-0,discard=on
qm set $VMID --boot order=scsi0
qm set $VMID --ide2 $STORAGE:cloudinit
qm set $VMID --ciuser $USER --sshkeys ~/.ssh/authorized_keys --ipconfig0 ip=dhcp --nameserver 8.8.8.8
qm resize $VMID scsi0 20G
qm template $VMID
rm -f /tmp/cloud.qcow2
echo "Template $NAME (VMID $VMID) created successfully"

Run it to create any template in one command:

chmod +x create-template.sh
./create-template.sh arch 797
./create-template.sh rocky 799
./create-template.sh ubuntu 800

For more on managing Proxmox VMs, including snapshots and deletion protection, check our Proxmox guides. The official Proxmox cloud-init documentation covers additional options like custom cloud-init snippets and multi-NIC configurations.

Related Articles

Virtualization How To Clone and Use KVM Virtual Machine in Linux Kali Linux How To Install VirtualBox 7.x on Kali Linux Cloud Install OpenStack Victoria on CentOS 8 With Packstack AWS Create Custom OS images for KVM, OpenStack, VMware and AWS using Image Builder

Leave a Comment

Press ESC to close