我有以下代码在我的本地环境中运行良好。但是,当我尝试从Docker容器(通过Boot2Docker)运行相同的代码时,我根本无法访问https://[boot2docker_ip]:4000
我尝试使用所有这些选项更新下面代码中的目标值,但似乎没有一个可以解决这个问题:
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。
Dockerfile:
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
答案 0 :(得分:6)
我刚看了你的Dockerfile,特别是你使用的run.sh
脚本。这一行来自您的run.sh
脚本:
/nodejs/bin/node /app/main.js; /nodejs/bin/node /proxy/main.js
这里要知道的重要一点是,这些命令中的每一个都会启动一个长期运行的服务器进程(理论上)永远运行。这意味着第二个进程(/proxy/main.js
)将永远不会启动,因为shell将等待第一个进程完成。
这意味着您无法访问代理服务器,因为它永远无法启动。
基本上我可以想到两种解决方案。请注意,惯用的#Docker方式&#34;但是,每个容器只运行一个进程。
我建议您在两个单独的容器中运行您的应用程序和代理服务器。你可以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
容器与app
容器中的主机名proxy
一起使用(通过创建/etc/hosts
来完成进入容器)。这意味着,在代理容器内,您可以使用http://app:3000
访问上游应用程序端口。
另一种解决方案是使用像<{3}}这样的流程管理工具来并行管理容器中的多个长时间运行的流程。文档中有Supervisord。它基本归结为以下几点:
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
访问您的上游应用程序。