【问题标题】:Docker not responding while running go server运行 go server 时 Docker 没有响应
【发布时间】:2019-01-19 13:55:02
【问题描述】:

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

【问题讨论】:

标签: docker go


【解决方案1】:

您正在使用 go run,因此您将信号发送到 go 工具,而不是您的服务器进程。您可以在 shell 中中断go run 启动的服务器,因为 shell 中的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

【讨论】:

  • 感谢您的回答!现在我明白发生了什么。
【解决方案2】:

为了让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
$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-20
    • 2020-07-29
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多