# Docker: Cross-Container Communication ###### tags: `Docker` [TOC] # 1st type: From Container to WorldWide Web(WWW) ![](https://i.imgur.com/3YMZFQA.png) Containers can send request can communicate with web API's and web pages from inside our dockerized applications. So sending requests to Worldwide Web (www) from containers works without any problem. # 2nd type: From Container to Machine Must use **host.docker.internal** as **URL/domain**. Docker will do the transformations and ensure communication between container and host machine works. **Note:** If we just use **localhost**, it will fail automatically, as it does not know how to find your host. ## Example This one will not work: ``` === Node.js 'mongodb://localhost:27017/swfavorites' ``` Must change into the one below: ``` === Node.js 'mongodb://host.docker.internal:27017/swfavorites' ``` By changing **localhost** to **host.docker.internal**, it is recognized by Docker and is **translated into the IP address of your host machine**. # 3rd type: From Container to Container In order to connect container to container, we have to either: 1. Look for IP Address of container to use it as a link (Simple Communication) 2. Make a Docker Network and link all containers below them by using container name (Multi Container Communication) ## Container to Container: Simple Communication We need to **retrive the container's IP address** in order to communicate with it. By using below command, we can check up container's information. In it we will find **"NetworkSettings: IP Address"**. With this, we need to put it in right url/domain when we call the other container, and the link between them will be up. ``` ==== docker container inspect containerName ``` **Note:** Be aware to check up that both container are running. ### Example with MongoDB as Container to communicate We first use an image from docker hub **mongo** and run a container called mongodb. ``` ==== docker run -d --name mongodb mongo ``` Let's check how to connect to this container: ``` ==== docker container inspect mongodb ``` We need to check **containers' Network Settings, which contains an IP-Address**. This one will be used to connect/communicate to this container. In this case it will be 172.17.0.3 ![](https://i.imgur.com/Jwt5AV6.png) We later use this IP-address in the part where we want to communicate with the other container(mongodb container in this case). After building image and running container, you will see that you can call it succesfully from APIs in this case. ![](https://i.imgur.com/Rf1XNE8.png) ### Simple Communication Disadvantage >You have to look up for IP Address all the time, it would take us lot up time if we had many. Take into account that if ip address change, we would have to build a new image, because we hard coded the IP address. Therefore, we will introduce another way of communication between containers. [color=red] ## Container to Container: Multi Containers Communication We can make Container Networks with Docker. docker run --network my_network ... Docker will then look up IP and resolve stuff. Within a Docker Network all containers can communicate with each other and IPs are automatically resolved. Unlike Volumes, Docker does not automatically create Nerwork for us ``` ==== Docker network --help ``` We have the commands we have below: ![](https://i.imgur.com/3zREtlx.png) We use the command below to create a new network: ``` ==== //docker network create fav-net docker network create networkName ``` And use ls to check the networks existing. ``` ==== docker network ls ``` After creating and checking the network is available, we can use it to run our containers. ``` ==== //docker run -d --name mongodb --network fav-net mongo docker run -d --name containerName --network networkName imgName ``` **But how we connect it to the other containers? What should we write in url/domain place, when we call the other container?** **Answer:** We just use the container name! Docker will know the containers which are actually running below the same Network and by checking the name, it will automatically know the IP Address you want to link it to. ***See the example Below:*** Our **another container is called mongodb**, as we want to connect to this one, instead of writting IP Address, we just use the containerName. ``` ==== JavaScript mongoose.connect( 'mongodb://mongodb:27017/swfavorites', { useNewUrlParser: true }, (err) => { if (err) { console.log(err); } else { app.listen(3000); } } ); ``` And we build an image and run container again. ``` ==== //docker run -d --rm --network fav-net --name favoriteapp -p 3000:3000 favorite docker run -d --rm --network networkName --name containerName -p localPort:exposePort imgName ``` We use postman to check their connection and it works. ![](https://i.imgur.com/EYtX1Tg.png) ## How Docker Resolves IP Address? ![](https://i.imgur.com/TXC1sV7.jpg) It is **IMPORTANT** to know that Docker will not go ahead and change **container name/host.docker.internal** to IP Address in our source code. Docker owns the environment, in which the application is running. So when application sends **an HTTP request or any other request that leaves the container, Docker will know that automatically and resolve the address at that time.** # Extra: Containers like mongoDB container, which is a container that another container will be connecting to, does not need to pur **-p option** when launching it. Because it is only necessary when we plan to connect something in that container from our local host machine or outside the container.