Lei Zhilong

The best way to input is to output

Jun 4, 2020 - 4 minute read - Comments - Cheat Sheets

Docker

Disclaimer: This article will be updated from time to time to add new content or make any changes in exsisting sections without any notice. Using them under your own investigation in production is advised.

I. Installation

1. Debug Docker desktop for macOS log in terminal

To get Docker desktop for macOS log, try this

1
2
3
4

pred='process matches ".*(ocker|vpnkit).*"
  || (process in {"taskgated-helper", "launchservicesd", "kernel"} && eventMessage contains[c] "docker")'
/usr/bin/log stream --style syslog --level=debug --color=always --predicate "$pred"

II. Usage

1. Container does not respond to Ctrl + C

Cause

The problem is that Ctrl-C sends a signal to the top-level process inside the container, but that process doesn’t necessarily react as you would expect. The top-level process has ID 1 inside the container, which means that it doesn’t get the default signal handlers that processes usually have. If the top-level process is a shell, then it can receive the signal through its own handler, but doesn’t forward it to the command that is executed within the shell.

Solution

Specify an init process 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.

Sample

1
2

docker run -v `pwd`:/srv/gitbook -p 4000:4000 --rm --init leizhilong/gitbook gitbook serve

Referecne

2. exec form or shell form in Dockerfile

There are two ways to specify a start command in Dockerfile, entrypoint and cmd.

ENTRYPOINT

  1. exec form ENTRYPOINT
1
2
# preferred form
ENTRYPOINT ["executable", "param1", "param2"]
  1. shell form ENTRYPOINT
1
2
3
4
ENTRYPOINT command param1 param2

# Which means the same as:
ENTRYPOINT ["sh", "-c, "command param1 param2"]

CMD

  1. exec form CMD
1
2
# preferred form
CMD ["executable", "param1", "param2"]
  1. shell form CMD
1
2
3
4
CMD command param1 param2

# Which means the same as:
CMD ["sh", "-c, "command param1 param2"]
  1. exec parameter form CMD
1
2
3
4
5
CMD ["param1", "param2"]


# Which means the same as:
ENTRYPOINT ["executable", "param1","param2"]

Diferences between exec form and shell form

The shell form prevents any CMD or run command line arguments from being used, but has the disadvantage that your ENTRYPOINT will be started as a subcommand of /bin/sh -c, which does not pass signals. This means that the executable will not be the container’s PID 1 - and will not receive Unix signals - so your executable will not receive a SIGTERM from docker stop <container>.

Unlike the shell form, the exec form does not invoke a command shell. This means that normal shell processing does not happen. For example, CMD [ "echo", "$HOME" ] will not do variable substitution on $HOME. If you want shell processing then either use the shell form or execute a shell directly, for example: CMD [ "sh", "-c", "echo $HOME" ]. When using the exec form and executing a shell directly, as in the case for the shell form, it is the shell that is doing the environment variable expansion, not docker.

When used in the shell or exec formats, the CMD instruction sets the command to be executed when running the image.

To sumarize:

  • shell form runs your command as a subcommand of shell /bin/sh -c, which prevents your command to receive system signals.
  • exec form runs your commnad directly without a shell enviroment, which means system signals can be received but shell enviroment variables such as $HOME won’t be substituted.

CMD and ENTRYPOINT combination

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.

  2. ENTRYPOINT should be defined when using the container as an executable.

  3. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.

  4. CMD will be overridden when running the container with alternative arguments.

entrypoint-and-cmd

Reference