Using Docker as chroot-on-steroids

I use chroot environments quite a lot as a light way to develop/test/integrate software for different Linux distributions or even platforms (eg. Ubuntu 18.04 on ARM vs Debian 10 on x86), thanks to the Linux kernel stable ABI and qemu emulation.

However, it was always a little bit painful to setup: using eg. debootstrap or extracting ISO images to get the basic filesystem and some manual configuration of schroot, etc., etc.

Enter docker

Docker introduced a lot of different things, but among them is the fact that all major Linux distributions basic filesystem images are available on docker hub. To use it as a replacement for our good old chroot, it basically boils down to 3 steps:

  1. create the container, using host networking (ie no separate network namespace) and sharing your homedir
  2. make sure everything is up-to-date and add a user with the exact same login, uid, gid and homedir as yours but inside the container (so you can use your homedir seamlessly)
  3. log into the container

But wait, there's more

Some time ago a multiarch/qemu-user-static image was introduced to ease multiarch support with docker. This will automatically configure the right qemu support for your image automatically!

Examples

Ubuntu 18.04

# step 1: create your chroot (must be done once - I am sharing my homedir with my chroot and same UID/GID)
docker run --name u1804 --privileged --net host -v $HOME:$HOME -v /dev:/dev -v/lib/modules:/lib/modules/host:ro -td ubuntu:18.04 /bin/bash
# step 2: update and add user inside container
docker container exec u1804 sh -c "apt -qy update && apt dist-upgrade -qy && apt install -qy vim sudo && groupadd -g $(id -rg) $USER && useradd -u $(id -ru) -g $(id -rg) -M -d $HOME -s /bin/bash $USER && echo '$USER ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && echo u1804 > /etc/debian_chroot"
# step 3: log into chroot
docker container exec -it u1804 /bin/login -f $USER

CentOS 7

# step 1: create your chroot (must be done once - I am sharing my homedir with my chroot and same UID/GID)
docker run --name centos7 --privileged --net host -v /dev:/dev -v $HOME:$HOME -v /lib/modules:/lib/modules:ro -td centos:7 /bin/bash
# step 2: update and add user inside container
docker container exec centos7 sh -c "yum -y makecache && yum -y install deltarpm && yum -y update && yum -y install vim sudo && groupadd -g $(id -rg) $USER && useradd -u $(id -ru) -g $(id -rg) -M -d $HOME -s /bin/bash $USER && echo '$USER ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && echo centos7 > /etc/debian_chroot"
# step 3: log into chroot
docker container exec -it centos7 /bin/login -f $USER

Debian 10 (Buster) for ARM64

# step 0: add support for multiarch (must be done once after reboot)
docker run --rm --privileged multiarch/qemu-user-static --reset --persistent yes --credential yes
# step 1: create your chroot (must be done once - I am sharing my homedir with my chroot and same UID/GID)
docker run --name aarch64_deb10 --privileged --net host -v $HOME:$HOME -v /dev:/dev -v/lib/modules:/lib/modules/host:ro -td arm64v8/debian:10 /bin/bash
# step 2: update and add user inside container
docker container exec aarch64_deb10 sh -c "apt -qy update && apt dist-upgrade -qy && apt install -qy vim sudo make git && groupadd -g $(id -rg) $USER && useradd -u $(id -ru) -g $(id -rg) -M -d $HOME -s /bin/bash $USER && echo '$USER ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers && echo aarch64_deb10 > /etc/debian_chroot"
# step 3: log into chroot
docker container exec -it aarch64_deb10 /bin/login -f $USER