Skip to content

Create a template

# interactive image selection; the VM ID is chosen automatically
qm-template create

# filter images with a regular expression on the relative path
qm-template create debian-13

# non-interactive with an explicit ID
qm-template create --vm-id 9000 --vm-name debian-13-template

# use a migration-friendly CPU type
qm-template create --cpu x86-64-v2-AES

# override the firmware auto-detected from the image name
qm-template create --firmware uefi

# attach Proxmox metadata
qm-template create --tags template,cloud --pool templates --onboot

# inspect the assembled command without running it
qm-template create --dry-run --vm-id 9000

create requires a Proxmox VE host and runs a single qm create ... --template 1 command, which --dry-run/-n pretty prints without executing it:

qm create 9000 \
    --name debian-13-template \
    --cpu cputype=host \
    --cores 1 \
    --balloon 1024 \
    --memory 1024 \
    --net0 model=virtio,firewall=1,bridge=vmbr0 \
    --scsihw virtio-scsi-single \
    --agent type=virtio,enabled=1 \
    --machine q35 \
    --ostype l26 \
    --serial0 socket \
    --vga serial0 \
    --scsi0 local-lvm:0,import-from=/path/to/image.qcow2 \
    --scsi1 local-lvm:cloudinit \
    --boot order=scsi0 \
    --ipconfig0 ip=dhcp \
    --ciupgrade 0 \
    --ciuser debian \
    --cipassword '********' \
    --sshkeys /tmp/qm-template-sshkeys-XXXX.pub \
    --template 1

The login name is cloudinit.user, or the distro's usual user when it is empty (debian for the image above); --cipassword is omitted when no password is configured and --sshkeys when no keys are. Secrets are masked in the preview, so run the command as printed only after replacing the masks.

When --vm-id is omitted, the IDs in use are collected from qm list combined with /etc/pve/qemu-server/*.conf and the first free ID at or after vmid.start (default 9000), advancing by vmid.step, is used. If qm create fails after leaving a VM config behind, the qm destroy command needed to clean it up is reported. The resources and metadata of the template come from the configuration and can be overridden with --storage, --cores, --memory, --cpu, --bridge, --tags, --pool, --onboot, --description and --firmware.

Remote Proxmox VE hosts

With --pve NAME, create talks to the Proxmox VE API instead of running qm, so a single workstation can manage several hosts without installing qm-template or downloading images on them:

qm-template create debian-13 --pve home --vm-name debian-13-template

# print the API requests instead of executing them
qm-template create debian-13 --pve home --dry-run

API mode requires Proxmox VE 8.4 or newer. The image is uploaded to the host's import_storage with content=import and imported with scsi0=<create.storage>:0,import-from=<import_storage>:import/<file>; an uploaded file with the same name and size is reused, so repeat runs skip the transfer. The image name is flattened from the path below paths.images_dir and the format is detected from the file itself, so Ubuntu's .img images are accepted. VM IDs come from the cluster (GET /cluster/nextid), and vmid.start/vmid.step still apply. When creation fails, the incomplete VM is removed again. --dry-run prints the upload and POST /api2/json/nodes/<node>/qemu requests with passwords and SSH keys masked, like the local qm create command. The selected host can override the global [create], [vmid] and [cloudinit] settings; see Configuration.

Prepare the remote host once:

  • create a user and API token that may allocate VMs:
pveum user add qm-template@pve
pveum acl modify / --users qm-template@pve --roles PVEAdmin
pveum user token add qm-template@pve automation --privsep 0

Token permissions are limited to the user's own permissions; a narrower custom role works too, but creating a VM touches several privileges (VM.Allocate, VM.Config.*, Datastore.AllocateSpace and Datastore.AllocateTemplate for the upload). Privilege separation is on by default, so without --privsep 0 a new token has no permissions of its own and needs a separate ACL entry (pveum acl modify / --tokens 'qm-template@pve!automation' --roles PVEAdmin). - enable the import content type on a file-based storage (Datacenter -> Storage -> your storage -> Edit -> Content) and point import_storage at it. LVM/ZFS storages cannot hold import content; create.storage (for example local-lvm) remains the target for the VM disk and Cloud-Init drive. Import storage needs Proxmox VE 8.4+. - set verify_ssl = false (or trust the PVE CA) when the host still uses its self-signed certificate.

Hosts older than 8.4 keep working with the default local mode.