Full-Stack development with Docker Compose
This article gives a brief overview of how to setup inter-container communication with Docker Compose (version 3+) using any backend/database you prefer.
After reading this article you are able to connect your app with any other dockerized application and eventually to enrich your local development flow with services like postgres
, mongo
, redis
,nginx
, localstack
and many more.
Prerequisites
- Docker Compose installed
- Docker installed
For this tutorial I use docker version 20.10.5
and Docker Compose version 1.29.0
.
How inter-container networking works with Docker Compose
By default Docker Compose uses a bridge network to provision inter-container communication. You can read more about this network at the Debian Wiki.
What matters for us, is that by default Docker Compose creates a hostname that equals the service name in the docker-compose.yml
file.
Consider the following docker-compose.yml
:
When you rundocker-compose up
, Docker will create a default network and assigns the service name as hostname for both mongo
and server
.
To verify, rundocker-compose up -d
and it will create 2 containers, the first container called server
is a NodeJS backend container. The second container called mongo
is a Mongo database.
Run docker container ls
or docker ps
to log our running containers:
Let’s now verify if we can connect from our backend to our database. Our service name is called mongo
and thus our hostname for our MongoDB should be mongo
plus the default port 27017
as stated in the official docs.
First let us access our backend container:
docker exec -it server bash
The output will be something like:
root@634a3a3b003d:/#
Now we can ping our MongoDB using Dockers internal network:
curl -v http://mongo:27017/my-database
The output should end with something like:
< It looks like you are trying to access MongoDB over HTTP on the native driver port.
Great! We now know, we can connect with our database!
Connect with multiple services in Docker Compose
Now we know that we can connect with a single service, let’s try to connect with a bunch of different services. Consider the following docker-compose.yml
:
We added 2 new services: redis
and postgres
and updatet our server to ubuntu
. To verify if we can connect with all the services from our backend we follow the same steps as earlier:
docker exec -it server bash
The output should be something like:
root@634a3a3b003d:/#
Now we first have to install curl, as it did not come out-of-the-box with Ubuntu. Run:
apt-get update && apt-get install -y curl
We can now ping bothredis
as postgress
and again mongo
.
curl -v http://redis:6379
curl -v http://postgres:5432
curl -v http://mongo:27017
Again, we verified the hostname is resolved and we can connect with all our services!
Conclusion
When using Docker Compose in your development flow, simply keep in mind that the default hostname with Docker Compose equals the service name defined in your docker-compose.yml
.