Docker Without Docker

Recurse Center

16 April 2015

Aditya Mukerjee

Some common questions

Wouldn't it be nice if

Why not virtualize

What is an operating system ("distro")?

That's basically it.

Inspecting processes

But what's actually in /sbin/init?

Within 9 days, all of the top 10 Linux distributions will use systemd by default, or descend from one that does.

What tools does systemd provide?

These are all already available on any machine using systemd

How do you create a distribution from scratch?

0. Create a directory that represents the new root directory (ie, "/")
1. Move all the right files there, either manually, or with a tool like deboostrap, pacstrap, yum, etc.)
2) Tar your directory and ship it

Congratulations! This directory is a pseudo-snapshot of your new distro!

Where does Docker come in?

FROM debian:wheezy
MAINTAINER Aditya Mukerjee <>

RUN apt-get update
RUN apt-get install -y procps psmisc
CMD ["/bin/bash"]

Build and run:

$ docker build -t bashtest .
$ docker run -it bashtest

(as with Git hashes, you can use the container ID or a prefix instead of the name)

Dissecting the Dockerfile

FROM debian:wheezy
MAINTAINER Aditya Mukerjee <>

RUN apt-get update
RUN apt-get install -y procps psmisc
CMD ["/bin/bash"]
$ docker ps 
$ docker exec <container> ps aux

Can I access this 'snapshot'?

$ docker export <container-hash> > img.tar

Let's inspect that:

$ mkdir ~/bashtestcontainer
$ tar -C ~/bashtestcontainer -xvf img.tar

What's inside the tarfile?

Does this look familiar?

Can I do this without Docker?

$ mkdir debian-tree
$ debootstrap --arch=amd64 unstable debian-tree

Does this look familiar?

How do we run the Debian image, though?

Let's try this out

$ systemd-nspawn -D debian-tree/ /bin/echo "hello, outside world!"
$ systemd-nspawn -D debian-tree/ /bin/bash 
$ systemd-nspawn -D debian-tree/ /sbin/init

We can manage our containers with machinectl

$ machinectl list
$ machinectl status debian-tree
$ machinectl reboot debian-tree
$ machinectl poweroff debian-tree

Note that these are analogous to

$ systemctl reboot
$ systemctl poweroff

which we use for managing our systemd (host) servers

But all this has to be on our local machine, right?

$ machinectl -H
$ machinectl -H

Daemons, services, and units

Daemonizing, the old way:

All in all, it requires fifteen different steps, with serious consequences for even small mistakes


Daemonizing, the new way:



No fork. No pain.

Daemonizing containers

$ mv ~/debian-tree /var/lib/container/debian-tree
$ systemctl start systemd-nspawn@debian-tree.service    # start now
$ systemctl enable systemd-nspawn@debian-tree.service   # autostart on boot

How do we get logs?

$ journalctl
$ journalctl -M debian-tree

What about profiling?

Same thing.

$ systemd-analyze -M debian-tree       # list startup time
$ systemd-analyze blame -M debian-tree # break down the boot time per-unit

But what about networking?

Networking just works

How can I control resources for a container?

$ systemd-cgroup

cgroups (control groups) are a kernel feature for managing resources for a single process or collection of processes, such as:

Is this all specific to systemd, or can I use Docker?

$ systemd-nspawn --machine bashtest --directory ~/bashtestcontainer /bin/bash

or even:

$ machinectl pull-dkr chimeracoder/nginx-nspawn --dkr-index-url



Remember what we said at the beginning

Containers let you virtualize parts of your OS, without requiring you to virtualize the whole OS.

Containers let you virtualize the filesystem, the process tree, the network stack,`/proc`, /sys, and more selectively.

So why use Docker at all?

Try it yourself!

Some cool things you can do with systemd-nspawn:

Thank you

Aditya Mukerjee