node.js - Docker 不公开节点和 webpack 开发服务器的端口
问题描述
我有 MacOS High Sierra,我的目标是在没有安装节点的情况下在 macos 上运行节点 Web 应用程序(我想使用 docker 来完成)。该网络应用程序通常是 angular-webpack(编译 + 运行开发服务器)。
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 上包含 Angular 项目的目录在哪里。
这是文件/work/tmp/example.js中的示例应用程序(映射到容器中),其中的问题是可见的(但是它们的主要目标是找到 webpack 开发服务器的正确配置):
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
如果我-p 3002:3002
从run.cmd文件中删除浏览器响应更改为
127.0.0.1 拒绝连接。尝试:检查连接检查代理和防火墙
ERR_CONNECTION_REFUSED
我也尝试使用docker run --ip=127.0.0.1...
,但我收到消息
docker:来自守护程序的错误响应:仅在用户定义的网络上支持用户指定的 IP 地址。
当我尝试使用docker run --net=host ...
它不会改变任何东西
我还想提一下,当我运行mysql
图像时,docker run -p 3306:3306 ...
我可以正常工作(!)-所以问题可能出在node
图像上(?)
问题:
- 如何“解锁”容器中的 3002 端口以允许主机浏览器连接容器内的服务?
- 如何使用子域
subdomain.local:3002
? - 如何使用webpack devServer使用子域(在 angular 中使用)而不是上面
example.js
(我需要在不同的端口上运行许多 angular web 应用程序和单独的子域)?
解决方案
我认为这个问题可能与您指定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
在本地计算机上编辑文件。
推荐阅读
- vb6 - 如何在 VB6 中从 Flexgrid 编写 .ini 格式
- vim - 在每个匹配模式的行上运行一个 shell 命令
- google-apps-script - 只执行一次脚本
- angular - NgRx 存储选项卡的状态
- r - 基于重复 ID 的子集,如果 value 与后续行的另一列中的 value 重复
- rust - 为什么我不能在索引到不可变 Vec 后调用 borrow_mut()
? - ios - 展开可选值(由 data.withUnsafeBytes(_:) 返回)有时不适用于 guard let
- r - 回填面板数据集中的 NA 值
- curl - curl 给出响应 200,但 openssl s_client 在 ssl 握手后给出超时
- django - 将登录用户附加到基于类的表单和模型