容器Node.js(Express)之后出现“ ECONNREFUSED”错误

时间:2019-09-24 21:39:57

标签: node.js docker express docker-compose dockerfile

我让node.js扮演“反向代理”的角色,这隐藏了主服务器(应用程序)。

在我进行容器化之前,它运行良好,但是在npm install的Docker中-reason: connect ECONNREFUSED 127.0.0.1:8080

却给我一个错误

似乎ENV HTTP_PROXY“ http://1270.0.1:8080”无效。

什么可能导致此问题? +我该如何解决?

用于Node.js的Dockerfile-运行命令:docker build -t saml-enabled-reverse-proxy .;docker run -it -p 8446:8446 saml-enabled-reverse-proxy bash

FROM node:12.10.0

ENV HTTP_PROXY "http://127.0.0.1:8080"
ENV HTTPS_PROXY "https://127.0.0.1:8080"

# Create app directory

# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./

# RUN npm config set proxy http://127.0.0.1:8080
# RUN npm config set https-proxy http://127.0.0.1:8080
RUN npm config set proxy null
RUN npm config set https-proxy null
RUN npm config set registry https://registry.npmjs.org
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production

COPY . .

EXPOSE 8080
EXPOSE 8446
CMD [ "node", "src/index.js" ]

应用程序Dockerfile 端口8080-应用程序(由反向代理隐藏)

FROM ubuntu:16.04
...

ENV HTTP_PROXY "http://127.0.0.1:8446"
ENV HTTPS_PROXY "https://127.0.0.1:8446"

1 个答案:

答案 0 :(得分:1)

问题
从容器的角度来看,127.0.0.1是其自身的IP地址-不是主机操作系统。这意味着您不应该将127.0.0.1:8080设置为HTTP_PROXYHTTPS_PROXY,因为您的容器会自行调用,因此不会到达Internet。这就是为什么您的npm install无法正常工作的原因。

类似地,您的node.js代理后面的主应用程序不应使用

...
ENV HTTP_PROXY "http://127.0.0.1:8446"
ENV HTTPS_PROXY "https://127.0.0.1:8446"
...

因为它将在端口8446而不是主机OS的8446上进行调用(您打算将其路由到运行node.js代理的另一个容器,但这将永远无法工作)。

解决方案
您必须使用docker compose或docker swarm之类的东西来链接两个容器的网络。请参考以下示例docker-compose.yml

version: "3.7"

services:
  proxy:
    image: myproxy
    port:
      - 8080:8080

  app:
    image: myapp

此外,从您的代理dockerfile中删除以下几行并重建映像。

ENV HTTP_PROXY "http://127.0.0.1:8080"
ENV HTTPS_PROXY "https://127.0.0.1:8080"

类似地,从此更改主应用程序dockerfile

ENV HTTP_PROXY "http://127.0.0.1:8446"
ENV HTTPS_PROXY "https://127.0.0.1:8446"

ENV HTTP_PROXY "http://proxy:8446"
ENV HTTPS_PROXY "https://proxy:8446"

现在使用此配置运行docker-compose up,您的主app将能够通过主机名proxy而不是proxy到达127.0.0.1容器。这意味着您将使用proxy:8080来使用在端口8080上运行的代理。

PS:您能够通过服务名称路由到docker容器/服务,因为docker具有服务维护机制,该机制在内部维护,并将动态解析这些容器的ip地址。这对于容器至关重要,因为容器可以随时被破坏和重新创建,这意味着IP地址可以随时更改。为了解决这个问题,docker维护了一个键值存储,该存储将服务/主机名映射到这些主机的IP地址。 容器,并针对尝试到达其他容器的容器进行解析。如果应将应用程序内的所有IP地址路由到其他Docker容器/服务,请确保将它们使用主机/服务名而不是静态IP地址。