用 server.listen 无法访问容器化节点服务器(端口,’127.0.0.1’)

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

文件夹

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标志运行
76872 次浏览

将 EXPOSE 1337添加到 docker 文件

如果您希望将该端口“公开”给其他容器,则 EXPOSE 强制性的

正如 贱人的评论:

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

所以:

使用 --expose 1337标志运行

不完全是: 你需要 去码头了-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 主机不是实际的主机,那么同样的端口需要快速转发到实际的主机。请看“ 如何从浏览器访问运行在 Docker 容器中的 tomcat?”。

如果 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,即 广播地址或零网络

您的端口正在正确地公开,但是您的服务器正在监听容器内 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。