Using schroot instead of LXC containers

So, I have been using LXC to host my server services for a period of time, with a view to keeping things portable should I need to change provider. It’s very good in that it’s integrated into the Linux kernel and in Ubuntu at least it’s not too difficult to setup, however there are a number of problems with it.

First and foremost, every time the container operating system upgrades anything to do with init scripts, it won’t boot any more, so you are forced to hold back packages with varying amounts of success. Secondly, there does seem to be some overhead running things in an LXC container, and thirdly it isn’t as portable as it could be i.e. there is no live migration. and you will have to change config files if you move hoster to reflect you new IP address.

As I’m not selling containers as VPS, I only need to run 1 server instance, and therefore don’t really need containerisation at all, enter schroot. Schroot is like chroot without the hassle and with added flexibility, in a nutshell it will mount and start everything correctly for you to the point where you can automate startup and running of services in the chroot, it doesn’t suffer from init script borkage since the init system isn’t used at all, and it’s more portable as networking is irrelevant to a chroot (it simply uses the hosts networking).

Ok so where to start, well if you are already using LXC you can use the directory your container is stored in. I opted to move mine to a sane location before starting, in the interests of convention and easy administration. So, I created a “schroot” directory in the /home directory i.e.

mkdir /home/schroot

and moved the LXC container directory like so

mv /home/lxc/server/rootfs /home/schroot

Then we have to setup the schroot config file which lives in /etc/schroot/schroot.conf

nano /etc/schroot/schroot.conf

The un-commented part of my file reads as follow

[lucid]
type=directory
description=Ubuntu Lucid
directory=/home/schroot/rootfs
users=root
groups=root
root-groups=root

We also need to edit “mount-defaults” so that it won’t overwrite existing user directories (you may already have data in user directories from the LXC container if you are using mail services in there) so

nano /etc/schroot/mount-defaults

and it should read like this:-

# fstab: static file system information for chroots.
# Note that the mount point will be prefixed by the chroot path
# (CHROOT_PATH)
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
/proc           /proc           none    rw,rbind        0       0
/sys            /sys            none    rw,rbind        0       0
/dev            /dev            none    rw,rbind        0       0
#/home          /home           none    rw,bind         0       0
/tmp            /tmp            none    rw,bind         0       0

Notice the “#” at the start of “/home” to comment that out.

We also want to comment out everything in the “nssdatabases-defaults” file as we have a full system inside the chroot and doing so will mean some services won’t start because of non-existent users. So

nano /etc/shcroot/nssdatabases-defaults

which should read:-

# System databases to copy into the chroot from the host system.
#
# <database name>
#passwd
#shadow
#group
#services
#protocols
#networks
#hosts

You should be able to go into the chroot at this stage to confirm you have got everything right so far:-

schroot -c lucid

The prompt should change to indicate you are in the chroot. If everything worked you are ready to move on to the next level of ascension.

At this point we can start services and treat the chroot “nearly” like a separate system. Important things to note here are that everything is shared between the 2 systems except environment variables and filesystem, so for instance when you start a service that port is then in use as far as the host system and chroot are concerned, things are therefore only “logged” on the host system. Exit out of the chroot and continue on.

We can automate startup and shutdown of the chroot and services using some shell scripts inside /root of the chroot, so on my system

nano /home/schroot/rootfs/root/startservices

which depending on what services you want started will look like this:-

#!/bin/sh
service amavis start
service clamav-daemon start
service courier-authdaemon start
service courier-imap start
service courier-imap-ssl start
service courier-pop start
service courier-pop-ssl start
service fetchmail start
service mysql start
service nginx start
service php5-fpm start
service postfix start
service postgrey start
service zabbix-agent start
service zabbix-server start

Don’t forget to make the script executable i.e.

chmod +x /home/schroot/rootfs/root/startupservices

Conversely make a stopservices script

nano /home/schroot/rootfs/root/stopservices

which reads:-

!/bin/sh

service amavis stop
service clamav-daemon stop
service courier-authdaemon stop
service courier-imap stop
service courier-imap-ssl stop
service courier-pop stop
service courier-pop-ssl stop
service fetchmail stop
service mysql stop
service nginx stop
service php5-fpm stop
service postfix stop
service postgrey stop
service zabbix-agent stop
service zabbix-server stop

and make that executable also. We make the chroot start and stop by adding the relevant commands to “/etc/rc.local”, for startup, and “/etc/rc0.d/schroot” and “/etc/rc6.d/schroot” for shutdown/reboot, again making the last 2 scripts executable using chmod.

So my /etc/rc.local reads:-

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

SESSION=$(schroot --begin-session -c lucid)
schroot --run-session -c "$SESSION" -- /root/startservices

exit 0

and /etc/rc0.d/schroot and /etc/rc6.d/schroot reads:

 schroot --run-session -c "$SESSION" -- /root/stopservices
 schroot --end-session -c "$SESSION"

Reboot to test and I apologise if it’s borked. It’s important to note that you can go into the chroot at any time when after boot to change things by typing

schroot --run-session -c "$SESSION"

Enjoy.

Join the conversation

8 Comments

    1. The thing I have never been able to figure out, both with LXC and Docker, is how to seamlessly log. I would like to use it as a stripped back virtualistion, but logging just seems to be a PITA.

      I’ll have a look at that. If you have a decent, and more or less automatic, sane, default logging, I would be very happy to give it a go.

  1. I’m going in opposite direction. I’m going to migrate from schroot to LXC. Reason: schroot makes total mess with mounts. Instead just mount –bind /proc,sys,dev and chroot, it mounts chroot somewhere with long, uuid-like, unreadable destination, next mounts lot of things on it, and then does chroot. And on fedora – doesn’t properly umount.

    So after I use schroot – my “mount” output is total annoying mess.

    1. I guess it was. As well as having loads of UUID type mounts, and not cleaning them up after exit, they would reappear after reboot, so you would have an ever increasing list of useless and illegible mounts!

Leave a comment