Proxmox VM Templates: Clone and Deploy VMs in Seconds

Learn how to create reusable Proxmox VM templates and clone them in seconds. Stop rebuilding VMs from scratch and deploy consistent machines instantly.

Proxmox Pulse Proxmox Pulse
9 min read
Glowing server template surrounded by identical cloned server nodes connected by luminous lines

If you've ever spun up a Proxmox VM, installed your base OS, configured SSH, set up your preferred packages, and then needed to do it all over again for the next VM — you already understand why templates exist. VM templates let you capture that perfectly configured base system and clone it instantly, as many times as you need, with zero redundant work.

This guide walks you through the entire process: creating a base VM, converting it to a template, and deploying clones using both the UI and command line. By the end, you'll have a workflow that turns a ten-minute VM setup into a ten-second one.

Why Templates Beat Manual Installs

The obvious benefit is speed, but templates also give you consistency. Every clone comes from the same known-good base, which means fewer "works on my VM" problems when you're comparing two machines.

Templates also pair extremely well with Cloud-Init for automated configuration at first boot — but even without Cloud-Init, a plain template saves significant time. If you're running a homelab or managing a small production cluster, this is one of the highest-leverage things you can set up.

Choosing Your Base Image

Before you build a template, decide what goes in it. There are two common approaches:

Minimal base template — Just the OS, SSH server, and basic utilities. All application config happens after cloning. This is the most flexible approach.

Role-specific template — A base plus a common stack (e.g., Docker + Compose). Faster for spinning up identical worker nodes.

For most use cases, start with a minimal base. You can always build role-specific templates on top of it later.

For a Debian/Ubuntu base template, install these before converting:

apt update && apt upgrade -y
apt install -y \
  curl \
  wget \
  git \
  vim \
  htop \
  sudo \
  qemu-guest-agent \
  cloud-init

The qemu-guest-agent is important — it lets Proxmox communicate with the VM for proper shutdown, IP reporting, and snapshot quiescing. cloud-init is optional but highly recommended for automated configuration.

Creating the Base VM

Start by creating a normal VM in Proxmox. A few settings matter here:

Machine type: Use q35 for modern hardware support (PCIe, better UEFI compatibility). Use i440fx only if you need older compatibility.

Disk format: Use qcow2 if you want snapshot support on directory storage, or leave it as the storage default. For ZFS or LVM-thin pools, the format is managed by the pool.

CPU: Set a reasonable default. 2 cores is a good starting point for a general-purpose template.

Memory: 2048 MB works for most base templates. Clones can have this adjusted after the fact.

Install and Configure the OS

Boot the VM from your ISO and run through the OS installation normally. Once installed:

  1. Remove the installation ISO from the VM's CD/DVD drive
  2. Install qemu-guest-agent and cloud-init as shown above
  3. Enable and start the guest agent:
systemctl enable qemu-guest-agent
systemctl start qemu-guest-agent
  1. If using Cloud-Init, configure the datasource:
# Create cloud-init config
cat > /etc/cloud/cloud.cfg.d/99-proxmox.cfg << 'EOF'
datasource_list: [ConfigDrive, NoCloud]
EOF
  1. Clean up machine-specific data before converting to template:
# Remove SSH host keys (regenerated on first boot)
rm -f /etc/ssh/ssh_host_*

Clear machine ID (systemd will regenerate)

truncate -s 0 /etc/machine-id rm -f /var/lib/dbus/machine-id

Clear bash history

history -c cat /dev/null > ~/.bash_history

Remove apt cache

apt clean

This cleanup is critical. If you skip removing SSH host keys, every clone will have identical keys — a serious security problem. The machine ID removal prevents systemd network interface naming conflicts.

  1. Shut down the VM (don't just stop it from the Proxmox UI — shut it down from inside so the filesystem syncs cleanly):
shutdown -h now

Converting the VM to a Template

Once the VM is shut down, converting it is a single click in the UI or one command.

Via the Web UI

Right-click the VM in the left panel → Convert to Template. Proxmox will ask you to confirm. After conversion, the VM icon changes to a template icon and you can no longer start it directly.

Via the Command Line

# Replace 100 with your VM ID
qm template 100

That's it. The VM is now a template. It's worth noting that templates are just regular VMs with the template flag set — all the same configuration files exist, you just can't start them directly.

Cloning VMs from a Template

Now the fun part. Cloning gives you a new, independent VM based on your template in seconds.

Full Clone vs Linked Clone

Proxmox offers two clone types:

Full clone — Creates a completely independent copy of the disk. Takes more storage but the clone has no dependency on the template. This is what you want for long-lived VMs.

Linked clone — The clone's disk is a diff on top of the template disk. Uses much less storage initially, but the clone depends on the template. Good for ephemeral VMs (CI/CD agents, short-lived test environments).

For most homelab use, full clones are the right choice. The storage cost is predictable and you can safely modify or delete the template later.

Cloning via the Web UI

  1. Right-click your template → Clone
  2. Set the new VM ID and name
  3. Choose Full Clone or Linked Clone
  4. Select the target storage and node
  5. Click Clone

The clone inherits all hardware configuration from the template. If you set up Cloud-Init on the template, you'll see a Cloud-Init tab on the new VM where you can set the hostname, username, SSH keys, and IP address before first boot.

Cloning via the Command Line

# Full clone: template 100 → new VM 201
qm clone 100 201 --name web-server-01 --full

Linked clone: template 100 → new VM 202

qm clone 100 202 --name test-env-01

Clone to specific storage

qm clone 100 203 --name db-server-01 --full --storage local-zfs

Clone to a different node in a cluster

qm clone 100 204 --name worker-01 --full --target pve-node2

Configuring the Clone Before First Boot

After cloning, adjust the VM settings as needed:

# Resize the disk (increase by 20GB)
qm resize 201 scsi0 +20G

Adjust CPU and memory

qm set 201 --cores 4 --memory 4096

Set Cloud-Init values

qm set 201
--ciuser admin
--sshkeys ~/.ssh/id_ed25519.pub
--ipconfig0 ip=192.168.10.50/24,gw=192.168.10.1

Regenerate Cloud-Init image

qm cloudinit update 201

Then start the VM:

qm start 201

With Cloud-Init configured, the VM will come up with the hostname, user, SSH key, and IP address you specified — no console interaction required.

Batch Deployment with a Shell Script

Once you have the pattern down, you can deploy multiple VMs with a simple script:

#!/bin/bash
# deploy-cluster.sh — Clone N VMs from a template

TEMPLATE_ID=100 START_ID=210 COUNT=5 BASE_NAME="worker" STORAGE="local-zfs" BASE_IP="192.168.10." BASE_OCTET=60 GATEWAY="192.168.10.1" SSH_KEY=$(cat ~/.ssh/id_ed25519.pub)

for i in $(seq 1 $COUNT); do VM_ID=$((START_ID + i - 1)) VM_NAME="${BASE_NAME}-$(printf '%02d' $i)" VM_IP="${BASE_IP}$((BASE_OCTET + i - 1))"

echo "Deploying ${VM_NAME} (ID: ${VM_ID}, IP: ${VM_IP})"

qm clone $TEMPLATE_ID $VM_ID
--name "$VM_NAME"
--full
--storage "$STORAGE"

qm set $VM_ID
--ciuser admin
--sshkeys <(echo "$SSH_KEY")
--ipconfig0 "ip=${VM_IP}/24,gw=${GATEWAY}"

qm cloudinit update $VM_ID qm start $VM_ID

echo "Started ${VM_NAME}" done

echo "Done. Deployed $COUNT VMs."

This deploys five VMs, each with a unique IP and hostname, in about 30 seconds. On fast storage like NVMe with ZFS, disk clone operations are nearly instant thanks to copy-on-write.

Managing Templates Over Time

Updating a Template

You can't start a template directly. To update it, you have two options:

Option 1: Clone → update → re-template

  1. Clone the template to a new VM
  2. Start the new VM and apply updates
  3. Shut it down, clean up (remove SSH keys, truncate machine-id)
  4. Convert to template with a new ID (or delete the old one first)

Option 2: Convert template back to VM temporarily bash

Remove the template flag

qm set 100 --template 0

Now you can start it, update it, shut it down

Then convert back

qm template 100

Option 2 is quicker but be careful — if you have linked clones depending on this template, don't modify its disk.

Naming and Documentation

As your template library grows, consistent naming saves headaches. A useful convention:

[distro]-[version]-[variant]-[date]

Examples: debian-12-base-20260301 ubuntu-2404-docker-20260301 almalinux-9-minimal-20260301

Add a description in the Proxmox UI (VM → Notes) documenting what's installed and any quirks.

Storing Templates on Shared Storage

In a cluster, store templates on shared storage (Ceph, NFS, or a shared ZFS pool) so they're accessible from any node. Templates on local storage can only be cloned to VMs on the same node.

# Move template disk to shared storage
qm move-disk 100 scsi0 ceph-pool --delete

Troubleshooting Common Issues

Clone fails with "already exists" error — The target VM ID is taken. Use qm list to see what IDs are in use.

Cloud-Init doesn't run on first boot — Check that a Cloud-Init drive is attached (qm set 100 --ide2 local:cloudinit). Also verify the cloud-init package is installed in the template.

All clones get the same IP — You forgot to set --ipconfig0 per-clone, or you're not using Cloud-Init and the OS is reading a static config from the template. Always set IPs post-clone.

SSH host key conflicts — You didn't remove /etc/ssh/ssh_host_* before templating. Clones with the same host keys will confuse your SSH client. Fix by deleting and regenerating keys on each affected clone:

rm /etc/ssh/ssh_host_*
ssh-keygen -A

Machine ID duplicates causing network issuessystemd-networkd and dhclient use machine ID to generate DHCP client IDs. If two clones have the same machine ID, they'll fight over the same DHCP lease. Fix:

rm /etc/machine-id /var/lib/dbus/machine-id
systemd-machine-id-setup

Conclusion

VM templates are one of those foundational Proxmox skills that immediately makes everything else faster and more consistent. The initial setup takes maybe 20 minutes — one clean OS install, the right packages, a cleanup script — and from there, deploying new VMs becomes nearly instant.

Pair this with Cloud-Init and you have fully automated, configuration-ready VMs at scale. Pair it with Terraform or Ansible and you have a proper infrastructure-as-code pipeline running on your homelab hardware.

Start with one solid Debian or Ubuntu base template, build the muscle memory for cloning and configuring clones, and you'll find yourself spinning up VMs for throwaway experiments far more readily than when every new VM meant 20 minutes of installer clicks.

Share
Proxmox Pulse

Written by

Proxmox Pulse

Sysadmin-driven guides for getting the most out of Proxmox VE in production and homelab environments.

Related Articles

View all →