When you’re setting up multiple virtual machines in Proxmox, it can get annoying to install and configure the same operating system over and over again. That’s where VM templates come in. A template is basically a master copy of a virtual machine that you can clone to create new VMs quickly and easily.
By creating a Debian template, you can do all the setup work once (installing updates, adding useful tools, and adjusting settings) and then reuse that same setup any time you need a new VM. Each new clone starts from the exact same clean state which helps keep everything consistent while saving time.
So, let’s get stated and learn how to build a Debian VM template for Proxmox that’s ready to use right away. Every time you clone it, the new VM will automatically generate its own SSH keys, unique MAC address, and custom hostname. This means each system will act like a fresh installation without network conflicts.
Before creating your Debian VM template, it’s worth thinking through a few key details — especially when it comes to storage.
The size of the virtual hard drive you choose for your template matters. Whatever size you set here will be the size of every VM cloned from it. For example, if you create a 20 GB virtual disk for the template, each cloned VM will also reserve 20 GB of space on your Proxmox storage. Make it large enough for your operating system, updates, and typical software installs, but not so large that it wastes storage across multiple clones. As an aside, there is something called a “linked clone” which uses much less storage space but I am going to highly recommend a “full clone” if you intend on creating a VM and keep it running for a long time.
You can always expand a virtual disk later if needed, but choosing a practical starting size for your template helps keep your Proxmox node more storage efficent. As a quick example, I have a 256GB SSD in a node. In Local-LVM I am left with about 170 GB of usable VM storage. If I want to run 3 40GB VMs and keep the template on hand that comes to 160GB and we are out of space. Just keep in mind the storage that you have and the space needed for what you are attempting to accomplish. Remember, as well, network shares exist and you will probably be using them for very large data sets; say Immich or Nextcloud.
Finally, Your template’s CPU and memory settings will also be copied when you create new VMs. It’s usually best to assign modest defaults — for example, 1–2 CPU cores and 1–2 GB of RAM — so your clones start lightweight. You can always increase these resources per VM later, depending on the role each one will play.
Now, lets get started!
Getting the Debian ISO onto the Proxmox node
Head over the Debian download page and grab the latest “netinst” ISO. The “netinst” (network installation) version is lightweight and perfect for template creation because it installs only what you need.
Put the ISO on the Proxmox node.
- From the GUI, in the left frame, open your node (It’s probably just under the Datacenter link if you have a vanilla installation).
- Further down the same list, with the node expanded, there will an option called “local(NODENAME)”
- Select this option, from there click ‘ISO Images” on the newly changed main window.
- Click the upload button, select the ISO you just downloaded and then click the upload button
- **GOTME** I had an issue where the upload would just hang. This appears to be an issue with the headers and my reverse proxy but I have not looked too deep into it. If this happens to you, I was able to fix this by accessing the Proxmox GUI by IP address instead of the CNAME I had for it on the local network and uploading again. That is to say…. 192.168.1.100:8006 instead of the easier to remember proxmox.my.domain.com.
Creating the VM in Proxmox
If you’re at the point in your Proxmox journey that you are making templates I will assume you are comfortable creating a new VM. Instead I just going to now a few things.
- General tab – make sure Start at boot remains off. I generally make templates in a high VM ID range (say, ID 900) to make sure I don’t have any ID number issues later but you can use any unused VM ID you want.
- System tab – you want to make sure the Qemu Agent is checked. It is not by default so don’t miss it. This enables support for the QEMU Guest Agent, a small program that runs inside your virtual machine and allows Proxmox to communicate directly with the guest operating system.
- Disk and CPU tabs – As discussed earlier, these settings will be cloned to all VMs created from the template so think through what you are going to need.
Install Debian to the VM
Now go ahead and boot the newly minted VM and go through the installation process. Again, I am sure you have installed many OSes in your day so I will save the step by step. I generally do the regular text “install” (not the graphical installer). Below are just a few thoughts to keep in mind.
- When you get to hostname you can put anything you want. It will be cleared and changed when you clone the device. As a note, the hostname (in Proxmox9) will be taken from the ‘Name’ you set when you create the clone. More on this later
- The same goes with the hostname, though the setting is made elsewhere during the cloning process.
- Unless you understand what’s happening during partitioning, and that is beyond the scope of this tutorial, just use the “Guided – use entire disk” and “All files in one partition” when it comes to partitioning the hard drive.
- When asked “Software selection” which begins with “Debian desktop enviornment”…..Deselect everything except “SSH server” and “standard system utilities”. There is no need for a desktop GUI in an headless server. It will only waste resources. In the text installer, the space bar is used to select/deselect items and enter will continue with the install.
- Go ahead and install the GRUB bootloader on the primary drive and select the only drive in the list (probably /dev/sda.
- Note down the root password and username and password you set. These will remain for all future clones.
Hold my beer, we’re going in
Go ahead and boot up the VM and open the console….
Enable root ssh (makes copying commands easier)
The Proxmox GUI console does not allow copying and pasting (without more changes). As such, the easiest way is to enable root SSH by manually editing the sshd_config using the console. Alternative you can skip this all together (justing to Update OS and applications) and just manually type all the commands in the Proxmox console.
From the shell open the sshd_config file:
nano /etc/ssh/sshd_config
add the following to the top of the file:
PermitRootLogin yes
PasswordAuthentication yes
After editing the config, save and exit, reboot the system and now you can log in using a better SSH application that allows for copy and paste. When you have completed this tutorial it is absolutely best practice to come back into the config and remove the two lines to shut off root SSH. Now that we are logged in as root in a proper SSH application…
Update OS and applications
apt update && apt upgrade -y && apt dist-upgrade -y
Install helpful tools
- Some of these may already be installed. These are just a few extras. for example tmux and htop are not required, I just install them on every system I use. If you have an application, say Vim, that you always use you can add them here to make sure that they are readily available in the clone.
apt install -y sudo curl wget net-tools gnupg lsb-release cloud-init qemu-guest-agent qemu-utils tmux htop
Add a new user (Maybe optional)
- Depending on how you installed the OS you probably set up a local user outside of the root account. If you did then you can skip adding the user, unless you want another different user, and instead jump right to adding that user to the sudo group in the next step. In this example I will create a user called ‘docker’.
adduser docker
Add the user to the sudo group
usermod -aG sudo docker
Add a cloud-init CFG file
- Here we will be adding a few options for the “first boot” initialization of the template. Start by opening the specifically named file in the Nano text editor.
nano /etc/cloud/cloud.cfg.d/99-regenerate-ssh-keys.cfg
- Enter the following into the new .cfg file you just opened and save the file by pressing CTRL + X, type a Y to save and press enter.
ssh_deletekeys: true
ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
preserve_hostname: false
- The purpose of this file is recreate new SSH keys and clear the hostname on the first boot of the new clone.
Final required shell commands to cleanup your toys
- Clean the cloud-init logs
cloud-init clean --logs
- Remove SSH keys so new clones generate their own unique ones
rm -f /etc/ssh/ssh_host_*
- Clear machine ID so a new one is generated for a new clone
truncate -s 0 /etc/machine-id
- Clean apt cache
apt clean
- Zero out log files
find /var/log -type f -exec truncate -s 0 {} \;
- Clear the bash history just to keep it clean
history -c
Post setup Proxmox
- Head back to the Proxmox GUI and shutdown the VM (or issue a poweroff command from the shell)
- In the main window click the “Hardware” option, then click the “Add” button, go down the list and click “CloudInit Drive”. You only have to select the Storage location at this point. It should be the same location as the VM (it’s probably Local-LVM unless you are doing something more advanced with storage).
- Finally, while still in the hardware window click the “CD/DVD Drive” and select “Do not use any media”. This just makes it so that any clone is not looking for that install DVD when it is started.
- Right click on the VM and choose ‘convert to template’.
Making Clones!
This is where you finally see the beauty of what you did. From the Proxmox GUI right click the template and choose ‘clone’.
From the popup, this is where I HIGHLY recommend that you choose ‘Full Clone’ under the ‘Mode’ drop down. This will create a a fully independent clone from the template and it’s drive. You will also have to choose a ‘VM ID’ that is available on your node. Finally the name, and this is kind of important, whatever name you give this clone will be the Hostname for the VM *since we are using a cloud-init setup.
Now BEFORE STARTING THE VM click the cloud-init tab in your newly made clone. If you have a domain (say, local.example.com) you can set this in the ‘DNS domain’ option. If you would like to set a static IP for this clone you can add it the ‘IP Config’ option. I generally deal with my IP allocations at the router so I don’t add anything here. There are more options which are outside of this tutorial, though not complicated, which we will pass over for now. The main take away is to add the domain to the Cloud-init.
And that’s it. Go ahead and fire up your new VM! On first boot, if you’re quick enough to open the console, you will see it regenerating the SSH keys. If not you can go ahead and ssh using your sudo username (you remembered to shut off root SSH right?!). Before doing anything I am going to say that you should again be running:
apt update && apt upgrade -y && apt dist-upgrade -y
Your clone is only up to date as of when the template was created. Since you just made it there shouldn’t be any updates but it’s a good habit to get into. Three months from now when you make a new clone from it you want to make sure that you are up to date!
Post Tutorial Thoughts
You can expand on the creation process. For example, you can install docker, before the clean up part, and it will already be ready to go on any clone. Or you can add SSH keys for your ‘management’ pc and turn off passwords all together. Anything that you want to be ready to go with a clone you can add to the template during it’s creation.
A Tip of the Hat to Ubuntu
The creation is just about the same with some minor differences:
- ISO to Use
- Debian: netinst ISO (lightweight, minimal install)
- Ubuntu: Server ISO (e.g., 24.04 LTS; lightweight, headless)
- Root Login / User
- Debian: Root login enabled by default; can add users later
- Ubuntu: Root login disabled; create a sudo user during install
- You can skip the root ssh stuff, user creation and adding them to the sudo group
- You will also have to use the ‘sudo’ preface command to run most of the commands above.
- Software Selection during installation
- Debian: Select SSH server + standard utilities, deselect everything else
- Ubuntu: Select OpenSSH server only, no desktop GUI
- Most of the applications we installed in the apt install command above are already installed. There is no harm to keeping the command as is, it will just skip those applications.
- GRUB Bootloader
- Debian: Must select and install manually
- Ubuntu: Usually installed automatically during server install
- Cloud-init setup (pre-first boot)
- On Ubuntu you MUST also go into the IP Config and select DHCP in the IPV4 area of the Cloud-init options. I don’t often use Ubunutu but it seems that with a clone sometimes it boots with a stale DHCP lease or doesn’t even request one.
TLDR Cookbook
- Create a VM being sure to check ‘QEMU Agent” during the creation wizard
- Start the VM and go through the Debian installation
- Post install, issue these commands, in order
# From the shell in the freshly installed VM
apt update && apt upgrade -y && apt dist-upgrade -y
apt install -y sudo tmux curl wget net-tools htop gnupg lsb-release cloud-init qemu-guest-agent qemu-utils
# adding a user is only for a user not set during installation
adduser USERNAME
#Though the user should be added to the sudo group regardless
usermod -aG sudo USERNAME
nano /etc/cloud/cloud.cfg.d/99-regenerate-ssh-keys.cfg
# Add the following to the file, save and close
ssh_deletekeys: true
ssh_genkeytypes: ['rsa', 'ecdsa', 'ed25519']
preserve_hostname: false
# Back at shell
cloud-init clean --logs
rm -f /etc/ssh/ssh_host_*
truncate -s 0 /etc/machine-id
apt clean
find /var/log -type f -exec truncate -s 0 {} \;
history -c
- Shutdown the VM
- Create a cloud-init drive in the Proxmox GUI
- Remove the mounted DVD from the VM.
- Convert the VM to a template.
- When making clones be sure to use ‘Full Clone’ during creation
- Add domain to cloud-init drive
- Boot the clone