[英]Mac host doesn't like Docker container port forwarding
I am experimenting with Docker for the first time, and am trying to get a Spring Boot web app to run inside a Docker container.我第一次尝试使用 Docker,并试图让 Spring Boot Web 应用程序在 Docker 容器内运行。 I am building the app (which packages up into a self-contained jar) and then adding it to the Docker image (which is what I want).
我正在构建应用程序(将其打包到一个独立的 jar 中),然后将其添加到 Docker 映像中(这正是我想要的)。
You can find my SSCCE at this Bootup repo on GitHub , whose README has all the instructions to reproduce what I'm seeing.您可以在 GitHub 上的这个Bootup 存储库中找到我的SSCCE ,其 README 包含重现我所看到内容的所有说明。 But basically:
但基本上:
docker build -t bootup .
docker build -t bootup .
which succeedsdocker run -it -p 9200:9200 -d --name bootup bootup
and then container seems to start up just fine, as is evidence by the docker ps
output belowdocker run -it -p 9200:9200 -d --name bootup bootup
然后容器似乎启动得很好,下面的docker ps
输出就是证据http://localhost:9200
, I get nothinghttp://localhost:9200
,我什么也得不到docker ps
output: 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
The web app is configured to run on port 9200 , not the Java default of 8080. You can see this for yourself by running the app outside of docker (so, just locally on you host machine) by running ./gradlew clean build && java -jar build/libs/bootup.jar
. Web 应用程序配置为在端口 9200 上运行,而不是Java 默认的 8080 端口。您可以通过运行
./gradlew clean build && java -jar build/libs/bootup.jar
在./gradlew clean build && java -jar build/libs/bootup.jar
之外运行应用程序(因此,仅在您的主机上本地运行)亲眼看到这一点./gradlew clean build && java -jar build/libs/bootup.jar
。
To my knowledge, there is no Firewall running on my host that would be blocking ports (I am on Mac 10.11.5 and verified that System Preferences >> Security & Privacy >> Firewall
is turned off).据我所知,我的主机上没有运行会阻止端口的防火墙(我在 Mac 10.11.5 上并验证
System Preferences >> Security & Privacy >> Firewall
已关闭)。
Can anyone spot where I'm going awry?谁能发现我哪里出错了?
Updates:更新:
I ran a curl
, netstat
and lsof
on the host:我在主机上运行了
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)
And then docker exec
'd into the container and ran another netstat
:然后
docker exec
进入容器并运行另一个netstat
:
CONTAINER:
netstat -an | grep 9200
bash: netstat: command not found
Update w/ photos:更新照片:
Picture of my browser (Chrome) pointed to http://localhost:9200
:我的浏览器(Chrome)的图片指向
http://localhost:9200
:
Picture of the source code at http://localhost:9200
: http://localhost:9200
的源代码图片:
Picture of Chrome Developer Tools inspecting the page at http://localhost:9200
: Chrome 开发者工具在
http://localhost:9200
检查页面的图片:
Picture of the Network
tab in Chrome Developer Tools: Chrome 开发者工具中
Network
标签的图片:
What the heck is going on here?!?!?这到底是怎么回事?!?!? According to the source, the browser should be rendering my Well hello there, from Dockerland!
根据消息来源,浏览器应该从 Dockerland渲染我的“你好”! message just fine.
消息就好了。 According to the actual browser page, it looks like there is a networking error.
根据实际浏览器页面,貌似是网络错误。 And according to Chrome Developer Tools, my app is returning all sorts of HTML/CSS/JS content that is not even remotely apart of my app (check out the source code, see for yourself)!!!
而据Chrome开发人员工具,我的应用程序返回的各种HTML / CSS / JS内容的甚至不是远程开我的应用程序(检查出的源代码,看看自己)的!
The Dockerfile doesn't expose 9200 to the daemon. Dockerfile 不会向守护程序公开 9200。 Add
添加
EXPOSE 9200
to the Dockerfile before ENTRYPOINT
在 ENTRYPOINT 之前到
ENTRYPOINT
Assuming you are using Docker Toolbox and not the beta ...假设您使用的是 Docker Toolbox 而不是测试版......
There is a 3 step process for exposing a port properly:正确公开端口有 3 个步骤:
EXPOSE 8080
where 8080 is just a port number in the DockerfileEXPOSE 8080
,其中 8080 只是Dockerfile 中的一个端口号 This applies to both Windows and OSX where Docker Toolbox is being used.这适用于使用 Docker Toolbox 的 Windows 和 OSX。 Linux doesn't use Oracle VirtualBox to run docker so those hosts do not need to do the third point
Linux 不使用 Oracle VirtualBox 来运行 docker,所以那些主机不需要做第三点
I ran your repo as-is on Docker 1.12 on OSX.我在 OSX 上的 Docker 1.12 上按原样运行了你的 repo。
If you look carefully at your container startup:如果您仔细查看容器启动:
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)
Although application.yml
and Dockerfile both contain 9200
, the application is starting on 8080
虽然
application.yml
和 Dockerfile 都包含9200
,但应用程序在8080
上启动
Going to add another answer here because I saw something related to the Github Repo that you posted:在这里添加另一个答案,因为我看到了与您发布的 Github Repo 相关的内容:
So the repo is a spring boot repo with an application.yml file.所以这个 repo 是一个带有 application.yml 文件的 spring boot repo。
Your Dockerfile looks like this:您的 Dockerfile 如下所示:
FROM openjdk:8
RUN mkdir /opt/bootup
ADD build/libs/bootup.jar /opt/bootup
WORKDIR /opt/bootup
EXPOSE 9200
ENTRYPOINT java -jar bootup.jar
Which is adding the built jar to the image.这是将构建的 jar 添加到图像中。 If my understanding is correct, the jar does not include application.yml because:
如果我的理解是正确的,jar不包含 application.yml,因为:
So therefore one can assume that your app is actually running on 8080 (the default) at the moment?因此,您可以假设您的应用程序目前实际上在 8080(默认)上运行?
A couple of options that one could try:可以尝试的几种选择:
--server.port=9200
--server.port=9200
ADD application.yml /opt/bootup
, after first ADD
command]ADD
命令之后ADD application.yml /opt/bootup
] References参考文献
Spring Boot reference documentation on the order of loading for external configuration Spring Boot 参考文档关于外部配置的加载顺序
Good News!好消息! (for MacOSx 10.15.7)
(对于 MacOSx 10.15.7)
I found the same issue as you, and I was able to solve it by directly opening VirutalBox connection发现和你一样的问题,直接打开VirutalBox连接就解决了
Go here first:先到这里:
changed to bridged then logged into the virtual machine within VirtualBox
改成bridged然后登录VirtualBox内的虚拟机
And found the actual machine's adapter labeled:并发现实际机器的适配器标有:
eth0
after I noted the setting it was originally NAT so I changed to bridged and then在我注意到设置后,它最初是 NAT,所以我更改为桥接,然后
I was able to use its address vs. localhost.我能够使用它的地址与本地主机。
After I used the public address I used:使用公共地址后,我使用了:
curl -i [bridged_ip_address_here]:9200 curl -i [bridged_ip_address_here]:9200
it then worked flawlessly.然后它完美地工作。
However I also noticed some firewalls and accessibility options that needed permission as well.但是,我也注意到一些防火墙和可访问性选项也需要许可。
I pray this helps you.我祈祷这对你有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.