Docker不公开节点和Webpack开发服务器的端口

时间:2018-08-08 14:42:57

标签: node.js docker webpack server port

我有MacOS High Sierra,我的目标是在macOS上运行没有安装节点的节点Web应用程序(我想使用docker来做到这一点)。该Web应用程序通常是angular-webpack(编译+运行dev serwer)。

Dockerfile

FROM node
WORKDIR /work
CMD while true; do sleep 10000; done
EXPOSE 3002

CMD while ...使该容器在运行后不会被docker杀死-这使我们可以“登录”到容器(由docker exec -it...登录)。

运行容器的Bash脚本 run.cmd

set -e
docker build -t node-cmd .
docker rm -f node-cmd |:
docker run -d --name node-cmd -p 3002:3002 -v /Volumes/work:/work node-cmd
docker exec -it node-cmd /bin/bash

/Volumes/work是我的MacO上的目录,其中包含有角项目。

以下是文件 /work/tmp/example.js 中的示例应用程序(映射在容器中),对于该应用程序可见问题(但是,它们的主要目标是找到正确的webpack dev-server配置) :

var http = require('http');

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

console.log('Server running at http://127.0.0.1:3002/');

所以我首先运行run.cmd-这是docker ps的写法:

CONTAINER ID        IMAGE               COMMAND                   CREATED             STATUS              PORTS                    NAMES
e22188d8e136        node-cmd            "/bin/sh -c 'echo \"R…"   16 seconds ago      Up 15 seconds       0.0.0.0:3002->3002/tcp   node-cmd

在内部容器中键入命令:

root@5cd3773e7815:/work# cd tmp
root@5cd3773e7815:/work# node example.js & 
[1] 18
root@5cd3773e7815:/work/tmp# Server running at http://127.0.0.1:3002/

所以服务开始了。现在我测试:

root@5cd3773e7815:/work/tmp# curl 127.0.0.1:3002
Hello World

因此在docker内部,一切正常。现在,当我使用macOS Chrome浏览器http://127.0.0.1:3002时,我会得到

  

此页面无法正常工作127.0.0.1没有发送任何数据。

     

ERR_EMPTY_RESPONSE

如果我从 run.cmd 文件中删除了-p 3002:3002,则浏览器响应更改为

  

127.0.0.1拒绝连接。尝试:检查连接检查代理和防火墙

     

ERR_CONNECTION_REFUSED

我也尝试使用docker run --ip=127.0.0.1...,但收到消息

  

docker:来自守护程序的错误响应:用户指定的IP地址为   仅在用户定义的网络上受支持。

当我尝试使用docker run --net=host ...时并没有改变

我也想提一提,当我运行mysql的{​​{1}}图像时,我工作正常(!)-可能是docker run -p 3306:3306 ...图像(?)的问题了

问题:

  1. 如何“解锁”容器中的端口3002以允许主机浏览器与容器中的服务连接?
  2. 如何也使用node之类的子域?
  3. 如何在subdomain.local:3002上方使用 webpack devServer (以角度使用)而不是在example.js上方使用子域(我需要在每个具有单独子域的不同端口上运行许多有角度的Web应用程序)?< / li>

2 个答案:

答案 0 :(得分:2)

我认为此问题可能与您将127.0.0.1指定为主机这一事实有关。尝试改用0.0.0.0

var http = require('http');

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

对于子域,您很可能必须在本地计算机上编辑/etc/hosts文件。

答案 1 :(得分:2)

Rob帮助我找到问题的主要解决方案。我进行了测试和调查,发现当我们设置.listen(3002, '0.0.0.0')并通过添加

这样的行来编辑/etc/hosts时,
127.0.0.1 node-test.local

当我们在浏览器node-test.local:3002中键入内容时,它将起作用。但是,如果我们使用webpack dev starter,则在浏览器中会出现错误:

  

无效的主机标头

因此,我们需要通过添加./config/webpack.dev.js重新配置webpack.js文件(例如,在disableHostCheck: true中的angular-starter framework ASF 中)-这是配置:

devServer: {
  port: "3002",            // in ASF is METADATA.port,
  host: "0.0.0.0",         // in ASF is METADATA.host,     
  public: "0.0.0.0:3002",  // in ASF is METADATA.public,
  disableHostCheck: true,
  //...
}

之后,http://node-test.local:3002应该可以在MacOs浏览器上使用。

如果我们需要在一个端口号上包含多个子域(这不在本问题的框架之内),则可能我们必须使用reverse-proxy(这可能是端口上的docker multi-webapps(子域)的标准解决方案80)