proxmox

Version 9.6 by Kevin Wiki on 2026/05/18 08:16

Getting Started with Proxmox VE LXC and VM Templates

Proxmox VE (PVE) allows users to create and manage both LXC containers and KVM virtual machines (VMs). This guide walks you through the process of downloading, importing, and creating templates for both.

LXC Templates

LXC containers are lightweight and ideal for running Linux services with minimal overhead.

List Available Templates

To view the available LXC templates:

pveam list

Download Templates

Use the pveam download command to import templates to the local storage:

pveam download local ubuntu-22.04-standard_22.04-1_amd64.tar.gz
pveam download local ubuntu-24.04-standard_24.04-1_amd64.tar.zst
pveam download local debian-12-standard_11.7-1_amd64.tar.zst

Once downloaded, these templates can be used to create new LXC containers from the Proxmox web interface or via CLI.

VM Template from Ubuntu Cloud Image

KVM VMs are ideal when you need full virtualization, for instance, to run Windows or more complex Linux systems.

Download Ubuntu Cloud Image

Download the official Ubuntu 24.04 cloud filename

wget http://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img

Create the Virtual Machine

Create a new VM with ID 910 (you can pick any unused ID):

qm create 910 -name template-ubuntu-jammy -memory 2048 -net0 virtio,bridge=vmbr0 -cores 2 -sockets 1

Import and Attach the Disk

Choose the correct storage (replace nvme if you use a different storage name):

qm importdisk 910 ubuntu-24.04-server-cloudimg-amd64.img nvme
qm set 910 -scsihw virtio-scsi-pci -virtio0 nvme:vm-910-disk-0

Configure the VM

qm set 910 -serial0 socket
qm set 910 -boot c -bootdisk virtio0
qm set 910 -agent 1
qm set 910 -hotplug disk,network,usb
qm set 910 -vcpus 1
qm set 910 -vga qxl
qm set 910 -ide2 nvme:cloudinit
qm resize 910 virtio0 +8G

If your disk is using SCSI instead of virtio, resize like this:

qm resize 910 scsi0 +8G

Convert the VM into a Template

qm template 910

Now you can use this template to clone new VMs instantly.

Bash Script to Automate Setup

Install the above using bash script below

setup_proxmox_templates.sh

#!/bin/bash

# Exit on errors
set -e

echo "Downloading LXC templates..."
pveam download nvme ubuntu-22.04-standard_22.04-1_amd64.tar.zst
pveam download nvme ubuntu-24.04-standard_24.04-2_amd64.tar.zst
pveam download nvme alpine-3.21-default_20241217_amd64.tar.xz
pveam download nvme debian-12-standard_12.7-1_amd64.tar.zst

echo "Downloading Ubuntu cloud image..."
wget -N http://cloud-images.ubuntu.com/releases/24.04/release/ubuntu-24.04-server-cloudimg-amd64.img

echo "Creating VM Template..."
qm create 910 -name template-ubuntu-jammy -memory 2048 -net0 virtio,bridge=vmbr0 -cores 2 -sockets 1 && 1

# qm importdisk 910 ubuntu-24.04-server-cloudimg-amd64.img nvme
# qm set 910 -scsihw virtio-scsi-pci -scsi0-virtio0 nvme:910/vm-910-disk-0
qm set 910 -scsihw virtio-scsi-pci -scsi0 nvme:0,import-from=/mnt/nvmestorage/template/iso/ubuntu-24.04-server-cloudimg-amd64.img

qm set 910 -serial0 socket
qm set 910 -boot c -bootdisk virtio0
qm set 910 -agent 1
qm set 910 -hotplug disk,network,usb
qm set 910 -vcpus 1
qm set 910 -vga qxl
qm set 910 -ide2 nvme:cloudinit
# qm resize 910 scsi0 +8G

read -p "Confirm converting to template by pressing Enter"
qm template 910

echo "Templates setup complete."

VM runtime setup

After creating the VM and before making it into a template there are some programs and settings we want to ensure exists always.

qemu-guest-agent is for allowing proxmox to query information from the VM such as IP address, shutdown commands, etc

sudo apt update
sudo apt upgrade -y
sudo apt install qemu-guest-agent -y

sudo systemctl enable qemu-guest-agent.service
sudo systemctl start qemu-guest-agent.service

cloud-init is a great hook for installing or configuring programs or receiving variables from cloudinit CDROM drive. Making it easier to change IP, hostname, DNS, username/password, etc between VMs.

# The top level settings are used as module
# and system configuration.
# A set of users which may be applied and/or used by various modules
# when a 'default' entry is found it will reference the 'default_user'
# from the distro configuration specified below
users:
   - default


# If this is set, 'root' will not be able to ssh in and they
# will get a message to login instead as the default $user
disable_root: true

# This will cause the set+update hostname module to not operate (if true)
preserve_hostname: false

apt:
  # This prevents cloud-init from rewriting apt's sources.list file,
  # which has been a source of surprise.
  preserve_sources_list: true

# If you use datasource_list array, keep array items in a single line.
# If you use multi line array, ds-identify script won't read array items.
# Example datasource config
# datasource:
#    Ec2:
#      metadata_urls: [ 'blah.com' ]
#      timeout: 5 # (defaults to 50 seconds)
#      max_wait: 10 # (defaults to 120 seconds)




# The modules that run in the 'init' stage
cloud_init_modules:
 - seed_random
 - bootcmd
 - write-files
 - growpart
 - resizefs
 - disk_setup
 - mounts
 - set_hostname
 - update_hostname
 - update_etc_hosts
 - ca-certs
 - rsyslog
 - users-groups
 - ssh

# The modules that run in the 'config' stage
cloud_config_modules:
 - snap
 - ssh-import-id
 - keyboard
 - locale
 - set-passwords
 - grub-dpkg
 - apt-pipelining
 - apt-configure
 - ntp
 - timezone
 - disable-ec2-metadata
 - runcmd
 - byobu

# The modules that run in the 'final' stage
cloud_final_modules:
 - package-update-upgrade-install
 - fan
 - landscape
 - lxd
 - write-files-deferred
 - puppet
 - chef
 - mcollective
 - salt-minion
 - reset_rmc
 - scripts-vendor
 - scripts-per-once
 - scripts-per-boot
 - scripts-per-instance
 - scripts-user
 - ssh-authkey-fingerprints
 - keys-to-console
 - install-hotplug
 - phone-home
 - final-message
 - power-state-change

# System and/or distro specific settings
# (not accessible to handlers/transforms)
system_info:
  # This will affect which distro class gets used
  distro: debian
  # Default user name + that default users groups (if added/used)
  default_user:
    name: debian
    lock_passwd: True
    gecos: Debian
    groups: [adm, audio, cdrom, dialout, dip, floppy, plugdev, sudo, video]
    sudo: ["ALL=(ALL) NOPASSWD:ALL"]
    shell: /bin/bash
  # Other config here will be given to the distro class and/or path classes
  paths:
     cloud_dir: /var/lib/cloud/
     templates_dir: /etc/cloud/templates/
  package_mirrors:
     - arches: [default]
      failsafe:
        primary: https://deb.debian.org/debian
        security: https://deb.debian.org/debian-security
  ssh_svcname: ssh