In my recent push for more virtualization I sat down today and constructed a very minimal Debian template that only has the bare necessities installed to be able to communicate on the network and operate the base-system. This template will be used to spin up LXC containers on a hypervisor, which is very fast and has virtually no overhead.

This post describes the steps you have to take to achieve the same.

First update your system to the latest version:

apt update apt upgrade

The following command spews out a list of packages marked by priority. Everything that’s not essential , required or important can be safely removed. Use apt purge $PACKAGENAME for uninstallation to also get rid of any config files.

dpkg-query -Wf '${Package;-40}${Priority}

' | sort -b -k2,2 -k1,1

Go through the list and decide what should be available in your template and what you don’t need. The biggest gains in disk space can be obtained by uninstalling X11 and all of the graphics related libraries. You don’t want a GUI on your servers anyway, do you?

By meticulously going through the list, I managed to get my base installation down to 170MB. That’s pretty good for a fully functional Linux system I think.

Next clean up the package system:

apt-get autoremove apt-get autoclean apt-get clean

Now this is very important: create new SSH keys on first bootup.

Otherwise all of your containers will have the same host keys, which has big security implications.

First, save /etc/rc.local to a new copy:

mv /etc/rc.local /etc/rc.local.orig

Now install the following script as /etc/rc.local . It creates new keys on the first startup and then replaces itself with the copy you made before.

#!/bin/sh rm -f etc/ssh/ssh_host_* /usr/bin/ssh-keygen -t rsa -N '' -f /etc/ssh/ssh_host_rsa_key /usr/bin/ssh-keygen -t dsa -N '' -f /etc/ssh/ssh_host_dsa_key /usr/bin/ssh-keygen -t ed25519 -N '' -f /etc/ssh/ssh_host_ed25519_key /usr/bin/ssh-keygen -t ecdsa -N '' -f /etc/ssh/ssh_host_ecdsa_key /usr/bin/ssh-keygen -t rsa1 -N '' -f /etc/ssh/ssh_host_key service restart ssh mv -f /etc/rc.local.orig /etc/rc.local

Be sure to make the script executable by running chmod a+x /etc/rc.local .

But you dont want to stop there! To achieve a nice and neat starting template, it is necessary to clean out all the stuff that should start from scratch when you spin up a new container based off of the template.

First run service rsyslogd stop , if you’re gonna clean out everything later, you don’t want to write new data anymore in this session.

Force a logrotate run to get fresh, empty logfiles logrotate -f /etc/logrotate.conf . Also also go through all the config files in /etc/logrotate.d/ and force run logrotate on them.

Now it’s time to clean up the log directory:

rm /var/log/*.log.* rm /var/log/apt/*.* cat /dev/null > /var/log/btmp rm /var/log/btmp.* cat /dev/null > /var/log/dmesg rm /var/log/dmesg.* cat /dev/null > /var/log/lastlog

Take another look into /var/log and see if you missed anything. All of the files in here should have a size of 0 bytes.

Clean up any temporary directories:

rm -rf /tmp/* rm -rf /var/tmp/*

Lastly remove any traces of your work by first removing bash’s history file and then unsetting the HISTFILE environment variable, otherwise you last logoff will be recorded into a new copy of that file.

rm ~/.bash_history unset HISTFILE

That’s it, now you have a clean slate to spin up your containers from and deploy all of the different services you need with your preferred config management solution. I personally like Ansible a lot, but choose whatever tickles your fancy. Just don’t do it all by hand, that’s error prone, slow and non reconstructable.