Docker容器

时间:2015-07-05 14:57:53

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

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

1 个答案:

答案 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;但是,每个容器只运行一个进程

  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容器与app容器中的主机名proxy一起使用(通过创建/etc/hosts来完成进入容器)。这意味着,在代理容器内,您可以使用http://app:3000访问上游应用程序端口。

  2. 另一种解决方案是使用像<{3}}这样的流程管理工具来并行管理容器中的多个长时间运行的流程。文档中有Supervisord。它基本归结为以下几点:

    1. 在Ubuntu中安装supervisord(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"]

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