简体   繁体   English

Docker - 为什么这个带有公开/发布端口的express.js容器拒绝连接? (使用boot2docker)

[英]Docker - Why is this express.js container with an exposed/published port reject connections? (using boot2docker)

I have a simple hello world express.js application inside of a docker container. 我在docker容器中有一个简单的hello world express.js应用程序。 It's set to run on port 8080 and the docker file exposes this port in the image. 它设置为在端口8080上运行,并且docker文件在映像中公开此端口。 Additionally, I publish the port when I run the image. 另外,我在运行图像时发布了端口。 Yet when I try to make a simple curl request, the connection is rejected. 然而,当我尝试做一个简单的curl请求时,连接被拒绝。 Here's how I've setup this test: 以下是我设置此测试的方法:

My Dockerfile is pretty simple: 我的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" ]

And inside my ./src directory I have a server.js file that looks like this: 在我的./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);
});

as well as a basic package.json which looks like this: 以及一个基本的package.json ,它看起来像这样:

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

The image builds just fine: 图像构建得很好:

→ 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

And starts just fine: 并开始很好:

→ 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          

I can confirm the server is running inside the container: 我可以确认服务器在容器内运行:

→ docker logs ee5024d16a67
Listening on port 8080

But if I attempt to make a request the connection is refused. 但是,如果我尝试提出请求,则拒绝连接。

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

Is there something I'm missing here? 这里有什么我想念的吗? If I run the application without using docker it works as expected: 如果我在不使用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

I found out the source of confusion. 我发现了混乱的根源。 My machine is running on Mac OSX and thus I installed docker with boot2docker . 我的机器在Mac OSX上运行,因此我用boot2docker安装了docker

So again repeating the process: 所以再次重复这个过程:

→ 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   

Finally, the trick was not to connect to my own machine but to curl from the VM's IP address: 最后,诀窍不是连接到我自己的机器,而是从VM的IP地址卷曲:

→ boot2docker ip

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

So I had finally achieved success when I curled the VM: 所以当我卷起虚拟机时,我终于取得了成功:

→ 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

This is all explained well in detail on Docker's installation guide but I missed it as it was towards the end of the document. 在Docker的安装指南中对此进行了详细解释,但我错过了它,因为它是在文档末尾。

After exposing the port in your dockerfile you also have to tell Docker how to map from your host system to your container. 暴露dockerfile中的端口后,您还必须告诉Docker如何从主机系统映射到容器。

Try changing your Docker run command to something like this: 尝试将Docker run命令更改为以下内容:

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

Then try: curl'ing: 然后尝试:curl'ing:

curl -i 127.0.0.1:49158

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM