Creating a Debain Template on Proxmox with a Cloud Image
Download and Import Cloud Image
All of these commands will have to be run directly from the proxmox shell.
Download the Image
The first step is to download the cloud image from debian.org. It is important to get the qcow2 image that matches your system architecture. Most machines that are running proxmox are likely using a 64 bit x86 processor. For this article, I’m going to keep the commands to that type of system. If you are using arm or riscv, you probably know more than I do.
wget https://cdimage.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2
Create a New VM with VirtIO SCSI Controller
This will create a new Virtual Machine. The 9000 in this example, is the VM ID. If you already have a VM or Template using that ID, you will have to change the number to one that is available. This will also create a virtual network device that connects to the network bridge vmbr0. This is the default on most systems, but if you have more than one NIC, you may have to change this too. The scsi settings are needed to import the cloud image in the next step.
qm create 9000 --memory 1024 --net0 virtio,bridge=vmbr0 --scsihw virtio-scsi-pci
Import the Image to the VM Storage
This imports the cloud image into the new virtual machine as a scsi drive. Make sure that the VM ID matches the previous step. You will also need to be sure that the path to image is correct. If you changed directories before running the command in the first step, then you will have to change the path to the image, to match it’s actual location in the file system.
qm set 9000 --scsi0 local-lvm:0,import-from=/root/debian-13-generic-amd64.qcow2
Changing the VM Settings
There are some hardware, VM options and cloud-init settings that I would recommend changing.
Changing Hardware Settings
On VM 9000 (or whatever ID you used) go to the hardware tab. All virtual hardware is added through the add dropdown menu.
For UEFI Templates
There are only three steps for using UEFI. They are:
- Add an EFI disk
- You will need to select a storage location. I only had one option (lvm-local), but any are fine
- Select BIOS and edit
- Select OVFM bios
- Select Machine and edit
- Select q35
For All Templates
Add a cloud-init drive to the VM. Any storage location will work.
Since the virtual disk has no free space, add a little room
- Select hard disk, Disk Action, Resize
- add at least 1G to virtual disk
Changing the Cloud-Init Settings
You don’t need to do this, but I would rather have some default settings before I start cloning my template. It can be nice to have a default admin user on each VM. Any of these can be changed after cloning the template. Select Cloud-Init and change the following settings
- User
- Password
- SSH public key (if you have one)
- IP Config
- Set ip address or select DHCP
Changing the Options
The only thing in here that truly needs to be done is changing the boot order. I prefer to change the name, since matching the template name to the cloud init vendor file helps keep things managable. I also always enable QEMU guest agent on all VM’s on proxmox. That will allow the host system to safely shut down VM’s if it nees to. Select VM options and change these settings
- Name
- Change to whatever you want your template to be named
- Boot Order
- Enable the SCSI device
- Change to boot from SCSI device
- QEMU-Guest-Agent
- Enable this
Set Local Storage to Allow Snippets
Under data center - storage - select local - edit - add snippets in the content drop down
Create Vendor File
From the proxmox shell, in /var/lib/vz/snippets create the vendor file vendor.yaml. The vendor file name is just generic here for this example but it is wise to match the name of the template. If you ever need to edit or remove the file, then matching the vendor file name to the template name will make it easier to identify where the change needs to be made.
vim /var/lib/vz/snippets/vendor.yaml
Here are a couple of examples that I use. They will install qemu-guest-agent, vim-nox, ufw and htop on the VM after the first boot. Then it will create a firewall rule to allow ssh connections, start the firewall and reboot.
#cloud-config
packages:
- qemu-guest-agent
- vim-nox
- ufw
- htop
runcmd:
- ufw allow ssh
- ufw enable
- reboot
The next one is the same except that it will install the latest docker-ce and add the user created by cloud-init to the docker group before rebooting.
#cloud-config
packages:
- qemu-guest-agent
- vim-nox
- ufw
- htop
runcmd:
- ufw allow ssh
- ufw enable
- curl -sSL https://get.docker.com/ | sh
- sudo usermod -aG docker $(id -u -n 1000)
- reboot
Apply Vendor File to VM
Then you simply identify the vendor file to be applied to the template. Of course, make sure the VM ID matches the template and the vendor file name is correct.
qm set 9000 --cicustom "vendor=local:snippets/vendor.yaml"
Create a Template from the VM
The last step is to select the VM from the left hand menu of proxmox. Right click on the VM and select convert to template. Select “Yes” on the next pop up screen and you have the most functional, lightweight, template that debian can offer. It’s not the fastest deploying template, but it is certainly the best one that I have come across. Happy labbing!