March 18, 2017

Docker Default Executable

Docker Default Executable

A Default Executable is the command that will run when the container is started. It is defined in the Dockerfile as an ENTRYPOINT or CMD instruction. CMD and ENTRYPOINT instructions both define the startup command for a container. You can enter one or the other, or both in the Dockerfile.
  • This example runs the debian container and starts a shell. The default executable, the shell, is defined in the Dockerfile as a default executable.
  • If a default executable is not specified in the Dockerfile and an argument is not given at the command line, the container will error out when called:

  • The above error can be remedied by entering the starting command at the command line. In this example, the shell, sh, is given as the starting command:
  • Entry Point instruction
  • An ENTRYPOINT allows you to configure a container to behave as it were the configured default executable. It is typically used when you don't expect the user to override the executable in the ENTRYPOINT instruction.
    • Application runs as PID 1
    • ENTRYPOINT gives a container its default nature or behavior, i.e. the container will always run the command given in the ENTRYPOINT instruction, unless overridden at the command line with the --entrypoint option.
    • In the exec form, ENTRYPOINT can be used to define the default command and arguments. Optionally CMD can be added to supply optional arguments. CMD arguments can be overridden with command line arguments, e.g. an image built from the following Dockerfile:
    • FROM ubuntu
      ENTRYPOINT ["top", "-b"]
      CMD ["-n 2"]
      will run the command top -b -n 2. The CMD instruction can be overridden by specifying an argument at the command line, e.g. $ docker run top -n 4 will run top -b -n 4 instead.
    • In the exec form, command line arguments, e.g. $ docker run will append to, NOT override the ENTRYPOINT instruction.
      • With the following Dockerfile:
      • FROM debian
        ENTRYPOINT ["top","-n 1"]
      • Build an image, tagged with the name top and version 1:
      • With the defined ENTRYPOINT, you can run the container as $ docker run --rm -t top:1:
      • You can override the ENTRYPOINT instruction with the --entrypoint option:

      The above example runs ping -c 1 in the container, instead of top -n 1 specified in the Dockerfile. Note: command ping is specified with --entrypoint, and the rest is given as an argument in the command line.
    • If there are multiple ENTRYPOINT instructions in the Dockerfile, only the last one will have an effect.
    • In the EXEC form, the default executable is run directly by the kernel without a parent shell. As a result, it runs with a process ID (PID) of 1. And in Linux, if a process with PID 1 is terminated, the operating system is also terminated.
    • A SIGTERM signal (or issuing CTRL-C)  sent to the docker container will be passed to the default executable. As this is running as PID 1 in the Linux kernel, the application is terminated and the container is stopped
  • CMD (Command) Instruction
    • Specified as CMD in the Dockerfile, e.g. CMD ["/bin/bash"]
    • The command (is started as a subcommand of a shell, /bin/sh -c, as such it) does NOT run under PID 1 in the shell
    • In this form, the command is prepended with /bin/sh -c:
    • "Cmd": [
                      "#(nop) ",
                      "CMD [\"/bin/bash\"]"
    • The CMD instruction allows the default executable to be overridden at the command line:

    • In the above example, the default executable of the debian image is bash -- we know that by looking at its Dockerfile. With the command above, bash, default executable is overridden at the command line with ls -Fs. The container runs this command and exits.
    • As it's easier to override the CMD instruction at the command line, the recommendation is to use CMD instead of ENTRYPOINT in your Dockerfile when you want flexibility in choosing a container command at runtime.
  • Exec vs Shell Form
    • Both CMD and ENTRYPOINT instructions support two forms: exec and shell.
    • Arguments in the shell form is space-delimited, executable param1 param2:, e.g. CMD ps -ef:
    • FROM debian
      CMD ps -ef
      Build the above Dockerfile, e.g. $ docker build -t pscmd . and run it:

      Note: the process running as PID 1 is the shell, /bin/sh, as opposed to the default executable, ps -ef, . There are two consequences of this:
      • the image now must include a shell layer, increasing its size
      • it is more difficult to kill the container by sending a POSIX signal. The signal gets intercepted by the shell as opposed to the default executable, ps.
    • Arguments in the exec form are formatted as a JSON array, ["executable","param1","param2"], e.g.
    • FROM debian
      CMD ["ps", "-ef"]
      Build the above Dockerfile, e.g. $ docker build -t psexec . and run it:

      Note: the process running as PID 1 is the default executable, ps -ef.
      Here's another example of the exec form, this time with the ENTRYPOINT instruction:
      FROM debian
      ENTRYPOINT ["/bin/ping","","-c 1"]
      Build the above Dockerfile, e.g. $ docker build -t pingexec . and run it:

      When run, the pingexec container pings once and exits.

No comments:

Post a Comment