When using Proxmox one of the things that feels helpful to do is to configure the LXC (Linux Container) OSes exactly how you like them. We all have our preferences of what we want in the VMs, or even just setting up some basic software that you then want to duplicate a bunch of times. A WordPress server, for example.
It seems odd then that when you select in Proxmox to ‘Make as template’ it doesn’t *actually* do what you might expect. It makes that image just read-only so that it can then be the basis of linked clones for new VMs. That’s really not what is expected when dealing with LXC templates.
However, there is a way around that. I found on a blog post about how to use the vzdump tool to be able to take the image of an LXC container, make it a dump file and then move it to the /var/lib/vz/template/cache directory. From there you can select it ‘as a template’ when making a new container!
With that I made a script that will use the name of the container as part of the filename and prefix the output template with your host’s domain name – so that you know they’re yours.
The script is below:
#!/bin/bash
TEMPLATEDIR=/var/lib/vz/template/cache/
#TEMPLATEDIR=/ceph/data/Proxmox/template/cache
CONTAINERID=$1
if [ "$CONTAINERID" != "" ]; then
CONFFILE=/tmp/vzdump_${CONTAINERID}.info
LOGFILE=/tmp/vzdump_${CONTAINERID}.log
pct config $CONTAINERID >$CONFFILE
if [ "$?" = "0" ]; then
echo "Working on container $CONTAINERID"
cat $CONFFILE
pct set $CONTAINERID --delete net0
echo "Archiving container $CONTAINERID ... "
vzdump $CONTAINERID --mode stop --compress gzip --dumpdir $TEMPLATEDIR >$LOGFILE
if [ "$?" = "0" ]; then
cat $LOGFILE
ARCFILE=`cat $LOGFILE | grep 'INFO: creating vzdump archive' | awk -F "'" {'print $2'}`
echo "Archive created as $ARCFILE"
# Move the log file out of the way
ARCLOG=`echo $ARCFILE | sed -e "s/.tar.gz/.log/g"`
rm -f $ARCLOG
# Get info about the container
CONTAINERHOST=`cat $CONFFILE | grep 'hostname:' | awk {'print $2'}`
CONTAINERARCH=`cat $CONFFILE | grep 'arch:' | awk {'print $2'}`
OURDOMAIN=`hostname -d`
# Form new container filename
EXTRA=""
if [ "$2" != "" ]; then
EXTRA="-${2}"
fi
NEWFILE="${OURDOMAIN}-${CONTAINERHOST}${EXTRA}-${CONTAINERARCH}.tar.gz"
echo "Renaming to ${NEWFILE}"
mv -f $ARCFILE ${TEMPLATEDIR}/${NEWFILE}
else
echo "Archive creation failed"
cat $LOGFILE
fi
else
echo "Unable to work on container $CONTAINERID"
cat $CONFFILE
fi
rm -f $LOGFILE
rm -f $CONFFILE
else
echo "Specify a container ID"
fi
The big thing about it is that you remove the network device from the image before compressing, then when you make your new container nothing like that of the old system will remain (including the hostname). When creating a container you may also want to clean it up. I have a script for that too:
Run this with the ‘full’ argument (e.g. /root/bin/cleanup full
) before making your VM template to save space:
#!/bin/bash
apt-get -y autoremove
apt-get clean
rm -f /var/log/dpkg.log
if [ "$1" = "full" ]; then
rm -f /root/.bash_history
rm -f /root/.lesshst
rm -f /root/.viminfo
find /var/lib/apt/lists -type f -exec rm \{\} \;
journalctl --flush --rotate --vacuum-time=1s
journalctl --user --flush --rotate --vacuum-time=1s
fi