I like to use a custom debian container image, that has some tools installed and a non root user setup. I then dump and export the rootfs as container template.
To keep this template updated, I wrote this script.
This script works for all distribitions, you just have to update the variables:
#!/bin/bash
set -euo pipefail
TEMPLATE_VMID=999
IMAGE_NAME="debian-12-custom_amd64"
UPDATE_CMD="apt-get update && apt-get dist-upgrade -y && apt-get autoremove -y --purge && apt-get clean -y && rm -rf /var/lib/apt/lists/* && history -c"
CONTAINER_STORAGE="local-lvm"
BACKUP_STORAGE="local"
TEMPLATE_STORAGE="local"
get_path() {
if [[ "${1}" == 'local' ]]; then
echo "/var/lib/vz"
else
echo "/mnt/pve/${1}"
fi
}
generate_vmid() {
while true; do
local vmid=$((RANDOM % 9901 + 100)) # Generate a random number between 100 and 10000
if ! pvesh get /cluster/resources --output-format json | jq -e ".[] | select(.vmid == ${vmid})" > /dev/null; then
echo "$vmid"
return
fi
done
}
main() {
local vmid
vmid=$(generate_vmid)
trap 'cleanup "${vmid}"' EXIT
pct clone "${TEMPLATE_VMID}" "${vmid}" --full --hostname "update-ct-image" --storage "${CONTAINER_STORAGE}"
pct start "${vmid}"
until pct exec "${vmid}" -- bash -c 'ping -c1 1.1.1.1 &>/dev/null'; do
echo "Waiting for container to come online..."
sleep 1
done
pct exec "${vmid}" -- bash -c "${UPDATE_CMD}"
pct stop "${vmid}"
local backup_path="$(get_path ${BACKUP_STORAGE})"
local template_path="$(get_path ${TEMPLATE_STORAGE})"
vzdump "${vmid}" --compress zstd --mode stop --storage "${BACKUP_STORAGE}"
mv "${backup_path}/dump/vzdump-lxc-${vmid}"*.tar.zst "${template_path}/template/cache/${IMAGE_NAME}.tar.zst"
rm "${backup_path}/dump/vzdump-lxc-${vmid}"*.log
pct destroy "${TEMPLATE_VMID}" --purge
pct clone "${vmid}" "${TEMPLATE_VMID}" --full --storage "${CONTAINER_STORAGE}" --hostname "debian-12"
pct template "${TEMPLATE_VMID}"
pct destroy "${vmid}" --purge
trap - EXIT
}
cleanup() {
local vmid="${1}"
local backup_path="$(get_path ${BACKUP_STORAGE})"
if [[ -n "${vmid}" ]]; then
rm -rf "${backup_path}/dump/vzdump-lxc-${vmid}"*
pct destroy "${vmid}" --purge
fi
}
main "$@"