TL;DR#
Cloud qcow2 → qm create → qm import-from → qm template → qm clone. Alma, Rocky, Ubuntu, etc.
You do not need an installer ISO if you just want Linux that boots with a user, an SSH key, and DHCP. Distros ship a GenericCloud / cloudimg (qcow2): import it, attach a cloud-init drive, turn it into a template.
Tested on Proxmox 8.0.4. The flow is this gist (fork of zidenis). Fedora 38 / Ubuntu 23.04 URLs go stale: point wget at the distro’s current cloud image.
1. Download the image#
On the node, as root, on a storage with space (NFS, local, whatever you use):
1
2
3
4
5
6
| export IMAGES_PATH="/mnt/pve/nfs-data/images/"
cd "${IMAGES_PATH}"
wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2
wget https://repo.almalinux.org/almalinux/9/cloud/x86_64/images/CHECKSUM -O SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
|
Other distros (uncomment one):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # Amazon Linux 2 — https://cdn.amazonlinux.com/os-images/latest/
# wget https://cdn.amazonlinux.com/os-images/2.0.20230727.0/kvm/amzn2-kvm-2.0.20230727.0-x86_64.xfs.gpt.qcow2
# CentOS Stream 9
# wget https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2
# Fedora (bump the version)
# wget https://download.fedoraproject.org/pub/fedora/linux/releases/38/Cloud/x86_64/images/Fedora-Cloud-Base-38-1.6.x86_64.qcow2
# Oracle Linux 9 — the .qcow is not qcow2; convert it
# wget https://yum.oracle.com/templates/OracleLinux/OL9/u2/x86_64/OL9U2_x86_64-kvm-b197.qcow
# qemu-img convert -O qcow2 -o compat=0.10 OL9U2_x86_64-kvm-b197.qcow OL9U2_x86_64-kvm-b197.qcow2
# RHEL 9 — needs a logged-in download from access.redhat.com
# Rocky 9
# wget https://dl.rockylinux.org/pub/rocky/9/images/x86_64/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2
# Ubuntu cloudimg
# wget https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img
|
2. VM and cloud-init variables#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| export QEMU_CPU_MODEL="host"
export VM_CPU_SOCKETS=1
export VM_CPU_CORES=2
export VM_MEMORY=4098
export VM_RESOURCE_POOL="CustomResourcePool"
export CLOUD_INIT_USER="user"
export CLOUD_INIT_SSHKEY="/home/user/.ssh/id_rsa.pub"
export CLOUD_INIT_IP="dhcp"
export CLOUD_INIT_NAMESERVER="1.1.1.1"
export CLOUD_INIT_SEARCHDOMAIN="example.com"
export TEMPLATE_ID=1001
export VM_NAME="alma9"
export VM_DISK_IMAGE="${IMAGES_PATH}/AlmaLinux-9-GenericCloud-latest.x86_64.qcow2"
|
--cpu host passes through the node CPU flags (faster; the template is not portable across CPU vendors). VM_MEMORY=4098 is the gist value; 4096 is fine.
The cloud-init user is not root. The key must be the .pub you will use from your laptop.
3. Create the base VM and import the disk#
Swap local-lvm and vmbr0 for your real storage and bridge.
1
2
3
4
5
6
7
8
9
10
11
| qm create ${TEMPLATE_ID} --name ${VM_NAME} --cpu ${QEMU_CPU_MODEL} \
--sockets ${VM_CPU_SOCKETS} --cores ${VM_CPU_CORES} --memory ${VM_MEMORY} \
--numa 1 --net0 virtio,bridge=vmbr0 --ostype l26 --agent 1 \
--pool ${VM_RESOURCE_POOL} --scsihw virtio-scsi-single
qm set ${TEMPLATE_ID} --scsi0 local-lvm:0,import-from=${VM_DISK_IMAGE}
qm set ${TEMPLATE_ID} --ide2 local-lvm:cloudinit --boot order=scsi0
qm set ${TEMPLATE_ID} --ipconfig0 ip=${CLOUD_INIT_IP} \
--nameserver ${CLOUD_INIT_NAMESERVER} --searchdomain ${CLOUD_INIT_SEARCHDOMAIN}
qm set ${TEMPLATE_ID} --ciupgrade 1 --ciuser ${CLOUD_INIT_USER} --sshkeys ${CLOUD_INIT_SSHKEY}
qm cloudinit update ${TEMPLATE_ID}
|
--agent 1 asks for qemu-guest-agent. Alma/Rocky/Fedora ship it or cloud-init installs it (ciupgrade). Amazon Linux 2 and some Ubuntu cloudimgs will not show the guest IP in the Proxmox GUI until you install the agent yourself.
4. Convert to a template#
1
2
| qm set ${TEMPLATE_ID} --name "${VM_NAME}-Template"
qm template ${TEMPLATE_ID}
|
Do not start that VM again: clone it.
5. Clone and boot#
1
2
3
| export VM_ID=$(pvesh get /cluster/nextid)
qm clone ${TEMPLATE_ID} ${VM_ID} --name ${VM_NAME}
qm start ${VM_ID}
|
SSH with the private key that matches the .pub you fed cloud-init:
1
| ssh user@192.168.0.123 -i ~/.ssh/id_rsa
|
If Proxmox does not show an IP: serial console, ip neigh on the bridge, or the router’s DHCP leases.
Source: gist inetshell/f1d0206d5319c11062845901e4f3d06b.