【问题标题】:Node http-proxy in Docker containerDocker 容器中的节点 http-proxy
【发布时间】:2015-07-05 14:57:53
【问题描述】:

我有以下代码在我的本地环境中运行良好。但是,当我尝试从 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-proxynode-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

【问题讨论】:

  • 监听 3000 端口的服务在哪里运行?在您的主机上,还是在另一个 Docker 容器内?
  • 在同一个 docker 容器内。我先启动这个代理,然后在端口 3000 上启动那个服务
  • 我明白了。您用于启动容器的 Dockerfile 和/或 docker run 命令可能很有用。
  • 勾选编辑。这是供您试用的存储库:github.com/munjalpatel/node-http-proxy-test
  • 好的!我编辑了您的问题以包含有问题的代码(通常,不鼓励在 SO 上使用仅链接问题和答案,因为链接往往会变得无效)并在下面起草了一个答案。如果有帮助,请告诉我!

标签: node.js docker boot2docker node-http-proxy


【解决方案1】:

我刚刚查看了您的 Dockerfile,尤其是您使用的 run.sh 脚本。此行来自您的 run.sh 脚本:

/nodejs/bin/node /app/main.js; /nodejs/bin/node /proxy/main.js

这里要知道的重要一点是,这些命令中的每一个都会启动一个长期运行的服务器进程,该进程(理论上)永远运行。这意味着第二个进程 (/proxy/main.js) 永远不会启动,因为 shell 将等待第一个进程完成。

这意味着您无法访问您的代理服务器,因为它永远不会启动

基本上我能想到两种解决方案。请注意,惯用的“Docker 方式”是每个容器仅运行一个进程

  1. 我建议在两个独立的容器中运行您的应用程序和代理服务器。你可以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 访问您的上游应用程序端口。

  2. 另一种解决方案是使用进程管理器工具(如Supervisord)来并行管理容器中的多个长时间运行的进程。文档中有一个good article。基本上可以归结为以下几点:

    1. 安装 supervisord(在 Ubuntu 中为apt-get install supervisor
    2. 创建一个配置文件(通常在 /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
      
    3. 然后使用 supervisord 作为启动命令,例如在 Dockerfile 中使用 CMD ["/usr/bin/supervisord"]

    在这种情况下,您的两个进程都在同一个容器中运行,您可以使用http://localhost:3000 访问您的上游应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多