【问题标题】:Docker publish not working correctly for golang applicationDocker 发布对于 golang 应用程序无法正常工作
【发布时间】:2015-07-09 02:09:00
【问题描述】:

我正在尝试通过 docker 运行 golang web server application(它试图运行由与 golang blog 相同的工具驱动的 go 博客)。它在没有 docker 的情况下运行良好,但如果我使用 docker 则无法给出任何响应。我不知道为什么会发生这种情况,因为对于更简单的go web application,相同的基于 docker 的方法效果很好。有关我使用的各种命令的输出,请参见下文。任何帮助将不胜感激。

docker pull maddyonline/gotutorial
docker run -d --publish 8080:8080 --name gotut maddyonline/gotutorial

81bc36e385286326a6d9f74322515a7b9748e493275c3426bcc6848a4589a7e7

docker ps

容器 ID 图像命令
创建状态端口名称 81bc36e38528 maddyonline/gotutorial “go-wrapper run” 20 秒前 上升 20 秒 0.0.0.0:8080->8080/tcp gotut

curl localhost:8080

curl: (52) 来自服务器的空回复

docker exec gotut curl localhost:8080
<!DOCTYPE html>
<html>
<head>

以及文件的其余部分

我使用的docker文件很简单。

FROM golang:onbuild
EXPOSE 8080

我在同一台服务器上用一个更简单的 golang 应用程序尝试了相同的 docker 文件。它有效。

docker pull maddyonline/gowebapp
docker run -d --publish 8080:8080 --name gowebapp maddyonline/gowebapp
curl localhost:8080/icecream

你好,我想我喜欢冰淇淋!

【问题讨论】:

  • 我需要查看 Go 代码,但我怀疑您绑定到 localhost 或 127.0.0.1 而不是 0.0.0.0。

标签: go docker


【解决方案1】:

我发现您当前的代码存在两个问题。

首先是你的main.go中的字符串localhost必须是0.0.0.0。问题是您已经告诉您的网络服务器只处理发送到localhost 的请求。由于 Docker 所做的网络重整,出现在您的网络服务器上的任何流量都不会在网络服务器上看起来好像它们被发送到 localhost。通过告诉您的网络服务器监听0.0.0.0,您实际上是在告诉它它不关心流量最初发送到哪里,它会接受所有流量。

var (
    httpFlag   = flag.String("http", "0.0.0.0:8080", "HTTP listen address") // <--- Here it the change. It's roughly line 25 of [main.go](https://github.com/maddyonline/gotutorial/blob/master/main.go#L25)
    originFlag = flag.String("origin", "", "web socket origin for Go Playground (e.g. localhost)")
    baseFlag   = flag.String("base", "", "base path for articles and resources")
)

第二个问题是由于您的导入路径与您从中扩展的onbuild Dockerfile 的预定目录结构冲突所致。我看到您正在尝试对导入路径进行硬编码,这不是一个好主意,但我认为这是您唯一的选择,因为 go-wrapper 的怪异被 onbuild Dockerfile 强加给您。最终,您应该让 docker build 过程在该容器中粘贴一个静态 Go 二进制文件。这将简化在容器中实际启动服务器的过程。

我没有在你的 Go 代码中弄乱你的路径,我认为你可以解决这个问题,但我确实抓住了上游 onbuild Dockerfile 并根据你的需要对其进行自定义。顺便说一句,如果您查看documentation 的onbuild Dockerfile,它实际上表示使用该Dockerfile 是个坏主意。 ;) 所以,我接受了他们的建议,这是我的港口:

FROM golang:1.4.2

RUN mkdir -p /go/src/github.com/maddyonline/gotutorial
WORKDIR      /go/src/github.com/maddyonline/gotutorial

ADD . /go/src/github.com/maddyonline/gotutorial
RUN go-wrapper download
RUN go-wrapper install

EXPOSE 8080
CMD ["go-wrapper", "run"]

您的其他示例服务器应用程序没有同样的问题,因为导入路径的指定方式与在此项目中的方式不同。基本上,它并不关心它在哪里,因为它的依赖项没有被硬编码到文件路径中。它使用正常的 Go 打包约定。

抱歉,这似乎是一个很大的变化,但我希望它至少可以帮助您推进您的项目。如果有什么不明白的地方请告诉我。

【讨论】:

  • 谢谢乔纳森!这是一个非常有帮助的回复。只需执行答案的第一步(将 localhost 更改为 0.0.0.0)就已经为我解决了问题。
  • 如果您不介意,请快速跟进问题。即使博客服务正确,博客也会启动一个网络套接字连接,但由于来源检查here而导致握手失败。
  • 具体来说,连接源主机和websocket源不匹配:0.0.0.0:8080, localhost:8080。有关如何解决此问题的任何建议(更新code in socket.go 除外)。
  • 是的,我也注意到了。我在想你可以设置一个 allow-origin CORS 标头来绕过它。更多信息MDN
  • 哦哦。 Dang,这是在您正在使用的 Go websockets 库中进行严格检查的。我不确定是否有办法在不更改该代码的情况下解决它。我原本以为是浏览器阻塞了请求。
猜你喜欢
  • 2014-04-28
  • 1970-01-01
  • 2020-09-06
  • 2020-05-14
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 2021-04-17
相关资源
最近更新 更多