A Guide to Docker Compose: Managing Multi-Container Applications
Learn how to use Docker Compose to define and run multi-container applications. This guide covers the basics of the docker-compose.yml file and shows you how to easily manage complex applications with a single command.
While Docker is fantastic for running individual application containers, most real-world applications are made up of multiple services. For example, a typical web application might have a web server, a database, and a caching service. Managing the lifecycle of all these containers manually with docker run
commands would be complex and error-prone.
This is the problem that Docker Compose solves. Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application's services, and then with a single command, you can create and start all the services from your configuration.
Why Docker Compose?
- Single Source of Truth: Your entire multi-service application is defined in a single
docker-compose.yml
file. - Simplicity: You can start, stop, and rebuild all the services of your application with a single command (
docker-compose up
,docker-compose down
). - Networking: Compose automatically sets up a network for your services, allowing them to discover and communicate with each other easily.
- Reproducibility: It makes it incredibly easy for any developer to get a complex application running on their local machine with a single command.
The docker-compose.yml
File
The heart of Docker Compose is the docker-compose.yml
file. This is a YAML file that defines the services, networks, and volumes for your application.
Let's look at an example for a simple web application that uses a web server and a Redis cache.
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "8000:5000"
volumes:
- .:/code
environment:
- FLASK_ENV=development
- REDIS_URL=redis://redis:6379
redis:
image: "redis:alpine"
Let's break down the key parts of this file:
version
: Specifies the version of the Compose file format.services
: This is the main section where you define your application's services.web
: This is the custom name we've given to our web server service.build: .
: Tells Compose to build the image for this service from theDockerfile
in the current directory.ports: - "8000:5000"
: Maps port 8000 on the host machine to port 5000 in the container.volumes: - .:/code
: Mounts the current directory on the host into the/code
directory in the container. This is great for development, as changes to your code are immediately reflected in the container.environment
: Sets environment variables inside the container.
redis
: This is the name of our Redis service.image: "redis:alpine"
: Tells Compose to pull theredis:alpine
image from Docker Hub. We don't need to build this one ourselves.
The Core Docker Compose Commands
With your docker-compose.yml
file in place, you can now manage your application with a few simple commands.
1. docker-compose up
This is the main command. It does everything needed to get your application running:
- Pulls or builds the necessary images.
- Creates a network for your services.
- Creates and starts the containers for your services.
docker-compose up
To run the containers in the background (detached mode), use the -d
flag:
docker-compose up -d
2. docker-compose down
This command stops and removes the containers, networks, and volumes created by up
.
docker-compose down
3. docker-compose ps
This command lists the containers running for your application.
4. docker-compose logs
This command shows the logs from your services.
# Show logs for all services
docker-compose logs
# Show logs for a specific service
docker-compose logs web
Service Discovery and Networking
One of the most powerful features of Docker Compose is its automatic networking. When you run docker-compose up
, it creates a default network and attaches all the services to it.
From within a container, you can refer to other services by their name. In our example, the web
service can connect to the Redis container using the hostname redis
.
This is why we set the REDIS_URL
environment variable to redis://redis:6379
. The web
container can resolve the hostname redis
to the IP address of the redis
container on the shared network.
Conclusion
Docker Compose is an essential tool for any developer working with Docker. It dramatically simplifies the process of managing multi-container applications, making it the standard for local development environments and a common choice for simple production deployments. By defining your entire application stack in a single, version-controllable docker-compose.yml
file, you create a development workflow that is simple, repeatable, and easy for anyone on your team to use.