-1

So I'm running a nodejs backend microservice based application. And I'm trying to do something like this:

services:
      comments:
        build: ./comments
        ports:
          - "4201:4201"
      posts:
        build: ./posts
        ports: 
          - "4200:4200"
        links:
          - comments
        depends_on:
          - comments

I'm hosting this on my local host address, I have my containers kept together in the environment, so how to properly get the microservice API IP from another service in docker-compose environment?

This is where I call comments inside of postsmicroservice

let comments  = await axios.get("http://localhost:4201/comments");

This is the error when I do docker-compose run and try to get the route with testing tool called Postman: enter image description here

At the end of the error line: It says isAxiosError: true (this might be helpful)

Jan Tuđan
  • 233
  • 3
  • 17
  • the name of the service is the DNS address – Daniel A. White Sep 10 '21 at 19:07
  • Okay, how can this be helpful? – Jan Tuđan Sep 10 '21 at 19:09
  • You reach them by using the service names, like `http://comments:4201/whatever` for example. In the future, try googling or reading the documentation before posting a question. – super Sep 10 '21 at 19:10
  • I can use this in docker compose? I already reached them, but when I have all of this microservices kept inside docker environment I cannot reach them. – Jan Tuđan Sep 10 '21 at 19:14
  • It's about networking, not calling them because I made the calls in my application... Read the question title, I said how to allow them communicate not how to make them communicate – Jan Tuđan Sep 10 '21 at 19:15
  • Did you solve your problem? – JRichardsz Sep 10 '21 at 19:35
  • @JRichardsz I didn't.. trying to solve it few days in a row and still nothing... Can you help? – Jan Tuđan Sep 10 '21 at 19:38
  • I see that post depends of comments. How are you consuming comment endpoints from your post app? And what is the exact error. Attach them to your question – JRichardsz Sep 10 '21 at 19:40
  • Okay, I added the line in my question, but I don't know where to put `depends_on` in this case? Maybe in `comments`? – Jan Tuđan Sep 10 '21 at 19:46
  • docker-compose is just for dev or test purposes, not for production environments. I think your problem is the word `localhost` Check this https://stackoverflow.com/a/63207679/3957754 #1 Could you attach the error log of your `axios.get ...` #2 You said **Vue backend microservice** but vue is not backend is frontend. Could you share the technology used in comments and post containers? #3 In which layer is called the `axios.get` on your post app? nodejs (javascript on server) or vue (vanilla javascript on browser) – JRichardsz Sep 10 '21 at 20:18
  • So should I use address like "172.0.0.1" instead of localhost? #1 I will update the error in my question #2 Sorry my bad, this is node js server-side, I'm not using client side at all #3 it's called in node js with pure javascript on server – Jan Tuđan Sep 10 '21 at 20:33
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236987/discussion-between-jan-tudan-and-jrichardsz). – Jan Tuđan Sep 10 '21 at 20:56
  • Have you read [Networking in Compose](https://docs.docker.com/compose/networking/) in the Docker documentation? This describes the setup previous commenters have suggested. `localhost` or `127.0.0.1` in Docker usually means "this container". – David Maze Sep 10 '21 at 20:57

2 Answers2

1

Your problem is related to the usage of localhost inside of containers. Check this to understand why localhost does not work in docker environments.

You need the ip of the server, in your case your laptop. If you start an app (any technology) at 5000, you can access it using localhost:5000 and if you know your ip: 192.168.1.10:5000

Try to get your local ip and use it directly on your axios invocation to validate if that is your problem.

If that was the mistake, the second level of improvement is to use environment variable in your nodejs to avoid hardcoded values. You could pass this value using your docker-compose

services:
  comments:
    build: ./comments
    ports:
      - "4201:4201"
  posts:
    build: ./posts
    ports: 
      - "4200:4200"
    environment:
        - POSTS_API_BASE_DOMAIN=http://192.168.4.15:4201
    depends_on:
      - comments

And in your nodejs:

await axios.get(process.env.POSTS_API_BASE_DOMAIN+"/comments");

This strategy will allow you to use a public domain for real scenarios instead ips on your development or staging environments:

POSTS_API_BASE_DOMAIN=https://jan-tudan-post.com

As you see, networks or links is not required if you use the ip and prepares you to real environment in which microservices are deployed in different servers with its own ip or public domain

Deploy on another server

What happen if you need to deploy in another server. You will have to update the ip in your docker-compose or use a kind of script to get the ip and use a variable. Sample on linux:

export POSTS_API_BASE_DOMAIN="http://"$(hostname -I| awk '{printf $1}')

and in your docker-compose

environment:
    - POSTS_API_BASE_DOMAIN=http://192.168.4.15:4201

Just for test or quickly deploy

If you don't want to mess up with ips and you just need a quicly deploy for a demo, you could use host.docker.internal. Check that section here

Recommend topics

JRichardsz
  • 14,356
  • 6
  • 59
  • 94
-1

you have to add all your services into the same network. You can do this by first creating a network in your compose file (add this to the bottom)

networks:
  my-network:

then connect your services into this network

services:
  comments:
    build: ./comments
    ports:
      - "4201:4201"
    networks:
      - my-network
  posts:
    build: ./posts
    ports: 
      - "4200:4200"
    networks:
      - my-network
    links:
      - comments
    depends_on:
      - comments
  • This seems helpful, what to put inside my-network for example? – Jan Tuđan Sep 10 '21 at 20:17
  • You don't have to put anything inside the network definition. You could include custom drivers etc. See this page of the docs for more info [link](https://docs.docker.com/compose/networking/) – Nejc Jamnik Sep 10 '21 at 20:23
  • This doesn't work for me, whether the `networks: mynetwork:` should include what it refers to? Why to put it at the bottom of whole yml file? – Jan Tuđan Sep 10 '21 at 20:38
  • 1
    Compose creates a network named `default` for you, and attaches containers to it if you don't have other network configuration. This is unnecessary. – David Maze Sep 10 '21 at 20:56
  • Oh i realised! Thank you, but it still doesn't work for me, getting error as a big response: `isAxiosError: true` – Jan Tuđan Sep 10 '21 at 21:28