我无法通过发送中断信号来停止docker容器中的docker golang Web服务器。 我有以下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))
}
和Dockerfile:
FROM golang:1.11.4-alpine3.8
WORKDIR /go/src/server
COPY main.go main.go
CMD ["go", "run", "main.go"]
我建立了:
docker build -t goserver .
并运行图片:
docker run -p 1818:1818 goserver
此刻服务器正在运行。当我在控制台容器(和服务器进程)中按Ctrl + C组合键时,它仍在运行,并且停止的唯一方法是调用docker来执行此操作。 我想知道如何处理这种行为,以便在按Ctrl + C时服务器和容器停止。
Docker版本18.09.1
答案 0 :(得分:2)
您正在使用go run,因此会将信号发送到go工具,而不是服务器进程。您可以中断由go run
在外壳程序中启动的服务器,因为外壳程序中的ctrl+c
将信号发送到整个进程组。
每次启动容器时也没有理由编译可执行文件(随着程序扩展,这可能会产生更多开销)。创建映像时生成可执行文件的效率更高,并且可以直接执行服务器。
示例docker文件:
FROM golang:1.11.4-alpine3.8
WORKDIR /go/src/server
COPY main.go main.go
RUN go build
CMD ["./server"]
在这里看到一个类似的问题,其中进程是一个shell而不是go
工具:
答案 1 :(得分:1)
为了让docker run
将诸如SIGINT之类的信号转发到容器,您需要同时将--interactive
和--tty
标志传递到docker run
,它们通常缩短为-it
。
没有这些标志,信号就不会像您提到的那样转发:
$ docker run -p 1818:1818 goserver
^C
但是设置了标志后,信号将转发到容器,并且程序将退出,就像直接在shell中运行一样:
$ docker run -it -p 1818:1818 goserver
^Csignal: interrupt
$