Sending signals to Golang application in Docker

I am trying to run servers written in golang inside docker containers. For example:

package main

import "net/http"

func main() {
  http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello"))
  })
  http.ListenAndServe(":3000", nil)
}

If I run this code on my local machine, I can send it a SIGINT with Ctrl-C and it will close the application. When I run it inside a docker container, I can’t seem to kill it with Ctrl-C.

  • Docker/EC2: getting exclusive access to a port?
  • Docker toolbox volumes on windows doesn't refresh changes on container
  • How to create postgis extension for postgresql in docker?
  • docker private registry user creation
  • How critical is dumb-init for Docker?
  • Push Docker Repository to Dockerhub with Jenkins
  • # Dockerfile
    FROM ubuntu:14.04
    
    RUN apt-get update && apt-get -y upgrade
    RUN apt-get install -y golang
    
    ENV GOPATH /go
    
    COPY . /go/src/github.com/ehaydenr/simple_server
    
    RUN cd /go/src/github.com/ehaydenr/simple_server && go install
    
    CMD /go/bin/simple_server
    

    I then proceeded to use docker to send signals to the container.

    docker kill --signal=INT 9354f574afd4
    

    Still running…

    docker kill --signal=TERM 9354f574afd4
    

    Still running…

    docker kill --signal=KILL 9354f574afd4
    

    Finally dead.

    I’m not catching any signals in my code and ignoring them. I’ve even tried augmented the code above to catch signals and print them out (which works on my host, but when in the container, it’s as if the signals never got to the program).

    Has anyone experienced this before? I haven’t tried something like this in another language, but I able to kill servers (e.g. mongo, nginx) using Ctrl-C while they’re in a docker container.. Why isn’t Go be getting the signals?

    Not sure if this makes a difference, but I am on OSX and using docker-machine.

    Any help is much appreciated.

  • How can I upgrade Docker on a Mac?
  • Registering SIGINT/SIGQUIT signals in a Django application served in Docker
  • Unable to access jarfile when running Docker image
  • Dockerfile vs docker-compose.yml
  • docker pull through cache for private registry not working
  • How to monitor docker containers log from non-root user?
  • One Solution collect form web for “Sending signals to Golang application in Docker”

    You are running your server inside a shell, and the shell is the process receiving the signals. Your server doesn’t exit until you force the shell to quit.

    When you use the “shell” form of CMD, it starts your server as an argument to /bin/sh -c. In order to exec the server binary directly, you need to provide an array of arguments to either CMD or ENTRYPOINT, starting with the full path of the executable.

    CMD ["/go/bin/simple_server"]
    

    A note from ENTRYPOINT in the Dockerfile docs:

    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.

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