Home > Net >  Node.js in Docker ECONNREFUSED
Node.js in Docker ECONNREFUSED

Time:10-18

I'm trying to implement Oauth2 authentication (passport-oauth2) with Dex to my Node.js.

If I'm running my API inside a docker container, I'm getting: Error: connect ECONNREFUSED 127.0.0.1:80. Outside a docker it works just fine!

My API runs on port 3000 and Dex runs on port 5556. I'm using nginx to proxy pass those services.

So localhost/dex will access dex

and localhost/node_api will access my API without having to specify the ports.

My relevant API code:

app.use(session({
  secret: 'XXXX',
  resave: true,
  saveUninitialized: true,
}));

app.use(passport.initialize());
app.use(passport.session());

const oAuthStrategy = new OAuth2Strategy({
  issuer: 'http://localhost/dex',
  authorizationURL: 'http://localhost/dex/auth',
  tokenURL: 'http://localhost/dex/token',
  token_endpoint: 'http://localhost/dex/token',
  clientID: 'example-app',
  clientSecret: 'XXXX',
  callbackURL: 'http://localhost/login/callback',
  scope: 'openid email',
}, ((accessToken, refreshToken, params, profile, cb) => {
  console.log(`params: ${params}`);
  console.log(profile);
  return cb(null, profile);
}));

passport.use(oAuthStrategy);

passport.serializeUser((user, next) => {
  console.log('serializeUser');
  console.log(user);
  next(null, user);
});

passport.deserializeUser((obj, next) => {
  console.log('deserializeUser');
  next(null, obj);
});

app.use('/login', passport.authenticate('oauth2'));

app.use('/login/callback', passport.authenticate('oauth2', { failureRedirect: '/error' }), (req, res) => {
  res.redirect('/loggedin');
});

Relevant docker-compose.yml code:

dex:
  image: dexidp/dex
  volumes:
    - ./config-ldap.yaml:/etc/dex/config.docker.yaml
  labels:
    - traefik.enable=true
    - traefik.http.routers.dex.entryPoints=https
    - traefik.http.routers.dex.rule=PathPrefix(`/dex`)
    - traefik.http.routers.dex.tls=true
    - traefik.http.services.dex.loadbalancer.server.port=5556


node_api:
  image: xxxxx
  build:
    ./node_api
  depends_on:
    - timescaledb
  environment:
    TS_USER: xxx
    TS_PASSWORD: xxx
    TS_DB: xxx
    TS_DOMAIN: timescaledb
  restart: always
  labels:
    - traefik.enable=true
    - traefik.http.routers.node_api.entryPoints=https
    - traefik.http.routers.node_api.rule=PathPrefix(`/node_api`)
    - traefik.http.routers.node_api.tls=true
    - traefik.http.services.node_api.loadbalancer.server.port=3000

nginx.conf:

server {
  listen 80;
  server_name nginx;
  # this is the internal Docker DNS, cache only for 30s
  resolver 127.0.0.11 valid=30s;

  location /node_api/ {
    set $upstream http://node_api:3000;
    # nginx will also start if host is not reachable
    proxy_pass $upstream;
  }

  location /dex/ {
    set $upstream http://dex:5556;
    # nginx will also start if host is not reachable
    proxy_pass $upstream;
  }
}

Help highly appreciated!

CodePudding user response:

It looks to me like you're not actually exposing the Dex or Node Ports in your docker-compose file.

Adding the following might help?

dex:
  ...
  ports:
    - "5556":"5556"

node_api:
  ...
  ports:
    - "3000":"3000"

Unless you tell it to, Docker will not expose any ports to your system. To make different containers visible you need to explicitly expose each port. For more about this, see the docs here: https://docs.docker.com/config/containers/container-networking/

Hope this helps!

CodePudding user response:

Two Things needs to be fix!

  1. first expose the port in docker-compose same as what helblingjoel mention
    dex:
      ...
      ports:
        - "5556":"5556"
    
    node_api:
      ...
      ports:
        - "3000":"3000"
  1. replace the url in your code from http://localhost/dex/token to http://host.docker.internal/dex/token (Prevent using 127.0.0.1/localhost in your connection string)

You can check more in this post

  • Related