Docker networking, how to connect different containers
Tags: docker, webdev, devops, tutorial
Published: 2024-04-11 21:34:43

**Having different containers is quite common when using Docker in a project, such as one for the React application, one for the backend, and one for the database, for example. And in this article I will show you how to connect these different containers using a solution called container 
networking.**

Following Docker best practices, each container should have only one responsibility, that’s why we usually have different containers in a project. But how can all these containers be connected and communicate with each other or use services outside the Docker? The answer for this question is a feature called networking.

## Scenario overview

All examples in this article will be based on the following example: a Node JS application that needs to create, read, update and delete data (CRUD) from a Mongo database (but can be applied to any type of language and services as the main idea here is to demonstrate how we can have different but connected containers).

So, **let's imagine we have a Node JS file that has methods for managing data from a Mongo database. In this file we also need to connect to the database to be able to execute all these methods.**

In this scenario we will have two containers:

- a container to run the Node JS application (which contains all the methods mentioned above and also the connection to the database)
- another container to run Mongo db

Next, we will focus on connecting to the Mongo database as this is the most important part of this article.

## Connecting different containers using network

> “You can create custom, user-defined networks, and connect multiple containers to the same network. Once connected to a user-defined network, containers can communicate with each other using container IP addresses or container names.” - [Docker docs](https://docs.docker.com/network/#user-defined-networks)

At this point you should know how to run containers via command line. I have an article called [“How to use Docker Images, Containers and Volumes”](https://dionarodrigues.dev/blog/how-to-use-docker-images-containers-volumes-and-bind-mounts) where you can learn about it in details.

### 1- Creating networks

The first step is to create a network to connect the containers.

`docker network create [network_name]`

Example:

`docker network create my_app_net`

### 2- Running Mongo db container connected to the created network

Now it’s time to run the Mongo db container via command line and connect it to the network.

`docker run -d --network my_app_net --name mongo_db mongo`

Where `my_app_net` is the network created above, `mongo_database` is the name of this container, and `mongo` is the name of the image this container is based on. The container name is important because we will use it in the next step.

### 3- Connecting to Mongo db container from Node JS file

As I mentioned in the Scenario Overview section, let's imagine here that we have a Node JS file that needs to connect to the Mongo database container created in the previous step. Then we can have the following code:

```js
mongoose.connect(
  'mongodb://mongo_db:27017/my_database_name',
  …
);

```

Where `mongo_db` is the name of the container created in the previous step and `27017` is just the port provided by Mongo (you can read more about this in its [documentation](https://www.mongodb.com/docs/manual/reference/default-mongodb-port/)). In a non-Docker solution, when we install Mongo on our host machine, `mongo_db` would be `localhost` or an IP address - in this case, it is the name of the container that contains the database we want to connect to.

### 4- Running Node JS container connected to the Mongo db container

Once we have the Mongo db container running - and the database connection in the Node JS file is already configured to connect to this container - all we need to do now is start this Node JS container using the same network as the Mongo container uses.

`docker run -d --rm  -p 3000:3000 --network my_app_net --name my_app my_node_img`

Where `my_app_net` is the above created network, `my_app` is the name of this container and `my_node_img` is the name of the image which this container is based on.

**And that’s all. Now you know how to connect containers using Docker container networking.** :)

You can read more about [networking in the Docker documentation](https://docs.docker.com/network/).

## Connecting containers to services installed on our host machine

When we want to connect to a service installed on our host machine from a Docker container, we have a different way of doing it.

Now, **let's imagine we have a Mongo database installed on our host machine instead of a container. When started, this service exposes a port that can be accessed using: `//localhost:27017/my_database_name`.**

In order to have this url working fine inside the container, and be able to execute CRUD on the db, we should replace `localhost` to `host.docker.internal`. This special domain will be understood by Docker and be translated to the IP address of our host machine as seen inside Docker container. So it will be something like:

```js
mongoose.connect(
  'mongodb://host.docker.internal:27017/my_database_name',
  ...
);
```

Read more about this [special Docker DNS name here](https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host).

## Conclusion

As we learned, communication between containers is easier to implement using the Docker network, so all we need to do is create a network and use it to run all the containers that must be connected.

We also saw that we can also use special Docker DNS names to connect services outside of Docker from our containers.

I hope you liked it.
See you next time! 😁