In this tutorial I show you how you can easily setup and use a chroot-jail on Linux, and explain why this can be especially useful for software development.
My main operating system is Arch Linux - I really like it because of it’s simplicity, flexibility and always up to date packages because of it’s rolling release style. A disadvantage of a rolling release style (for software development) is that the system is quite “volatile”: Major packet update can happen every time you update your system or just certain packages. For software development this is usually not desired - you often need clearly defined and stable environment (see below). A chroot enables to mix both: the bleeding edge characteristics of a rolling release system and the clearly defined and stable development environment.
A chroot is an operation that changes the apparent root directory for the current process and its children to another root directory. Inside a chroot environment - the so called chroot jail - you cannot access files and commands outside that directory. A chroot jail can be a seen as a lightweight virtualization alternative compared to kvm, virtualbox etc. It does not provide the same amount of encapsulation and security as a virtual machine (e.g. a root user can easily “break out” of the chroot), but there are plenty of purposes where this not an issue. On of such purpose where it can make a lot of sense to use chroot jails is software development. They are so easy so setup and can be used (nearly) transparently from the host system.
A chroot as development and test environment has several nice properties:
- minimal: You might only install the the expected dependencies needed to build and run your application. This way you have better control over your dependencies.
- clearly defined: E.g. exactly the same settings, libraries and tools as on the production system.
- stable (regarding packet/library versions): E.g. if you upgrade your host system (or just certain packages), it might be that a newer compiler, newer libraries or other tools that you use to build, run and test are installed. Also any other setting on your your system might interfere somehow with your build and runtime environment needed to build and test your product. A chroot is clearly separated therefore not effected by changes to the host system.
- easy “cross-compilation”: If you run a 64 bit system and you want to compile for a 32 bit system, you can do this in a 32 bit chroot instead of setting up a complete cross compilation toolchain.
- easy backup and distribution: Just archive the directory of the chroot (e.g. with tar) go to another PC, extract and use it there - no need to setup the build/test toolchain there.
In the following I’ll describe how to setup and efficiently use a chroot jail.
In this tutorial we use the tool debootstrap - the ideal tool for quickly installing a new Debian based chroot jail. It should be available via your package manager if you use on of the common used Linux distributions (on Arch Linux it’s available via AUR). Installing Ubuntu 12.04 (precise) 64 bit into the directory
/chroot/ubuntu1204. It is as easy as follows:
sudo debootstrap --variant=buildd --arch=amd64 precise /chroot/ubuntu1204 http://archive.ubuntu.com/ubuntu
It just takes a few minutes (about ~3 minutes on my system) and you have a ubuntu system installed in the directory
/chroot/ubuntu1204 ready to use for chroot - it contains just the basic system and the build-essentials package (this is what the parameter
--variant=buildd means). The installation has just ~300Mb.
Manually changing root
Ok, now we want to chroot to our newly installed ubuntu. At first we do it “manually”. Afterwards, i’ll show you the tool called schroot that simplifies using chroots.
Note: you need root privileges for the most of the following instructions, so run them as sudo
Mount the temporal filesystems from the host system to the chroot system:
cd /chroot/ubuntu1204 mount -t proc proc proc/ mount --rbind /sys sys/ mount --rbind /dev dev/
If you want to use your internet connection it in the chroot system, you have to copy over your DNS details:
cp /etc/resolv.conf etc/resolv.conf
Now change root:
chroot /chroot/ubuntu1204 /bin/bash
You have now entered the chroot-jail - your new root directory is now
/chroot/ubuntu1204 and you should be able to use the chroot as if you had booted to it. With
exit you can leave chroot-jail.
This “manual” procedure is quite a lot to type. Note that you also need root privileges to every time you want do a chroot. Therefore i recommend using schroot, a tool that makes using chroot-jails more convenient - this is what i describe next.
Using schroot to change root
Install schroot on your host system - usually available via your packagemanager.
Now create the configuration file
/etc/schroot/chroot.d/ubuntu1204.conf - mine has the following content (change groups and root-users accordingly):
[ubuntu1204] description=ubuntu_12.04 type=directory directory=/chroot/ubuntu1204 profile=default groups=gernot root-users=gernot
You can now simply change root even without root privileges with:
schroot -c ubuntu1204
or just execute a command (e.g. ls -la) inside the chroot-jail with:
schroot -c ubuntu1204 -- ls -la
This is already quite handy and way easier to use then the “manual” approach described above, but we can further simplify this by setting an alias like:
alias b_="schroot -c ubuntu1204 -- "
Now, executing a command inside the chroot is as simple as:
Using the chroot-jail transparently
The above described approach with using an alias to execute commands might already be simple enough for a lot of use cases. But there is further potential for simplification. Sometimes you might want to make the execution of commands inside the chroot completely transparent, i.e. calling “make” on the host actually executes “make” in a chroot.
One scenario where this makes sense is when you want to use the IDE from the host system but want to build, debug and test inside a chroot. E.g. you use Arch Linux like me ;) and want to use the most recent, bleeding edge KDevelop installed on your host system, but want to build and test the software you develop inside a clearly defined chroot environment. To be able to start the build process from within your IDE in this case, you would have to prepend every command with
schroot -c ubuntu1204 -- - this might be complicated or even not possible to configure (depending on the IDE you use).
This can be achieved easily with execInChroot - a few bash scrips i uploaded to my github account, that enables to easily wrap arbitrary commands to be transparently executed inside a chroot-jail. Just download it (or clone the repository), add the required commands, and start your IDE from the same shell where you sourced enable.source. For more information on how to use execInChroot please read its Readme.
If you find this article useful, if you have suggestions or any other feedback i would appreciate if leave a comment! Thank you!