A clean start – How to prepare a minimal Debian template for LXC containers

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}\n' | 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.

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

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.


  1. get my base installation down to about 500MB
    Well, something tells me that your minimal system is not minimal at all.

    Default debian jessie (amd64) image that comes with lxd (i.e. you can get it running via ‘lxc launch images:debian/jessie/amd64 mydeb’) is around 100MB packed. Unpacked it will be something around 150MB, I guess.
    As a side note, if you really want to have minimal containers, give alpine linux a try. That’s one thing which is really minimal.

    1. Well, my base installation already has some software components installed that I need on each of my containers. Of course there would be ways to shrink it down even further and still have a working system. This was just tailored to my specific needs, which is why I also want Debian and not Alpine (which I was aware of). But thanks for your remarks they might be very helpful for someone else reading this article.

    2. Erratum: I just checked and my minimal template is indeed only 170MB compressed.
      -rw-r--r-- 1 root root 170M Aug 10 20:22 debian-8.0-minimal_8.4.1_amd64.tar.gz

      Thanks for pointing out that error.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.