In this article, you can get training on setting up a multi-container application using Docker. Docker is a powerful tool that simplifies the process of managing multiple services within a single application. By using Docker and Docker Compose, developers can streamline deployment and environment configuration, making it easier to develop and manage applications.
Creating a docker-compose.yml File
To get started with Docker Compose, the first step is to create a compose file. This file defines the services that make up your application, their configurations, and the relationships between them. The structure of the compose file is crucial as it provides Docker with the necessary instructions to build and run your application.
Here’s a basic example of what a docker-compose.yml
file might look like for a simple web application with a frontend and a backend service:
services:
web:
image: nginx:latest
ports:
- "80:80"
networks:
- my-network
db:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
networks:
- my-network
backend:
build: ./backend
ports:
- "3000:3000"
networks:
- my-network
In this example, we define three services: web, backend, and db (the database).
Defining Services in Your Application
Each service in the docker-compose.yml
file represents a specific component of your application. You can define various properties, such as image, build, ports, and volumes.
- Image: Specifies which Docker image to use for the service. In the frontend, we use the official Nginx image.
- Build: Indicates the context for building a custom Docker image. In this case, the backend service will build an image from the Dockerfile located in the .
/backend
directory. - Ports: Maps the container's ports to the host machine's ports. This allows you to access the services from your local machine.
- Volumes: Used to persist data or share files between the host and the container. For instance, the frontend service mounts the local
./frontend
directory to the container’s HTML directory.
Example of a Dockerfile for the Backend Service
To build the backend service, you need a Dockerfile
. Here’s a simple example using Flask:
# Use the official Python image from Docker Hub
FROM python:3.8-slim
# Set the working directory
WORKDIR /app
# Copy requirements.txt and install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy the application code
COPY . .
# Expose the port the app runs on
EXPOSE 5000
# Command to run the application
CMD ["python", "app.py"]
This Dockerfile sets up a minimal Python environment for a Flask application. The dependencies are installed, and the application is copied into the container before it starts.
Configuring Networking for Multi-Container Setup
Docker Compose creates a default network for your application, allowing all services to communicate with each other. This is particularly useful for microservices architectures, where different services need to interact.
To configure networking, you can add a networks section to your docker-compose.yml
file:
services:
web:
image: nginx:latest
ports:
- "80:80"
networks:
- my-network
db:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
networks:
- my-network
backend:
build: ./backend
ports:
- "3000:3000"
networks:
- my-network
networks:
my-network:
driver: bridge
In this example, all services are connected to a custom network named my-network
. This allows them to communicate with each other while keeping them isolated from other Docker containers on different networks.
Each service in the docker-compose.yml
can communicate with others using their service names. For example, if the backend service needs to connect to the database, it can use db
as the hostname:
import os
import psycopg2
connection = psycopg2.connect(
dbname=os.environ['POSTGRES_DB'],
user=os.environ['POSTGRES_USER'],
password=os.environ['POSTGRES_PASSWORD'],
host='db' # Referring to the db service
)
This configuration simplifies connection management and reduces the need for hardcoding IP addresses.
Managing Data with Volumes
Volumes are essential for managing persistent data in Docker containers. They allow you to store data outside of the container's filesystem, ensuring that it isn’t lost when containers are stopped or removed.
In our example, you can add a volume to the database service to persist PostgreSQL data:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
db:
image: postgres:latest
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
volumes:
- db_data:/var/lib/postgresql/data
backend:
build: ./backend
ports:
- "3000:3000"
volumes:
db_data:
This configuration will create a named volume called db_data that stores the database’s data files, ensuring data persistence across container restarts.
Building and Running Your Multi-Container Application
To build and run the entire application, navigate to the directory containing your compose file and execute the following command:
docker compose up --build
docker-compose up --build -d # To run the containers in detached mode
The --build
flag ensures that Docker Compose rebuilds the images if there have been any changes to the Dockerfiles or application code. Once the containers are running, you can access the frontend service by navigating to http://localhost
in your web browser.
To stop the application, you can simply press CTRL+C
in the terminal. If you want to remove the containers and networks created by Docker Compose, you can use:
docker compose down
Scaling Services with Docker Compose
One of the powerful features of Docker Compose is the ability to scale services easily. If you want to run multiple instances of your backend service for load balancing, you can use the --scale
option:
docker compose up --scale backend=3
This command will launch three instances of the backend service, allowing it to handle more requests simultaneously. You can also define a replicas key within the service definition in the compose file for more permanent scaling configurations.
backend:
deploy:
replicas: 3
Summary
In this article, we walked through the process of setting up a multi-container application using Docker. We began by creating a docker-compose.yml
file to define our services and their configurations. We then explored networking, data management using volumes, and how to build and run the application.
Last Update: 21 Jan, 2025