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,其自述文件包含重现我所见内容的所有说明。但基本上:
- 我将 Web 应用构建到 jar 中
- 运行
docker build -t bootup .
成功
- 运行
docker run -it -p 9200:9200 -d --name bootup bootup
然后容器似乎启动得很好,下面的 docker ps
输出就是证据
- 但是,当我将浏览器指向
http://localhost:9200
时,我什么也没得到
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
已关闭).
谁能看出我哪里出错了?
更新:
我在主机上 运行 curl
、netstat
和 lsof
:
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
然后它就完美地工作了。
但是我也注意到一些防火墙和辅助功能选项也需要许可。
希望对你有所帮助。
我是第一次尝试 Docker,我正在尝试在 Docker 容器中将 Spring 启动网络应用程序 运行。我正在构建应用程序(将其打包到 self-contained jar 中)然后 然后 将其添加到 Docker 图像(这就是我想要的)。
您可以找到我的 SSCCE at this Bootup repo on GitHub,其自述文件包含重现我所见内容的所有说明。但基本上:
- 我将 Web 应用构建到 jar 中
- 运行
docker build -t bootup .
成功 - 运行
docker run -it -p 9200:9200 -d --name bootup bootup
然后容器似乎启动得很好,下面的docker ps
输出就是证据 - 但是,当我将浏览器指向
http://localhost:9200
时,我什么也没得到
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
已关闭).
谁能看出我哪里出错了?
更新:
我在主机上 运行 curl
、netstat
和 lsof
:
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
假设您使用的是 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连接就解决了
先到这里:
并找到标有:
的实际机器的适配器eth0
在我注意到设置后,它最初是 NAT,所以我改为桥接,然后
我能够使用它的地址与本地主机。
在我使用public地址后我使用了:
curl -i [bridged_ip_address_here]:9200
然后它就完美地工作了。
但是我也注意到一些防火墙和辅助功能选项也需要许可。
希望对你有所帮助。