node.js - 容器 Node.js (Express) 后出现 "ECONNREFUSED"错误

标签 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"

最佳答案

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

同样,node.js 代理后面的主应用程序不应使用

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

因为这将在端口 8446 处调用自身,而不是主机操作系统的 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容器代理而不是127.0.0.1。这意味着您将使用 proxy:8080 来使用在端口 8080 上运行的代理。

PS:您可以通过服务名称路由到 docker 容器/服务,因为 docker 有一个内部维护的服务发现机制,并且它将动态解析这些容器的 IP 地址。这对于容器来说至关重要,因为容器可以随时销毁和重新创建,这意味着 IP 地址可以随时更改。为了解决这个问题,docker 维护了一个键值存储,它将服务/主机名映射到这些服务/主机的 IP 地址。 容器并解析它们以查找尝试访问其他容器的容器。如果应用程序应路由到其他 Docker 容器/服务,请确保将应用程序中的所有 IP 地址更改为使用主机/服务名称而不是静态 IP 地址。

关于node.js - 容器 Node.js (Express) 后出现 "ECONNREFUSED"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58088481/

相关文章:

带有 Express 应用程序的 Node.js 在 Heroku 上崩溃,在本地工作

javascript - 如何在 influxdb 中编写(nodejs)具有相同时间戳的多个点?

node.js - Phonegap 推送通知 + Node gcm : group notifications

process - 使用 docker run 命令时 Docker 容器退出(0),但与 docker start 命令一起使用

python - Flask with docker 在除 root 之外的所有路由上返回 404

javascript - 在一个命令中运行多个 Nodejs 服务器

node.js - 使用 mocha+sinon 测试 ExpressJS 路由时,如何 "stub"路由本地函数?

node.js - 最佳实践 : Angular SSR Partial Pre-rendering with dynamic fallback

angularjs - 使用 Grunt Connect 时无法获取/获取

docker - Docker 中的用户是什么概念,权限是如何工作的?