0

I have 2 containers one running on localhost:3001 and the other on localhost:3003

container localhost:3001 hits an endpoint thats running in the container localhost:3003 But gets a (failed)net::ERR_EMPTY_RESPONSE

I have tried multiple ways to get them to connect. Please don't tell me to setup a docker compose file. I should be able to spin up 2 containers and have them communicate with their ports.

I also tried adding a network.

docker network create my-network

Shows as: ea26d2eaf604   my-network   bridge    local

Then I spin up both containers with the flag --net my-network. When container localhost:3001 hits an endpoint thats running in the container localhost:3003 again I get a (failed)net::ERR_EMPTY_RESPONSE

This is driving me crazy. What am I doing wrong here ?

I have even used shell to run a curl from localhost:3001 to localhost:3003 and I get

to curl: (7) Failed to connect to localhost port 3003 after 0 ms: Connection refused
me-me
  • 5,139
  • 13
  • 50
  • 91
  • `localhost` in Docker almost always means "the current container". Imagine connecting two separate physical computers to the same wired or wireless network; even though they're on the same network, each thinks itself is `localhost` and you'd use the other system's DNS name to connect to it. In Docker, see for example [How to communicate between Docker containers via "hostname"](https://stackoverflow.com/questions/30545023/how-to-communicate-between-docker-containers-via-hostname/35184695#35184695). – David Maze Aug 31 '22 at 10:54

1 Answers1

1

When you place both machines on the same network, they are able to reference each other by their service/container name. (not localhost - as localhost is a local loopback on each container). Using a dedicated network would be the ideal way to connect from container to container.

I suspect what is happening in your case is that you are exposing 3001 from container a on the host, and 3003 from container b on the host. These ports are then open on the host, and from the host you can use localhost, however, from the containers to access the host you should use host.docker.internal which is a reference to the host machine, instead of using localhost

Here is some further reading about host.docker.internal https://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms

Update: docker-compose example


version: '3.1'

services:
  express1:
    image: node:latest
    networks:
      - my-private-network
    working_dir: /express
    command: node express-entrypoint.js
    volumes:
      - ./path-to-project1:/express

  express2:
    image: node:latest
    networks:
      - my-private-network
    working_dir: /express
    command: node express-entrypoint.js
    volumes:
      - ./path-to-project2:/express
  
networks:
  my-private-network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.31.27.0/24

Then you can reference each container by their service name, e.g: from express1 you can ping express2

Tjad Clark
  • 552
  • 3
  • 17
  • I'm not exposing anything but my express server in container a is running on localhost:3001 and the other container b is on localhost:3003. I even tried just one container running localhost:3001 and then running my other express server from my host machine instead of docker and then using host.docker.internal instead of localhost but that didnt work. – me-me Aug 31 '22 at 03:45
  • 2 ways to go about it. First way involves more understanding (which is to set them up on their network, and use their respective host names/ip addresses. You can provide a hostname with `--hostname` . The 2nd way which will be slightly easier to understand is to expose your ports on the host and use `host.docker.internal` – Tjad Clark Aug 31 '22 at 03:50
  • Using docker-compose to setup your containers may make this a lot easier. You can setup the network within docker-compose, add the containers to the network, and then reference the containers by their `service` name that you have provided - I usually do this. – Tjad Clark Aug 31 '22 at 03:53
  • Ok lets take the easy way until I understand this. expose your ports on the host ? How do I do this ? – me-me Aug 31 '22 at 03:55
  • Do you mean adding EXPOSE 3001 to my dockerfile – me-me Aug 31 '22 at 03:55
  • You can use `-p` as part of docker run. `docker run -p 3001:3001 my_image`, that will expose port 3001 of the container as port 3001 on your host – Tjad Clark Aug 31 '22 at 04:11
  • What is command: node express-entrypoint.js ? I already have my images built do I need this ? Cant i just use image: myImage – me-me Aug 31 '22 at 04:17
  • 1
    You just posted docker-compose.yml so why you saying docker run -p 3001:3001 my_image ? Shouldn't it just be docker-compose up – me-me Aug 31 '22 at 04:19
  • `-p` is if you are not using docker-compose. Yes you can do just docker-compose up. yes if your image is setup already, you can remove the `volumes` and `command` and `working_dir` – Tjad Clark Aug 31 '22 at 04:32
  • I have my urls setup in my env file which I have working with your code above. would I need to change them to AUTH_AUTHORIZATION_URL=http://express2:3003/authorize AUTH_TOKEN_URL=http://express2:3003/token AUTH_CALLBACK_URL=http://express1:3001/callback – me-me Aug 31 '22 at 04:36
  • If they are being requested from within the containers, yes, that would be required. Sounds like you're getting there. – Tjad Clark Aug 31 '22 at 04:38
  • I still have to use localhost:3001 to start the app in my browser. But when my express app running inside the container hits http://express2:3003/authorize it fails and just hangs – me-me Aug 31 '22 at 04:44
  • I tried a curl from inside exprerss1 to talk to express2 curl http://express2:3003/authorize curl: (7) Failed to connect to express2 port 3003 after 9 ms: Connection refused – me-me Aug 31 '22 at 04:54
  • The problem may then be that the express server is listening on the local loopback. Try set the host that express listens to `0.0.0.0` – Tjad Clark Aug 31 '22 at 04:56
  • I changed both servers to app.listen(3001, "0.0.0.0"); and app.listen(3003, "0.0.0.0"); still the same enter the site on http://localhost:3001/ then it tries to hit the express2:3003/authorize and hangs and eventualls fails as it can't connect – me-me Aug 31 '22 at 05:06