Docker端口未公开

时间:2016-02-15 16:36:15

标签: networking docker port

我在Docker中设置了一个简单的节点服务器。

Dockerfile

FROM node:latest
RUN apt-get -y update
ADD example.js .
EXPOSE 1337   
CMD node example.js

example.js

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');

现在构建图像

$ docker build -t node_server .

现在在容器中运行

$ docker run -p 1337:1337 -d node_server  
$ 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70

验证容器是否正在运行并且端口已映射:

$ docker ps  

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
5909e87302ab        node_server         "/bin/sh -c 'node exa"   7 seconds ago       Up 6 seconds        0.0.0.0:1337->1337/tcp   grave_goldberg

现在让我们连接到容器并验证服务器是否在内部运行:

$ docker exec -it 5909e87302ab7520884060437e19ef543ffafc568419c04630abffe6ff731f70 /bin/bash 

在容器命令行中输入:

root@5909e87302ab:/# curl http://localhost:1337
Hello World
Mon Feb 15 2016 16:28:38 GMT+0000 (UTC)

看起来不错?

问题

当我在主机上执行相同的curl命令(或使用我的浏览器导航到http://localhost:1337)时,我什么都没看到。

任何想法为什么容器和主机之间的端口映射都不起作用?

我已经尝试过的事情:

  • 使用--expose 1337标志
  • 运行

2 个答案:

答案 0 :(得分:60)

您的端口正确暴露,但您的服务器正在侦听容器内127.0.0.1上的连接:

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'+new Date);
}).listen(1337, '127.0.0.1');

您需要像这样运行服务器:

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n'+new Date);
}).listen(1337, '0.0.0.0');

请注意0.0.0.0而不是127.0.0.1。

答案 1 :(得分:23)

  

将EXPOSE 1337添加到泊坞窗文件

EXPOSE强制如果你想"暴露"那个端口到其他容器。

作为BMitch评论:

  

Expose不需要发布端口或通过共享的docker网络将容器连接到容器。
  它是使用-P发布所有端口并检查图像/容器的元数据。

所以:

  

使用--expose 1337标志

运行

不完全是:您需要docker run with -p 1337:1337

您需要:

  • 使用EXPOSE指令构建一个图像(由-P使用)
  • 使用在主机-p 1337:1337
  • 上发布的端口运行它

测试curl http://localhost:1337是在容器内完成的(无EXPOSE或需要发布) 如果您希望它在Linux主机上运行,​​则需要EXPOSE+-P ,您需要-p 1337:1337

声明单独曝光有助于记录意图,但不会单独执行任何操作。

例如:

https://i.stack.imgur.com/wmKgd.png

在该图中,8080是EXPOSE' d,发布到Linux主机8888 如果该Linux主机不是实际主机,则需要将相同的端口快速发送到实际主机。请参阅" How to access tomcat running in docker container from browser?"。

如果localhost无法在Linux主机上运行,​​请尝试使用其IP地址:

CID=$(docker run -p 1337:1337 -d node_server)
CIP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${CID})
curl http://${CIP}:1337

或者,如上所述,让您的服务器监听来自任何IP的连接:0.0.0.0 the broadcast address or zero network