Docker在运行Go Server时没有响应

时间:2019-01-19 13:55:02

标签: docker go

我无法通过发送中断信号来停止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

2 个答案:

答案 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工具:

Sending signals to Golang application in Docker

答案 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
$