我让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_PROXY
和 HTTPS_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/