向Docker

时间:2015-10-27 22:26:23

标签: go docker boot2docker dockerfile

我正在尝试在docker容器中运行用golang编写的服务器。例如:

package main

import "net/http"

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

如果我在本地计算机上运行此代码,我可以使用 Ctrl-C 向其发送SIGINT,它将关闭应用程序。当我在docker容器中运行它时,我似乎无法用 Ctrl-C 杀死它。

# 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

然后我继续使用docker向容器发送信号。

docker kill --signal=INT 9354f574afd4

还在跑...

docker kill --signal=TERM 9354f574afd4

还在跑...

docker kill --signal=KILL 9354f574afd4

终于死了。

我没有在我的代码中捕获任何信号而忽略它们。我甚至尝试增加上面的代码来捕获信号并打印出来(这些信号在我的主机上运行,​​但是当它在容器中时,就像信号从未进入程序一样)。

以前有没有人经历过这个?我还没有用另一种语言尝试这样的东西,但是我能够使用 Ctrl-C 杀死服务器(例如mongonginx)。在一个码头工人的容器中..为什么没有获得信号?

不确定这是否有所不同,但我使用的是OSX并使用docker-machine。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:6)

您正在shell中运行服务器,而shell是接收信号的进程。在强制shell退出之前,您的服务器不会退出。

当您使用CMD的“shell”形式时,它会将您的服务器作为/bin/sh -c的参数启动。为了直接执行服务器二进制文件,您需要为CMD或ENTRYPOINT提供一个参数数组,从可执行文件的完整路径开始。

CMD ["/go/bin/simple_server"]

Dockerfile docs中的ENTRYPOINT注释:

  

shell窗体阻止使用任何CMD或运行命令行参数,但缺点是ENTRYPOINT将作为/ bin / sh -c的子命令启动,它不传递信号。