Mohamed Hussein
Mohamed Hussein

Reputation: 23

Docker Can't connect to linked container on the same network - all other containers working

Hello Iam running 4 services in this docker-compose file:

all services running good but only having a problem with the service named "repnjs".

version: "3"

volumes:
  local_mongo_data: {}
  local_mongo_data_backups: {}

services:
  tomcat: &tomcat
    build:
      context: .
      dockerfile: compose/local/tomcat/Dockerfile
    image: oneuni_local_tomcat
    depends_on:
      - mongo
    volumes:
      - .:/app
    env_file:
      - .envs/.local/.main
      - .envs/.local/.mongo
    ports:
      - "8080:8080"

  repnjs:
    build:
      context: .
      dockerfile: compose/local/repnjs/Dockerfile
    image: oneuni_local_repnjs
    restart: always
    depends_on:
      - mongo
    volumes:
      - ./oneuni-student-report:/home/node/app
      - ./oneuni-student-report/node_modules:/home/node/app/node_modules
      - ./compose/local/repnjs/mongotest.js:/app/mongotest.js
    env_file:
      - .envs/.local/.main
      - .envs/.local/.mongo
    ports:
      - 3500:3500
    command: npm run startDev



  web-client:
    build:
      context: .
      dockerfile: ./compose/local/web-client/Dockerfile
    image: local_web-client
    depends_on:
      - tomcat
      - repnjs
    restart: always
    volumes:
      - .:/home/node/app
      - ./one-uni-web-client/node_modules:/home/node/app/node_modules
    env_file:
      - .envs/.local/.main
    ports:
      - 4200:4200

  mongo:
    build:
      context: .
      dockerfile: compose/production/mongo/Dockerfile
    image: oneuni_production_mongo
    container_name: mongo
    volumes:
      - ./compose/production/mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
      - ./compose/production/mongo/conf/mongod.conf:/etc/mongod.conf
      - local_mongo_data:/data/db
      - local_mongo_data_backups:/backups
    env_file:
      - .envs/.local/.mongo
    ports:
      - '27017-27019:27017-27019'
    environment:
      - MONGO_INITDB_ROOT_USERNAME=user
      - MONGO_INITDB_ROOT_PASSWORD=password
    hostname: mongo


it doesn't connect to localhost:3500

I have tried

curl -i localhost:3500

always give me this error

curl: (56) Recv failure: Connection reset by peer

I have tried curl the other docker ports all working fine , I have entered each container to curl the other on the same network with the service hostname also all working only the "repnjs" not working

this is the docker file of "repnjs"



FROM node:12.19.0


COPY ./oneuni-student-report/ /app
COPY ./compose/local/tomcat/oneuni/ /etc/oneuni/

WORKDIR /app

RUN npm install
RUN npm install -g nodemon
CMD ["npm", "run", "startDev"]

this is the package.json file for the express application


{
  "name": "nodejs-project",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www",
    "startDev": "nodemon ./bin/www"
  },
  "dependencies": {
    "body-parser": "~1.18.2",
    "cookie-parser": "~1.4.3",
    "cors": "^2.8.4",
    "debug": "~2.6.9",
    "express": "~4.15.5",
    "jade": "~1.11.0",
    "mongodb": "^3.0.3",
    "morgan": "~1.9.0",
    "properties-reader": "0.0.16",
    "serve-favicon": "~2.4.5"
  }
}

and this is the entry point of the server /bin/www


#!/usr/bin/env node

/**
 * Module dependencies.
 */

var app = require("../app");
var debug = require("debug")("nodejs-project:server");
var http = require("http");

/**
 * Get port from environment and store in Express.
 */

var port = normalizePort(process.env.PORT || "3500");
app.set("port", port);

/**
 * Create HTTP server.
 */

var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */

server.listen(port, "localhost", function () {
  console.log("started to listen on" + port + " localhost");
});
server.on("error", onError);
server.on("listening", onListening);

/**
 * Normalize a port into a number, string, or false.
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 * Event listener for HTTP server "error" event.
 */

function onError(error) {
  if (error.syscall !== "listen") {
    throw error;
  }

  var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case "EACCES":
      console.error(bind + " requires elevated privileges");
      process.exit(1);
      break;
    case "EADDRINUSE":
      console.error(bind + " is already in use");
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * Event listener for HTTP server "listening" event.
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port;
  debug("Listening on " + bind);
}

to note as well , the code of nodejs works perfectly on the local machine its just not accessible when its run by docker-compose

I would appreciate if someone can help me in this issue I have been a week trying to solve it out and not sure why its happening.

thanks

Upvotes: 1

Views: 842

Answers (1)

David Maze
David Maze

Reputation: 159998

Any TCP-based server has a bind address that says what interfaces it wants to listen to. In your example code, you server.listen(port, "localhost") which causes the server to only be reachable on the loopback interface, via the 127.0.0.1 special IP address. However, in Docker, each container has its own private loopback interface, so this setting makes the container unreachable from anywhere else.

There is a special value for the bind address, 0.0.0.0, which means "listen on all interfaces". This is usually the default value when it's configurable (and indeed it's the default for the Node server.listen function). You need to change the localhost bind address to 0.0.0.0, or just remove it, or make it configurable.

// Just remove the bind address parameter entirely
server.listen(port, function() { ... });

// Make it configurable, if you need to
const bindAddress = process.env.BIND_ADDRESS || "0.0.0.0";
server.listen(port, bindAddress, function() { ... });

Upvotes: 1

Related Questions