dock
is a "micro init system" for linux containers
curl -sL https://github.com/robinmonjo/dock/releases/download/v0.8/dock-v0.8.tgz | tar -C /usr/local/bin -zxf -
This will place the latest dock
binary in /usr/local/bin
dock
acts as the PID 1 in the container. It forwards every signals to it's child process. When a child process dies, dock
:
- detect one of its child died
- send SIGTERM to all processes remaining in its process tree
- call
wait4
until no more children exist
Step 3 may block if some processes do not respond to the SIGTERM in step 2. If this is the case, a SIGKILL is sent after the SIGTERM (within a 5 seconds timeout)
dock
is written in Go and has no dependency. The binary can simply be added into a linux container image. It also provides some useful features :
- can call a web hook when process state changes (
starting
,running
andcrashed
) - can say a process started only when a given port is bound (if you start a web server, you may want to know when this one is ready to accept connections). Think container rotation during a deployment process
- smart stdin / stdout (see the
--io
flag for more information) - can provide log rotation (see
--log-rotate
flag for more information) - authoritarian signal transmission (see
--thug
flag for more information)
Note: dock
may be used outside of a container, directly on a linux system
dock [OPTIONS] command
Allows to redirect process stdin / stdout:
dock bash
run bash with current stdin and stdoutdock --io file:///var/run/process.log server.go
redirect stdout to the given file. Stdin stay unchangeddock --io tcp://192.168.1.9:2567 bash
make stdin and stdout go over a tcp connectiondock --io tls://192.168.1.9:2657 bash
make stdin and stdout go over a tls connection
Every URL scheme supported by Go's net.Dial
are supported by dock
If specified, dock
performs a HTTP PUT request with a JSON payload that contains information about the process and its environment:
{
"ps": {
"status": "running",
"net_interfaces": [
{
"name": "lo",
"ipv4": "127.0.0.1",
"ipv6": "::1"
},
{
"name":"eth0",
"ipv4":"172.17.0.2",
"ipv6":"fe80::42:acff:fe11:2"
}
]
}
}
where status
may be: starting
, running
or crashed
. Note that if --bind-port
flag is used, the running
status is sent only once the given port is bound by one of dock
children processes.
This payload will evolve to carry more useful information in the future.
Port dock
's child process is expected to bind. Port may be bound by any processes in the container. See --strict-port-binding
for more control.
If --bind-port
is specified, this flag will ensure that the process is considered running only if the binder is a descendant process of dock
. This is not really useful in container environment since dock will have PID 1 (hence any port in the container will be bound by a descendant). Be careful while using this flag (TODO: explain why)
If given --io
is a file, specifying --log-rotate X
perform a log rotation every X hours:
- archive (gzip) the current log file by prepending a timestamp (in the stdout file directory)
- empty the current log file
- keep at most 5 log archives
Add a prefix to stdout lines. Format: prefix[:<color>]
where color may be white, green, blue, magenta, yellow, cyan or red
When you stop a docker container, a SIGTERM is sent to the process running it. The docker daemon then wait for a certain delay and if the container still exists, it will kill the process (using SIGKILL). This happens a lot with process ran as PID 1 inside a linux container, since the kernel will treat PID 1 specially.
With dock
this behavior happens less frequently since dock
runs as PID 1. However some program block or ignore some signals. For example, sh
ignores the SIGTERM signal. Using docker stop
on a container running sh
will force the docker engine to kill the process. This may be frustrating.
The --thug
flag allows to translate a stopping signal (SIGINT, SIGQUIT, SIGTERM) into a SIGKILL if the stopping signal is blocked or ignored by dock
's child process
- use the Makefile and Dockerfile :)
- use the
-d
flag for verbosity - the
utils.go
file contains some nice function to inspect and debug
- why this ?
- more tests !
- process is not stopped if interactive and over the network and the connection is closed