Mac 主机不喜欢 Docker 容器端口转发

Mac host doesn't like Docker container port forwarding

我是第一次尝试 Docker,我正在尝试在 Docker 容器中将 Spring 启动网络应用程序 运行。我正在构建应用程序(将其打包到 self-contained jar 中)然后 然后 将其添加到 Docker 图像(这就是我想要的)。

您可以找到我的 SSCCE at this Bootup repo on GitHub,其自述文件包含重现我所见内容的所有说明。但基本上:

docker ps 输出:

CONTAINER ID        IMAGE               COMMAND                  CREATED
a8c4ee64a1bc        bootup              "/bin/sh -c 'java -ja"   2 days ago

STATUS              PORTS                    NAMES
Up 12 seconds       0.0.0.0:9200->9200/tcp   bootup

Web 应用程序 configured to run on port 9200 不是 Java 默认值 8080。您可以通过 运行ning docker 之外的应用程序(因此,仅在您的主机本地)由 运行ning ./gradlew clean build && java -jar build/libs/bootup.jar.

据我所知,我的主机上没有防火墙 运行ning 会阻塞端口(我在 Mac 10.11.5 上并验证 System Preferences >> Security & Privacy >> Firewall 已关闭).

谁能看出我哪里出错了?


更新:

我在主机上 运行 curlnetstatlsof

HOST:
curl http://localhost:9200
curl: (52) Empty reply from server

netstat -an | grep 9200
tcp6       0      0  ::1.9200               *.*                    LISTEN     
tcp4       0      0  *.9200                 *.*                    LISTEN 

lsof -n -i4TCP:9200 | grep LISTEN
com.docke 2578 myuser   19u  IPv4 <someHexNumber>      0t0  TCP *:wap-wsp (LISTEN)

然后 docker exec 进入容器和 运行 另一个 netstat:

CONTAINER:
netstat -an | grep 9200
bash: netstat: command not found

更新照片:

我的浏览器图片 (Chrome) 指向 http://localhost:9200:

源代码图片在http://localhost:9200:

Chrome 开发人员工具检查页面 http://localhost:9200 的图片:

Chrome 开发人员工具中 Network 选项卡的图片:

这到底是怎么回事?!?!? 根据消息来源,浏览器应该呈现我的 你好,来自 Dockerland! 留言就好了。从实际浏览器页面来看,好像是网络错误。根据 Chrome 开发者工具,我的应用程序返回各种 HTML/CSS/JS 内容,这些内容甚至 远程 我的应用程序(查看源代码,自己看看)!!!

Dockerfile 不会将 9200 暴露给守护进程。添加

EXPOSE 9200

ENTRYPOINT

之前的 Dockerfile

假设您使用的是 Docker 工具箱而不是测试版 ...

正确公开端口有 3 个步骤:

  • 使用 EXPOSE 8080 其中 8080 只是 Docker 文件
  • 中的一个端口号
  • docker 运行 命令中使用 -p 8080:8080
  • 确保在 Oracle Virtual Box 中设置端口转发,以便 boot2docker 机器能够接收来自端口 8080 的请求。

这适用于使用 Docker 工具箱的 Windows 和 OSX。 Linux 不使用 Oracle VirtualBox 运行 docker 所以那些主机不需要做第三点

要在这里添加另一个答案,因为我看到了与您发布的 Github 回购协议相关的内容:

所以该存储库是一个 spring 引导存储库,其中包含一个 application.yml 文件。

您的 Docker 文件如下所示:

FROM openjdk:8

RUN mkdir /opt/bootup

ADD build/libs/bootup.jar /opt/bootup
WORKDIR /opt/bootup
EXPOSE 9200
ENTRYPOINT java -jar bootup.jar

这是将构建的 jar 添加到图像中。如果我的理解是正确的,jar 不包含 application.yml 因为:

  • 它不是构建的一部分(gradle 只会打包 src/main)。它位于项目根文件夹
  • 未明确添加到 Docker

因此可以假设您的应用目前实际上 运行 在 8080(默认)上?

可以尝试的几个选项:

  • 尝试公开 8080 而不是 9200(或同时公开两者),看看是否有所不同?
  • 入口点命令可以附加端口--server.port=9200
  • 应该将 application.yml 文件添加到图像中(您可能需要添加参数以正确引用它)[ADD application.yml /opt/bootup,在第一个 ADD 命令之后]
  • 在 src/main/resources 中包含 application.yml 文件,以便 spring 引导可以自动获取它。

参考文献

Spring Boot reference documentation on the order of loading for external configuration

我 运行 你的回购协议在 Docker 1.12 上 OSX。

如果您仔细查看您的容器启动:

2016-08-29 20:52:31.028  INFO 5 --- [           main] o.eclipse.jetty.server.ServerConnector   : Started ServerConnector@47949d1a{HTTP/1.1}{0.0.0.0:8080}
2016-08-29 20:52:31.033  INFO 5 --- [           main] .s.b.c.e.j.JettyEmbeddedServletContainer : Jetty started on port(s) 8080 (http/1.1)

虽然 application.yml 和 Docker 文件都包含 9200,但应用程序开始于 8080

好消息!(适用于 MacOSx 10.15.7)

我发现了和你一样的问题,直接打开VirutalBox连接就解决了

先到这里:

更改为桥接然后登录到 VirtualBox

中的虚拟机

并找到标有:

的实际机器的适配器

eth0

在我注意到设置后,它最初是 NAT,所以我改为桥接,然后

我能够使用它的地址与本地主机。

在我使用public地址后我使用了:

curl -i [bridged_ip_address_here]:9200

然后它就完美地工作了。

但是我也注意到一些防火墙和辅助功能选项也需要许可。

希望对你有所帮助。