Docker – 为什么这个express.js容器有一个暴露/发布的端口拒绝连接? (使用boot2docker)

在Docker容器中有一个简单的hello world express.js应用程序。 它被设置为在端口8080上运行,docker文件在图像中公开这个端口。 此外,我运行映像时发布端口。 然而,当我试图做一个简单的curl请求,连接被拒绝。 以下是我如何设置这个testing:

我的Dockerfile非常简单:

FROM node ADD ./src /src WORKDIR /src # install your application's dependencies RUN npm install # replace this with your application's default port EXPOSE 8080 # replace this with your main "server" script file CMD [ "node", "server.js" ] 

而在我的./src目录中,我有一个如下所示的server.js文件:

 var express = require('express'); var app = express(); app.get('/', function(req, res){ res.send('Hello World'); }); var server = app.listen(8080, function() { console.log('Listening on port %d', server.address().port); }); 

以及一个基本的package.json ,看起来像这样:

 { "name": "hello-world", "description": "hello world test app", "version": "0.0.1", "private": true, "dependencies": { "express": "4.7.2" } } 

图像生成得很好:

 → docker build -t jimjeffers/hello-world . Sending build context to Docker daemon 1.126 MB Sending build context to Docker daemon Step 0 : FROM node ---> 6a8a9894567d Step 1 : ADD ./src /src ---> 753466503fbf Removing intermediate container 135dab70dfff Step 2 : WORKDIR /src ---> Running in 12257ff3f990 ---> 010ce4140cdc Removing intermediate container 12257ff3f990 Step 3 : RUN npm install ---> Running in 1a9a0eb9d188 ---> 5dc97c79281e Removing intermediate container 1a9a0eb9d188 Step 4 : EXPOSE 8080 ---> Running in abbaadf8709d ---> 9ed540098ed2 Removing intermediate container abbaadf8709d Step 5 : CMD [ "node", "server.js" ] ---> Running in 63b14b5581cd ---> eababd51b50e Removing intermediate container 63b14b5581cd Successfully built eababd51b50e 

并开始很好:

 → docker run -P -d jimjeffers/hello-world ee5024d16a679c10131d23c1c336c163e9a6f4c4ebed94ad4d2a5a66a64bde1d → docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ee5024d16a67 jimjeffers/hello-world:latest node server.js About an hour ago Up 11 seconds 0.0.0.0:49158->8080/tcp jovial_engelbart 5d43b2dee28d mongo:2.6 /usr/src/mongo/docke 5 hours ago Up 3 hours 27017/tcp some-mongo 

我可以确认服务器正在容器内运行:

 → docker logs ee5024d16a67 Listening on port 8080 

但是,如果我尝试提出请求,连接将被拒绝。

 → curl -i 0.0.0.0:49158 curl: (7) Failed connect to 0.0.0.0:49158; Connection refused 

有什么我在这里失踪? 如果我不使用docker运行应用程序,它按预期工作:

 → node src/server.js Listening on port 8080 → curl -i 0.0.0.0:8080 HTTP/1.1 200 OK X-Powered-By: Express Content-Type: text/html; charset=utf-8 Content-Length: 11 ETag: W/"b-1243066710" Date: Mon, 04 Aug 2014 05:11:58 GMT Connection: keep-alive Hello World 

我发现混乱的根源。 我的机器在Mac OSX上运行,因此我使用boot2docker安装了docker 。

所以再次重复这个过程:

 → docker run -P -d jimjeffers/hello-world 28431b32b93dbecaa2a8a5b129cbd36eebe8a90f4c20ab10735455d82fa9de37 → docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 28431b32b93d jimjeffers/hello-world:latest node server.js 2 hours ago Up 9 minutes 0.0.0.0:49159->8080/tcp stoic_franklin 5d43b2dee28d mongo:2.6 /usr/src/mongo/docke 6 hours ago Up 4 hours 27017/tcp some-mongo 

最后,诀窍是不要连接到我自己的机器,而是从虚拟机的IP地址卷起:

 → boot2docker ip The VM's Host only interface IP address is: 192.168.59.103 

所以当我蜷缩虚拟机时,我终于取得了成功:

 → curl -i 192.168.59.103:49159 HTTP/1.1 200 OK X-Powered-By: Express Content-Type: text/html; charset=utf-8 Content-Length: 11 ETag: W/"b-1243066710" Date: Mon, 04 Aug 2014 04:32:37 GMT Connection: keep-alive 

这在Docker的安装指南中有很详细的解释,但是在文档结尾时我错过了。

在Docker文件中公开端口之后,您还必须告诉Docker如何从主机系统映射到容器。

尝试改变你的Docker运行命令是这样的:

docker run -p 127.0.0.1:49158:8080 -d jimjeffers/hello-world

然后尝试:curl'ing:

curl -i 127.0.0.1:49158