Can access container form other containers but not from localhost

I have an application which uses MySQL, Nest.js an Angular for the DB, Back and Front. I’ve managed to get Nest to communicate to the MySQL container and (I suppose) Angular with Nest, but when I try to access the frontend from the browser it says that the site cant be reached, or that the server didn’t answer if I do a request from Postman to the backend. I’m already exposing and assigning port ports but it isn’t working.

I’m running docker-compose up --build , browsing localhost:4200 or sending a request to localhost:3000 and what I get from the browser is localhost didn’t send any data. ERR_EMPTY_RESPONSE on Chrome.

this is mi docker-compose.yml file:

version: '3'

services:

# MySQL
  db:
    image: mysql:5.7
    command: --default-authentication-plugin=mysql_native_password
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

# Nest.js Backend
  server:
    build: ./backend
    expose:
      - 3000
    ports:
      - "3000:3000"
    depends_on:
      - db
    links:
      - db
    volumes:
      - ./backend/src:/srv/app/bk-god/src

# Angular 6 Frontend
  client:
    build: ./frontend
    expose:
      - 4200
    ports:
      - "4200:4200"
    volumes:
      - ./frontend/src:/srv/app/fr-god/src
      - ./frontend/public:/srv/app/fr-god/public
    links:
      - server

And this is my Dockerfile on each folder [only difference is that backend runs Yarn run start:dev]:

FROM node:8.15.0-alpine

RUN mkdir -p /srv/app/fr-god
WORKDIR /srv/app/fr-god

COPY package.json /srv/app/fr-god
COPY yarn.lock /srv/app/fr-god

RUN yarn

COPY . /srv/app/fr-god
CMD ["yarn", "start"]

PS: MySQL is accessible through console and GUI, pointing to localhost:3306.

This is the docker ps output:

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                    PORTS                               NAMES
435bfc1aa66d        docker_client       "yarn start"             About a minute ago   Up About a minute         0.0.0.0:4200->4200/tcp              docker_client_1
c96a84289d12        docker_server       "yarn run start:dev"     About a minute ago   Up About a minute         0.0.0.0:3000->3000/tcp              docker_server_1
069f8d61b770        mysql:5.7           "docker-entrypoint.s…"   About a minute ago   Up About a minute         0.0.0.0:3306->3306/tcp, 33060/tcp   docker_db_1

I’ve noticed the ports seems different on the db container (with a comma and the port again) and this is the only container I can access from localhost.

The question is how you connect from client to server and from server to the database. Published ports are for you, you don’t have to open any ports on server and db if you don’t need them personally. The containers are running in a temporary network and find each other with their names db, server and client. Take a look at this description.

Ok, so I don’t need the port declaration on both DB and server since I’m not using them, but what about client? I’m exposing and binding port 4200 but when I try to open localhost:4200 it won’ show anything at all.

You have a rather complicated setup, so this could be anything in any of the three containers. Is your application running? Is it listening to port 4200? Did you check its errorlog?

Why would you say it’s a complicated setup? Maybe I’m overthinking it, but what I’m trying to achieve is that the backend container connects to the db container, and the client container connects to the backend and also that can be accessible through the host web browser. Backend and client are running [I did `docker logs` on both], and the logs of the client says it has been build and it’s accessible through localhost:4200 [is an angular frontend].

Not the setup in itself is complicated, but it’s complicated to find an error here if you don’t have any information about what’s going wrong. I would first make sure that the frontend is working and for example try to display some static content.

oh, sorry for the misunderstading… so I ran the client by itself, and then tried to curl localhost:4200 from inside the container and this is what I get:

Miguel@MacBook-Pro ~> docker exec upbeat_cohen curl http://localhost:4200
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Game</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
</html>
100   573  100   573    0     0  23875      0 --:--:-- --:--:-- --:--:-- 23875

wich means that the frontend is working… however I’ve exposed and published port 4200 but I can’t access it from the host machine.

Just a guess: your application listens to localhost:4200 only instead of *:4200. This simple example

var http = require('http');

http.createServer(function (req, res) {
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end('<h1>Hello Docker!</h1>');
}).listen(4200);

works, but

}).listen(4200, 'localhost');

produces the same symptoms you describe: no response in the browser and correct content using curl inside the container.

well, when the application starts it prompts this message ** Angular Live Development Server is listening on localhost:4200, open your browser on http://localhost:4200/ ** so I’m going to guess yes, it only listen to localhost.

Yeap, and if you take a look at this page and search for ‘host’ everything gets clear.

So it should work if I try to access the port on the containers IP?

I’ve read some article from a guy who create the image based on a nginx:alpine distro an then on the nginx config file it tells to listen on an specific port. guess I’m going to give it a try.

Here on Stackoverflow the same question is discussed. Seems you have to add "host": "0.0.0.0" to the config file.
You meant node:alpine, not nginx, didn’t you?

1 Like

I added the config for the host and port and now it is working, thanks!!

BTW I meant nginx, take a look at this article

This helped, thanks!