Composing Docker Environments: Networking
22 Sep 2016Web framework? Got it! Database? Yep! Today we are going to see how can we link both services through the Docker network. It can be a pretty simple and quick configuration, but it also exposes a mature surface to be explored. :whale:
Previously on Deploy Everyday
If you are arriving here for the first time, make sure you also read the introduction on Docker Compose and what services, images and builds mean. It’s a quick and (I hope) fun post 🙂
Getting started: jump to the following Git tag:
Also, as Django needs psycopg2
, our Docker web
image needs to be rebuilt. You can do that with:
Talk network to me
Computers network exists since, well, a lot of time. Modern web applications (and the old ones) depend heavily on them. Databases need to be connected to applications, APIs must answer HTTP requests, caches need to cache and proxies need to proxy. With Docker Compose, it’s easy to get all components working. In this post, we are going to connect Django web framework with a Postgres database, as they are by nature great friends.
To get our database powered application up and running, type this at the repository root:
After a couple seconds, open in your browser the address http://localhost:8000
. You’ll see a simple counter being incremented at every request. Neat.
docker-compose.yml barely changed!
Yep, I know. If you see the diff, the only parameters changed in our docker-compose.yml
file is:
- An
environment
variable to define our database password. - Change the
web
command to avoid race condition (what was done here is a poor implementation, see this article for a best practice!). - Tell out loud that
web
depends_on
db
. This does not provide any network configuration, just says thatweb
will not run without adb
.
The magic is: Docker Compose creates a default network out of the box, named by the project name (based on the project’s directory). To see all networks and their details, use these commands:
As the output shows, the network driver is a bridge
which allows communication between the container and its host (machine it lives on). It also has information about the IP addressing, scope, ID etc.
Another awesome trick Docker does is to create an entry in /etc/hosts
for all containers, mapping the service name to its IP address. What this means? Our web application can connect with the database by using something like postgres://db:5432
, as configured in our Django app:
Links, expose and ports
More cool stuff can be done with networking!
links
creates aliases to make a service reachable by another name, expose
exposes ports between the linked services and ports
exposes a container port to a host port (HOST:CONTAINER
), as we are already doing with the web application.
And to complete, Compose also allows to use custom networks and multi-hosting deployment, but this is a topic for another day 😉
Awesome, right?! Compose makes Docker networking stack pretty easy to use! If you have any doubts, drop a comment and I’ll be glad to chat!