What purpose does using exec in docker entrypoint scripts serve?

For example in the redis official image:

https://github.com/docker-library/redis/blob/master/2.8/docker-entrypoint.sh

  • Enable etcd service auto start in CoreOS via systemd
  • Docker image size not matching the container size after a commit
  • use nvidia-docker from docker-compose
  • openshift v3 pod file not found
  • “Filename too long” in sbt assembly inside a docker container
  • Default arguments in Docker
  • #!/bin/bash
    set -e
    
    if [ "$1" = 'redis-server' ]; then
        chown -R redis .
        exec gosu redis "$@"
    fi
    
    exec "$@"
    

    Why not just run the commands as usual without exec preceding them?

  • docker-compose does not launch
  • Error when running application at the container -Docker
  • Iterate in RUN command in Dockerfile
  • Creating a docker-compose with PHP drivers for mongo+memcache+ES
  • Dockerize Eclipse Plugin
  • Setting up the docker api - modification of docker.conf
  • 3 Solutions collect form web for “What purpose does using exec in docker entrypoint scripts serve?”

    As @Peter Lyons says, using exec will replace the parent process, rather than have two processes running.

    This is important in Docker for signals to be proxied correctly. For example, if Redis was started without exec, it will not receive a SIGTERM upon docker stop and will not get a chance to shutdown cleanly. In some cases, this can lead to data loss or zombie processes.

    If you do start child processes (i.e. don’t use exec), the parent process becomes responsible for handling and forwarding signals as appropriate. This is one of the reasons it’s best to use supervisord or similar when running multiple processes in a container, as it will forward signals appropriately.

    Without exec, the parent shell process survives and waits for the child to exit. With exec, the child process replaces the parent process entirely so when there’s nothing for the parent to do after forking the child, I would consider exec slightly more precise/correct/efficient. In the grand scheme of things, I think it’s probably safe to classify it as a minor optimization.

    without exec

    • parent shell starts
    • parent shell forks child
      • child runs
      • child exits
    • parent shell exits

    with exec

    • parent shell starts
    • parent shell forks child, replaces itself with child
    • child program runs taking over the shell’s process
    • child exits

    Think of it as an optimization like tail recursion.

    If running another program is the final act of the shell script, there’s not much of a need to have the shell run the program in a new process and wait for it. Using exec, the shell process replaces itself with the program.

    In either case, the exit value of the shell script will be identical1. Whatever program originally called the shell script will see an exit value that is equal to the exit value of the exec`ed program (or 127 if the program cannot be found).

    1 modulo corner cases such as a program doing something different depending on the name of its parent.

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.