Reputation: 4625
I have node.js playing a role of "reverse proxy" which hides the main server (application).
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
Seems like ENV HTTP_PROXY "http://1270.0.1:8080" didn't work.
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
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)
FROM ubuntu:16.04
...
ENV HTTP_PROXY "http://127.0.0.1:8446"
ENV HTTPS_PROXY "https://127.0.0.1:8446"
Upvotes: 2
Views: 1418
Reputation: 2638
The Problem
From the container's point of view, 127.0.0.1
is the ip address of itself -- not the host 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. This is why your npm install
isn't working.
Similarly, your main application behind the node.js proxy should not be using
...
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).
The Solution
You have to use something like docker compose or docker swarm to link the two containers' network. Refer to the following example 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.
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
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
. Which means that you will use proxy:8080
to use the proxy running on port 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. 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. 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. 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.
Upvotes: 3