Docker 容器中的节点 http-proxy
Node http-proxy in Docker container
我有以下代码在我的本地环境中运行良好。但是,当我尝试从 Docker 容器(通过 Boot2Docker)运行 相同的代码时,我根本无法到达 https://[boot2docker_ip]:4000
我尝试使用所有这些选项更新下面代码中的目标值,但其中 none 似乎可以解决问题:
target: 'http://localhost:3000',
target: 'http://0.0.0.0:3000',
target: 'http://127.0.0.1:3000',
target: 'http://<boot2docker_ip>:3000',
var fs = require('fs');
require('http-proxy').createProxyServer({
ssl: {
key: fs.readFileSync(__dirname + '/certs/ssl.key', 'utf8'),
cert: fs.readFileSync(__dirname + '/certs/ssl.crt', 'utf8')
},
target: 'http://localhost:3000',
ws: true,
xfwd: true
}).listen(4000);
我正在使用来自 https://github.com/nodejitsu/node-http-proxy
的 node-http-proxy
包
编辑
这里有一个 Git repo 来尝试这种行为;为了简单起见,我检查了伪造的 SSL。
Docker文件:
FROM readytalk/nodejs
ADD ./src /app
ADD ./ssl-proxy /proxy
COPY ./run.sh /run.sh
RUN chmod +x /run.sh
EXPOSE 3000
EXPOSE 4000
ENTRYPOINT ["/run.sh"]
run.sh:
#!/bin/sh
/nodejs/bin/node /app/main.js; /nodejs/bin/node /proxy/main.js
我刚刚查看了您的 Dockerfile,尤其是您使用的 run.sh
脚本。此行来自您的 run.sh
脚本:
/nodejs/bin/node /app/main.js; /nodejs/bin/node /proxy/main.js
这里要知道的重要一点是,这些命令中的每一个都会启动一个长期 运行ning 服务器进程,(理论上)永远 运行s。这意味着第二个进程 (/proxy/main.js
) 永远不会启动,因为 shell 将等待第一个进程完成。
这意味着您无法访问您的代理服务器,因为它从未启动。
基本上我能想到两种解决方案。请注意,惯用语 "Docker way" 是 运行 每个容器仅一个进程 。
我建议运行将您的应用程序和代理服务器放在两个单独的容器中。你可以 link those two containers together:
docker run --name app -p 3000 <your-image> /nodejs/bin/node /app/main.js
docker run --name proxy -l app:app -p 4000:4000 <your-image> /nodejs/bin/node /proxy/main.js
标志 -l app:app
将导致 app
容器在您的 proxy
容器中使用主机名 app
可用(这是通过创建 /etc/hosts
进入容器)。这意味着,在代理容器内,您可以使用 http://app:3000
访问您的上游应用程序端口。
另一种解决方案是使用 进程管理器工具 ,如文档中的 Supervisord to manage several long-running processes in your container in parallel. There's a good article。基本上可以归结为以下几点:
- 安装 supervisord(Ubuntu 中的
apt-get install supervisor
)
创建一个配置文件(通常在 /etc/supervisor/conf.d/yourapplication.conf
中),在其中配置您需要的所有服务 运行:
[supervisord]
nodaemon=true
[program:application]
command=/nodejs/bin/node /app/main.js
[program:proxy]
command=/nodejs/bin/node /proxy/main.js
然后使用 supervisord
作为启动命令,例如在 Dockerfile 中使用 CMD ["/usr/bin/supervisord"]
。
在这种情况下,您的两个进程 运行 都在同一个容器中,您可以使用 http://localhost:3000
访问您的上游应用程序。
我有以下代码在我的本地环境中运行良好。但是,当我尝试从 Docker 容器(通过 Boot2Docker)运行 相同的代码时,我根本无法到达 https://[boot2docker_ip]:4000
我尝试使用所有这些选项更新下面代码中的目标值,但其中 none 似乎可以解决问题:
target: 'http://localhost:3000',
target: 'http://0.0.0.0:3000',
target: 'http://127.0.0.1:3000',
target: 'http://<boot2docker_ip>:3000',
var fs = require('fs');
require('http-proxy').createProxyServer({
ssl: {
key: fs.readFileSync(__dirname + '/certs/ssl.key', 'utf8'),
cert: fs.readFileSync(__dirname + '/certs/ssl.crt', 'utf8')
},
target: 'http://localhost:3000',
ws: true,
xfwd: true
}).listen(4000);
我正在使用来自 https://github.com/nodejitsu/node-http-proxy
的node-http-proxy
包
编辑
这里有一个 Git repo 来尝试这种行为;为了简单起见,我检查了伪造的 SSL。
Docker文件:
FROM readytalk/nodejs
ADD ./src /app
ADD ./ssl-proxy /proxy
COPY ./run.sh /run.sh
RUN chmod +x /run.sh
EXPOSE 3000
EXPOSE 4000
ENTRYPOINT ["/run.sh"]
run.sh:
#!/bin/sh
/nodejs/bin/node /app/main.js; /nodejs/bin/node /proxy/main.js
我刚刚查看了您的 Dockerfile,尤其是您使用的 run.sh
脚本。此行来自您的 run.sh
脚本:
/nodejs/bin/node /app/main.js; /nodejs/bin/node /proxy/main.js
这里要知道的重要一点是,这些命令中的每一个都会启动一个长期 运行ning 服务器进程,(理论上)永远 运行s。这意味着第二个进程 (/proxy/main.js
) 永远不会启动,因为 shell 将等待第一个进程完成。
这意味着您无法访问您的代理服务器,因为它从未启动。
基本上我能想到两种解决方案。请注意,惯用语 "Docker way" 是 运行 每个容器仅一个进程 。
我建议运行将您的应用程序和代理服务器放在两个单独的容器中。你可以 link those two containers together:
docker run --name app -p 3000 <your-image> /nodejs/bin/node /app/main.js docker run --name proxy -l app:app -p 4000:4000 <your-image> /nodejs/bin/node /proxy/main.js
标志
-l app:app
将导致app
容器在您的proxy
容器中使用主机名app
可用(这是通过创建/etc/hosts
进入容器)。这意味着,在代理容器内,您可以使用http://app:3000
访问您的上游应用程序端口。另一种解决方案是使用 进程管理器工具 ,如文档中的 Supervisord to manage several long-running processes in your container in parallel. There's a good article。基本上可以归结为以下几点:
- 安装 supervisord(Ubuntu 中的
apt-get install supervisor
) 创建一个配置文件(通常在
/etc/supervisor/conf.d/yourapplication.conf
中),在其中配置您需要的所有服务 运行:[supervisord] nodaemon=true [program:application] command=/nodejs/bin/node /app/main.js [program:proxy] command=/nodejs/bin/node /proxy/main.js
然后使用
supervisord
作为启动命令,例如在 Dockerfile 中使用CMD ["/usr/bin/supervisord"]
。
在这种情况下,您的两个进程 运行 都在同一个容器中,您可以使用
http://localhost:3000
访问您的上游应用程序。- 安装 supervisord(Ubuntu 中的