dockergograceful-shutdown

Is it safe to shutdown go application running inside a container this way on `docker kill --signal=SIGX`?


Context

There is an app running inside docker container. When docker stop %container_id% is sent the container receives SIGTERM. This signal is handled inside golang application via executing cleanup code before exiting. In this case code is a single log statement before exiting.

Questions

  1. Is it guaranteed that container won't cease to exist before this statement is executed?
  2. If yes does it apply to other signals?
  3. If no are there signals to which this do apply?
func main() {
    http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(rw, "chirtkem mudila")
    })

    go func() {
        if err := http.ListenAndServe(":8080", nil); err != nil {
            log.Fatal(err)
        }
    }()

    interupt := make(chan os.Signal, 1)
    signal.Notify(interupt, syscall.SIGTERM, syscall.SIGINT)
    <-interupt

    log.Println("graceful shutdown") // is it guaranteed to execute before container ceases to exist?
}

Solution

  • In case of docker stop %container_id% docker sends SIGTERM and waits for timeout, default 10 seconds, and sends a SIGKILL.

    This timeout is configurable with --time option, docs

    Usage:  docker stop [OPTIONS] CONTAINER [CONTAINER...]
    Stop one or more running containers
    Options:
      -t, --time int   Seconds to wait for stop before killing it (default 10)
    

    Thus (1) it is not guaranteed that the container will be alive during completion of the statement, if the statement takes more than this time.

    For (2) and (3) As (1) is a no and docker stop has no override for signals, does not apply to other signals.

    docker kill has an override for signal, default being SIGKILL, with --signal flag. docs

    While the default (SIGKILL) signal will terminate the container, the signal set through --signal may be non-terminal, depending on the container’s main process. For example, the SIGHUP signal in most cases will be non-terminal, and the container will continue running after receiving the signal.

    Thus depending on the signal supplied in command, the container may or may not be killed after processing of signal.