简体   繁体   English

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

[英]“ECONNREFUSED” error after containering Node.js (Express)

I have node.js playing a role of "reverse proxy" which hides the main server (application).我有 node.js 扮演隐藏主服务器(应用程序)的“反向代理”的角色。

It worked fine before I containerized but it gets me an error while npm install in Docker - reason: connect ECONNREFUSED 127.0.0.1:8080在我容器化之前它工作得很好,但是当npm install在 Docker 中时它给我一个错误 - reason: connect ECONNREFUSED 127.0.0.1:8080

Seems like ENV HTTP_PROXY " http://1270.0.1:8080 " didn't work.似乎 ENV HTTP_PROXY " http://1270.0.1:8080 " 不起作用。

What might cause the problem?什么可能导致问题? + How can I possibly fix this? + 我怎么可能解决这个问题?

Dockerfile in for Node.js - Run command: docker build -t saml-enabled-reverse-proxy.;docker run -it -p 8446:8446 saml-enabled-reverse-proxy bash Dockerfile in for Node.js - Run command: 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" ]

Application Dockerfile port 8080 - application (hided by reverse proxy)应用程序 Dockerfile 端口 8080 - 应用程序(被反向代理隐藏)

FROM ubuntu:16.04
...

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

The Problem问题
From the container's point of view, 127.0.0.1 is the ip address of itself -- not the host OS .从容器的角度来看, 127.0.0.1是其自身的 ip 地址 -而不是主机 OS That means you shouldn't set 127.0.0.1:8080 as a HTTP_PROXY and HTTPS_PROXY because your container would be calling itself so it won't reach the Internet.这意味着您不应将127.0.0.1:8080设置为HTTP_PROXYHTTPS_PROXY ,因为您的容器会调用自身,因此无法访问 Internet。 This is why your npm install isn't working.这就是为什么您的npm install无法正常工作的原因。

Similarly, your main application behind the node.js proxy should not be using同样,不应使用 node.js 代理背后的主应用程序

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

because that would be calling itself at port 8446 and not the 8446 of the host OS (which you intended to route to the other container running the node.js proxy, but this will never work).因为这将在端口8446上调用自身,而不是主机操作系统的 8446(您打算将其路由到运行 node.js 代理的另一个容器,但这永远不会起作用)。

The Solution解决方案
You have to use something like docker compose or docker swarm to link the two containers' network.您必须使用 docker compose 或 docker swarm 之类的东西来链接两个容器的网络。 Refer to the following example docker-compose.yml :请参考以下示例docker-compose.yml

version: "3.7"

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

  app:
    image: myapp

Also, remove the following lines from your proxy dockerfile and rebuild the image.此外,从您的代理 dockerfile 中删除以下行并重建映像。

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

Similarly, change the main application dockerfile from this同样,从这里更改主应用程序 dockerfile

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

to

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

Now run docker-compose up with this configuration, and your main app will be able to reach proxy container by the host name proxy rather than 127.0.0.1 .现在使用此配置运行docker-compose up ,您的主app将能够通过主机名proxy而不是127.0.0.1访问proxy容器。 Which means that you will use proxy:8080 to use the proxy running on port 8080.这意味着您将使用proxy:8080来使用在端口 8080 上运行的代理。

PS: You are able to route to the docker containers/services via their service name because docker has a service discovery mechanism it maintains internally and it will resolve the ip address of these conatiners dynamically. PS:您可以通过服务名称路由到 docker 容器/服务,因为 docker 具有内部维护的服务发现机制,它将动态解析 ip 的这些容器地址。 This is essential to containers because containers can be destroyed and recreated at any time which means that IP addresses can change at any time.这对容器至关重要,因为容器可以随时销毁和重新创建,这意味着 IP 地址可以随时更改。 In order to resolve this, docker maintains a key-value store which maps service/host names to the IP addresses of these containers and resolve them for containers that are trying to reach other containers.为了解决这个问题,docker 维护一个键值存储,它将服务/主机名映射到这些容器的 IP 地址,并为试图访问其他容器的容器解析它们。 Make sure to change all the IP addresses within your app to use host/service names instead of static IP addresses if they should route to other docker containers/services. Make sure to change all the IP addresses within your app to use host/service names instead of static IP addresses if they should route to other docker containers/services.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM