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" 是 运行 每个容器仅一个进程

  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 to manage several long-running processes in your container in parallel. There's a 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 访问您的上游应用程序。