From Gentoo Wiki
Jump to: navigation, search

Not to be confused with Docky.

Docker is a container virtualization environment which can establish development or runtime environments without modifying the environment of the base operating system. It has the ability to deploy instances of containers that provide a thin virtualization, using the host kernel, which makes it faster and lighter than full hardware visualization.

Containers that produce kernel panics will induce kernel panics into the host operating system.



Kernel version 3.10 or greater is required in order to run Docker.

If the kernel has not been configured properly before merging the app-emulation/docker package a list of missing kernel options will be printed by emerge. These kernel features must be enabled manually. Pressing the / (forward slash) key while in the ncurses-based menuconfig to search the name of the configuration option.

For the most up-to-date values check the contents of the `CONFIG_CHECK in /usr/portage/app-emulation/docker/docker-9999.ebuild file.

A graphical representation would look something like this:

KERNEL Configuring the kernel for Docker
General setup  --->
    [*] POSIX Message Queues
    -*- Control Group support  --->
        [*]   Freezer cgroup subsystem
        [*]   Device controller for cgroups
        [*]   Cpuset support
        [*]     Include legacy /proc/<pid>/cpuset file
        [*]   Simple CPU accounting cgroup subsystem
        [*]   Memory Resource Controller for Control Groups
        [*]     Memory Resource Controller Swap Extension
        [*]       Memory Resource Controller Swap Extension enabled by default
        [*]     Memory Resource Controller Kernel Memory accounting
        [*]   HugeTLB Resource Controller for Control Groups
        [*]   Enable perf_event per-cpu per-container group (cgroup) monitoring
        [*]   Group CPU scheduler  --->
            [*]   Group scheduling for SCHED_OTHER
            [*]     CPU bandwidth provisioning for FAIR_GROUP_SCHED
            [*]   Group scheduling for SCHED_RR/FIFO
        [*]   Block IO controller
    -*- Namespaces support
        [*]   UTS namespace
        [*]   IPC namespace
        [*]   PID Namespaces
        [*]   Network namespace
[*] Networking support  --->
       Networking options  --->
        [*] Network packet filtering framework (Netfilter)  --->
            [*]   Advanced netfilter configuration
            [*]     Bridged IP/ARP packets filtering
         Core Netfilter Configuration  --->
            <*> Netfilter connection tracking support 
                  *** Xtables matches ***
            <*>   "addrtype" address type match support
            <*>   "conntrack" connection tracking match support
         IP: Netfilter Configuration  --->
            <*> IPv4 connection tracking support (required for NAT)
            <*> IP tables support (required for filtering/masq/NAT)
            <*>   Packet filtering
            <*>   IPv4 NAT
            <*>     MASQUERADE target support
            <*>   iptables NAT support  
            <*>     MASQUERADE target support
            <*>     NETMAP target support
            <*>     REDIRECT target support
        <*> 802.1d Ethernet Bridging
        [*] QoS and/or fair queueing  ---> 
            <*>   Control Group Classifier
        [*] Network priority cgroup
        -*- Network classid cgroup
Device Drivers  --->
    [*] Multiple devices driver support (RAID and LVM)  --->
        <*>   Device mapper support
        <*>     Thin provisioning target
    [*] Network device support  --->
        [*]   Network core driver support
        <*>     Virtual ethernet pair device
    Character devices  --->
        -*- Enable TTY
        -*-   Unix98 PTY support
        [*]     Support multiple instances of devpts
File systems  --->
    <*> Overlay filesystem support 
    Pseudo filesystems  --->
        [*] HugeTLB file system support
Security options  --->
    [*] Enable access key retention support
    [*]   Enable register of persistent per-UID keyrings
    [*]   Diffie-Hellman operations on retained keys

After exiting the kernel configuration, rebuild the kernel. If the kernel rebuild as also a kernel upgrade be sure to rebuild the bootloader's menu configuration, then reboot the system to the newly recompiled kernel binary.

Docker way of checking the kernel configuration:

root #exec /usr/share/docker/contrib/


Install app-emulation/docker:

root #emerge --ask --verbose app-emulation/docker

PaX kernel

When running a PaX kernel (like sys-kernel/hardened-sources), memory protection on containerd needs to be disabled.

Tools in the sys-apps/paxctl package are necessary for this operation. See Hardened/PaX Quickstart for an introduction.

root #/sbin/paxctl -m /usr/bin/containerd

For the hello-world example set this flag for containerd-shim and runc:

root #/sbin/paxctl -m /usr/bin/containerd-shim
root #/sbin/paxctl -m /usr/bin/runc

If an issue with denied chmods in chroots occurs, a more recent version of Docker (>=1.12) is needed. Use the ~amd64 Keyword for Docker and its dependencies listed subsequently when running emerge app-emulation/docker again.




After Docker has been successfully installed, add it to the system's default runlevel then tell OpenrC to start the daemon:

root #rc-update add docker default
root #service docker start

If you need to pass any additional options to the docker daemon edit /etc/conf.d/docker file. See upstream documentation for the various options that can be passed to the DOCKER_OPTS variable.


To have Docker start on boot, enable it:

root #systemctl enable docker.service

To start it now:

root #systemctl start docker.service

If you need to pass any additional options to the docker daemon create the /etc/docker/daemon.json file. See the upstream documentation for various options that be placed into this systemd specific configuration file.

Storage driver

By default on Gentoo Docker will use the device-mapper storage driver. View docker's settings in detail with the info subcommand:

root #docker info

To change the storage driver, first verify the host machines kernel has support for the desired fileystem. The btrfs filesystem will be used in this example:

user $grep btrfs /proc/filesystems

Be aware the root of the docker engine (/var/lib/docker/ by default) must be adjusted to use the btrfs filesystem. If the btrfs storage pool is located under /mnt or /srv, then be sure to change the root (call the 'graph' in docker speak) of the engine.


OpenRC users will need to adjust the DOCKER_OPTS variable in the service configuration file located in /etc/conf.d. The example below displays a change to the storage driver and the docker engine root:

FILE /etc/conf.d/docker
DOCKER_OPTS="--storage-driver btrfs --graph /srv/var/lib/docker"

Start or restart the docker service in order to for the changes to take effect and then validate the changes:

root #docker info


systemd users will need to create a /etc/docker/daemon.json file in order to change the storage driver for the docker service. For example, to use the btrfs driver:

FILE /etc/docker/daemon.json
    "storage-driver": "btrfs"

(Re)start the service in order to make the changes take effect:

root #systemctl restart docker


Add relevant users to the docker group:

root #usermod -aG docker <username>
Allowing a user to talk to the Docker daemon is equivalent to giving it full root access to the host. More



In order to test the installation, run the following command:

user $docker run --rm hello-world

Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:

For more examples and ideas, visit:

That will first download from the Docker Hub the image named hello-world (if it has not been downloaded locally yet), then it will run it inside new namespaces. It purpose is just to display some text through a container.

Building from a Dockerfile

Create a new Dockerfile in an empty directory with the following content:

FILE Dockerfile
FROM php:5.6-apache


user $docker build -t my-php-app .
user $docker run -it --rm --name my-running-app my-php-app

Own images

There are two different ideas how a container should be built.

  • The minimal approach: According to the container philosophy a container should only contain what is needed to serve one process. In this case ideally the container consists of one static binary.
  • The VM approach: A container can be treated like a full system virtualization environment. In this case the container includes a whole operating system.

Build environment for the image

The image can be created out of a live system or - preferably - out of a special build environment

  • To create a build environment for the image, follow the Cross_build_environment guide. There is no need to emerge a full @system. The build essentials are enough.
    • The toolchain tuple could look like x86_64-docker-linux-gnu
    • The build essentials can be build like this
      root #x86_64-docker-linux-gnu-emerge -uva1 --keep-going $(egrep '^[a-z]+' /usr/portage/profiles/default/linux/ portage openrc util-linux netifrc

The minimal approach: Statically linked binaries

There are some caveats with this. The hints for statically linked binaries should be kept in mind for this.

To build an nginx-image:

  • Chroot into the build environment (e.g. chroot-x86_64-docker)
  • Build the desired package statically linked
    root #NGINX_MODULES_HTTP="gzip" CFLAGS="$(emerge --info|grep ^CFLAGS|grep -oP '(?<=").*(?=")') -static" CXXFLAGS=$CFLAGS LDFLAGS="$(emerge --info|grep LDFLAGS|grep -oP '(?<=").*(?=")') -static" PKGDIR=/tmp/ emerge-chroot -va1 --buildpkgonly nginx:mainline
  • Extract the binary package to a tmp dir (e.g. mkdir /tmp/nginx && cd /tmp/nginx && tar xjvf /tmp/www-servers/nginx-*.tbz2)
  • Change the nginx configuration. At least add daemon off; and swap listen for listen
  • Add etc/passwd,etc/resolv.conf,etc/nsswitch.conf and a appropriate etc/ssldirectory. Make sure the etc/nsswitch.conf has "files" instead of "compat" and the etc/passwd file has an "nginx" user entry.
  • Create the docker image out of the current directory
    user $tar --numeric-owner -cj --to-stdout . |docker import - nginx-image
  • Spawn a container and start nginx
    user $docker run -p 80:80 -p 443:443 --name nginx-test -ti --rm nginx-image nginx

The VM-like approach

  • Create the image out of the full environment
    user $cd /usr/x86_64-docker-linux-gnu/ && tar --numeric-owner -cj --to-stdout . --exclude=./{proc,sys,tmp/portage} .|docker import - gentoo-image
  • Spawn a new gentoo container and start a shell:
    user $docker run -v /usr/portage:/usr/portage --name gentoo-test -ti gentoo-image /bin/bash
  • This image can used as a base image. To build a nginx image for example run emerge nginx inside the container and push it back as new image afterwards:
    user $docker commit --message "nginx-image" gentoo-test


Docker service fails to start (systemd)

  • Some users have issues on starting docker.service because of device-mapper error. It can be solved by loading a different storage-driver. E.g. Loading “overlay” graph driver instead of “device-mapper” graph driver.
  • “overlay” graph driver requires "Overlay filesystem support" in kernel configuration:
KERNEL Configuring the kernel for Docker
File systems  --->
    <*> Overlay filesystem support
  • Add following to /etc/portage/package.use/iputils, then re-emerge docker will solve this issue.
FILE /etc/portage/package.use/iputils
app-emulation/docker overlay -device-mapper
  • If you receive an error saying, Error starting daemon: Error initializing network controller: list bridge addresses failed: no available network, you may be missing the docker0 network bridge. Please see the following docker issue which provides a bash script solution to create the docker0 network bridge:

Docker service runs but fails to start container (systemd)

  • if you are using systemd-232 or higher, and receive an error related to cgroups...
user $docker run hello-world

container_linux.go:247: starting container process caused "process_linux.go:359:lib/docker/overlay2/523ed887f681de6ea3838aa5b26c57e88547d65bdd883a6d3538729f19a3 docker: Error response from daemon: invalid header field value "oci runtime errotainer init caused \\\"rootfs_linux.go:54: mounting \\\\\\\"cgroup\\\\\\\" to

ro38729f19a34501/merged\\\\\\\" at \\\\\\\"/sys/fs/cgroup\\\\\\\" caused \\\\\\\"n
  • You will need to add the following line to your kernel boot parameters
CODE Kernel Boot Parameter

See also

  • LXC - Linux containers.

External resources