Persi
Persi

Reputation: 424

Docker not responding while running go server

I cannot stop docker golang web server in docker container by sending Interrupt Signal. I have following main.go:

package main

import (
    "log"
    "net/http"
)

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

And Dockerfile:

FROM golang:1.11.4-alpine3.8
WORKDIR /go/src/server
COPY main.go main.go
CMD ["go", "run", "main.go"]

I build:

docker build -t goserver .

and run image:

docker run -p 1818:1818 goserver

At this moment server is running. When I hit Ctrl+C in my console container (and server process) is still running and the only way to stop is by calling docker to do it. I would like to know how to handle such behaviour so that server and container stops when hitting Ctrl+C.

Docker version 18.09.1

Upvotes: 1

Views: 1340

Answers (2)

Mr_Pink
Mr_Pink

Reputation: 109442

You're using go run, so you're sending the signal to the go tool, not your server process. You can interrupt the sever started by go run in a shell, because ctrl+c in a shell sends the signal to the entire process group.

There's also no reason to compile the executable every time you start the container (which can incur much more overhead as your program expands). Building the executable when creating the image is more efficient, and lets you execute the server directly.

An example docker file:

FROM golang:1.11.4-alpine3.8
WORKDIR /go/src/server
COPY main.go main.go
RUN go build
CMD ["./server"]

See a similar question here, where the process is a shell rather than the go tool:

Sending signals to Golang application in Docker

Upvotes: 2

lmars
lmars

Reputation: 2532

In order for docker run to forward signals like SIGINT to the container, you need to pass both the --interactive and --tty flags to docker run, which are typically shortened to -it.

Without those flags, the signal isn't forward as you mention:

$ docker run -p 1818:1818 goserver
^C

With the flags set however, the signal is forwarded to the container and the program exits as it would do if run directly in a shell:

$ docker run -it -p 1818:1818 goserver
^Csignal: interrupt
$

Upvotes: 1

Related Questions