Connect API and a Database with Docker Network
Tags: docker, node, postgres, devops
Published: 2021-06-02 09:58:37

Hi everyone,

This is a tutorial I am going to walk through how to run two docker containers, add them to a new docker network and communicate with each other.

for this, I am going to create a demo API with nodejs and a Postgres database in containers, and connect them to a docker network.  

so first I am creating a docker network. docker network is an isolated network layer, which allows you to add containers to it. we can assign these containers' IP addresses inside the network, and let them communicate. host to container port mapping is still available when using a network in a container. docker will create a `bridge` by default. 

to create a docker network 
```bash
docker network create --subnet 172.20.0.0/16 dockernetworkdemo
```
here I have specified a `subnet` with the value `172.20.0.0/16` in CIDR format. 

after we run this command we can check it using 
```bash
docker network ls
```
![docker network ls](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0e9rlaxyefcfe1pw562n.png)

we can also use 
```bash
docker network inspect dockernetworkdemo
```
to view more details about the network. 

here `dockernetworkdemo` is the name of the network we specified then creating the network.


![docker network inspect](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/71iqy1gg59c0sd2lqtvq.png)

now we have the network in place next move to the database. 
here we are going to use a Postgres database. 

to spin a Postgres database I will use 

```bash
docker run --name dockernetworkdemopg -p 6543:5432 -e POSTGRES_PASSWORD=123 -e POSTGRES_USER=postgres -e POSTGRES_DB=postgres -d postgres:10-alpine
```
in this command,

`dockernetworkdemopg` is the name of the container 

`-p 6543:5432` will map port `5432` in the container to `6543` host port. here I have used a different port because I have a Postgres database already running on port `5432`

`-e POSTGRES_PASSWORD=123 -e POSTGRES_USER=postgres -e POSTGRES_DB=postgres` here `-e` flag will pass an environment variable to the container, here we specify the password, user, and database. 

 `-d` flag will run this container in detached mode. 

`postgres:10-alpine` is the name and the tag of the Postgres image we are fetching from the [Docker Hub](https://hub.docker.com/). here I have chosen the alpine version because it is lightweight and smaller in size around 20 mb . 

now if we use 
```
docker ps 
```
command we can see that our Postgres container is up and running.

![docker ps](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5q84hqdnbsw6zes155o.png)

next, we are going to connect the Postgres container (`dockernetworkdemopg`) to the network (`dockernetworkdemo`) we created.

```bash
docker network connect --ip 172.20.0.5 dockernetworkdemo dockernetworkdemopg

```
here we have specified the IP of the connecting container to be `172.20.0.5` using `--ip` flag.

now if we run the network inspect command we can see 
the container we added. 

![inspect](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/807zwjgql4476tcbmkp1.png)

now we'll setup the API. I am using a simple nodejs API, and build a docker image.

{% github RizkyRajitha/dockernetworkdemo %}


```yml
FROM  node:current-alpine3.12

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm i

ENV NODE_ENV=production
ENV DBURL=postgres://postgres:123@172.20.0.5:5432/postgres
ENV PORT=3001

COPY . .

EXPOSE 3001

CMD [ "npm", "run" , "prod" ]
```

in the dockerfile, we have specified the environment variable `DBURL` to the Postgres container we ran earlier.

`ENV DBURL=postgres://postgres:123@172.20.0.5:5432/postgres`
 
in the connection string `postgres://postgres:123@172.20.0.5:5432/postgres`

`172.20.0.5:5432` is the IP address and the port of the Postgres container.`172.20.0.5` is the IP address we specified when connecting to the network. 

```bash
docker build -t dockernetworkdemoapi .
```

here `-t` will set the name and tag to `dockernetworkdemoapi:latest`

before running the images we have to create the database relation so that we can query data using the API . for that I am using a migration script to run some SQL commands. 

![migrate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82ylkhky01ow4uht5a8n.png)

because migration is running in the host machine, connection string is passed as `postgres://postgres:123@localhost:6543/postgres` with database IP as `localhost` and port as `6543` specified when running the Postgres database.

next, we will run the API image `dockernetworkdemoapi:latest` . 

```bash
docker run --name dockernetworkdemoapicont -p 3001:3001 dockernetworkdemoapi:latest
```

in the above command `--name` flag specifies the name of the container to be `dockernetworkdemoapicont`

`-p 3001:3001 ` to publish the ports with `3001` container port to `3001` host port. 

`dockernetworkdemoapi:latest` is the docker image. 

![api run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/slr3g9uwqdr7glcocgqi.png)

here i ran the container without detached mode so we can see the output.

now as the final step we are connecting the API (`dockernetworkdemoapicont`) container to the `dockernetworkdemo` docker network.

```bash
docker network connect dockernetworkdemo dockernetworkdemoapicont
```

now if we send a get request to the API we can see that API is able to connect to the database.

![api request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obterhot53q4rflpd7qt.png)

![api log](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a4tsmx0mpq5waxs71lr0.png)

final docker inspect output

![docker inspect ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vr6cdvyiwwljctch2vtm.png)

illustration of the network.

![diagram network](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/re53jiv75q9u543yl5g7.jpg)

## Thanks for reading till the end 🙌
## I value your opinions, and appreciate you taking the time to share your thoughts.