How to use --init parameter in docker run

There are --init and --init-path options for docker run, but it's not clear how to use it.

At first, I thought it's something like dumb-init, but included in docker core (kind of "native"). But --init key demands --init-path to be set as well, pointing to docker-init binary, and gives no clue on where to take it. Google is silent about docker-init.

Okay, maybe I'm supposed to use yelp/dumb-init or 'phusion/baseimage-docker', but those solutions don't seem to use docker run's --init option.

So, I'm curious where do I take this "docker-init binary" to set the --init-path to?


Solution 1:

Specifiying the new docker --init option in the run command basically sets ENTRYPOINT to tini and passes the CMD to it or whatever you specify on the commandline.

For example, without init, CMD becomes pid 1. In this case, /bin/bash

docker run -ti --rm ubuntu:16.04 /bin/bash
root@d740f7360840:/# ps -fA
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  1 03:30 ?        00:00:00 /bin/bash
root        11     1  0 03:30 ?        00:00:00 ps -fA

With --init, tini (/dev/init) becomes pid 1

docker run -ti --init --rm ubuntu:16.04 /bin/bash
root@5b5fe6ee71b5:/# ps -fA
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  1 03:30 ?        00:00:00 /dev/init -- /bin/bash
root         7     1  0 03:30 ?        00:00:00 /bin/bash
root        12     7  0 03:30 ?        00:00:00 ps -fA

tini is a first class init process that can be run as pid 1 correctly. A pid 1 process must reap forked child processes correctly, if it doesn't then bad things happen like resources get leaked and zombies appear.

This is what you want for applications that fork and haven't been written with child reaping in mind as normally they would leave this up to the init system. A classic example is java Jenkins applications.

Solution 2:

I've found this in documentation:

You can use the --init flag to indicate that an init process should be used as the PID 1 in the container. Specifying an init process ensures the usual responsibilities of an init system, such as reaping zombie processes, are performed inside the created container. The default init process used is the first docker-init executable found in the system path of the Docker daemon process. This docker-init binary, included in the default installation, is backed by tini.

I couldn't find docker-init on a macOS Docker installation, but on Linux it's here:

/usr/bin/docker-init