8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

容器化节点服务器无法通过 server.listen(port, '127.0.0.1') 访问

ProfDFrancis 2月前

79 0

我在Docker 中设置了一个简单的 Node 服务器。DockerfileFROM node:latestRUN apt-get -y updateADD example.js .EXPOSE 1337 CMD node example.jsexample.jsvar http = require('http');http.createSer...

我在 Docker 中建立了一个简单的 Node 服务器。

Dockerfile

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

例子.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 奔跑
帖子版权声明 1、本帖标题:容器化节点服务器无法通过 server.listen(port, '127.0.0.1') 访问
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由ProfDFrancis在本站《http》版块原创发布, 转载请注明出处!
最新回复 (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。

  • 监听 0.0.0.0 看起来很奇怪,它的含义不是立即显而易见的。但它似乎是默认的,因此您可以从 listen() 函数中省略该参数,我认为这更容易理解 nodejs.org/api/…

  • 监听 0.0.0.0 意味着“监听所有接口”。这通常是过度的,有时会造成安全问题,但通常无害。这在 Docker 容器中很有意义。

  • 非常感谢,此解决方案解决了在 docker 中运行的任何类型的服务器(如 java 或 node.js express 服务器)的问题。在任何情况下,接口都必须是:0.0.0.0,其中端口是使用 -P $PORT:$PORT/tcp 选项导出的端口,因此服务器通常会在运行时检查导出 HOST=0.0.0.0。

  • 非常感谢。我遇到了同样的问题,但使用 netty 时,我无法从容器外部访问它。有没有更好的方法来了解哪个网络接口容器边界,从而不使用 0.0.0.0?

  • Olaf 2月前 0 只看Ta
    引用 7

    这救了我一命!我刚刚意识到显然没有办法发布容器本地主机接口的端口。规则是 --publish [ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort]

  • 将 EXPOSE 1337 添加到 docker 文件

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

    正如 BMitch 评论的那样:

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

    所以:

    旗帜 --expose 1337 奔跑

    不完全是:你需要 使用 -p 1337:1337 with -p 1337:1337

    您需要:

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

    测试 curl http://localhost:1337 是在容器内部完成的(无需 EXPOSE 发布)。
    如果你希望它在 Linux 主机上运行,​​你需要 EXPOSE+-P 或者 你需要 -p 1337:1337 .
    任何一个。

    单独声明它公开有利于记录意图,但单独并不能做任何事情。

    例如:

    https://i.sstatic.net/wmKgd.png

    在该图中,8080 被 EXPOSE,发布到 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 广播地址或零网络 .

  • 感谢您的评论,但正如我上面提到的,我已经尝试添加 EXPOSE 1337,但它也不起作用

  • 谢谢,当然,我尝试了这两种方法。即:使用 EXPOSE 1337 构建并使用 -p 1337:1337 运行,仍然没有结果。我修改了问题以反映这一点。

  • Dockerfile 中的 EXPOSE 完全没有必要。它纯粹用作文档。这是一个好主意,可以表明意图,但也容易引起误解,因为它什么也不做。它也可能是一个注释。

返回
作者最近主题: