In this tutorial, we'll explain how to deploy multi-container applications with docker compose.
Docker Compose is a tool for defining and running multi-container Docker applications. It allows you to define your application's services, networks, and volumes in a single YAML file, making it easier to manage and scale complex applications.
Prerequisites
- A Linux dedicated server or KVM VPS (Ubuntu 20.04 or later)
- Docker installed on your server
- Basic knowledge of Docker and containerization
- A user account with sudo privileges
Multi-Container Applications with Docker Compose
Step 1: Install Docker and Docker Compose
If you haven't installed Docker and Docker Compose yet, follow these steps:
First install Docker. Execute following set of commands:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Install the Docker packages.
sudo apt-get install docker-ce
Download the latest version of Docker Compose:
sudo curl -L "https://github.com/docker/compose/releases/download/$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep -oP '"tag_name": "\K(.*)(?=")')/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Apply executable permissions to the binary:
sudo chmod +x /usr/local/bin/docker-compose
Verify the installation:
docker-compose --version
Docker Compose helps manage multi-container Docker applications. We'll use it to simplify the management of our Flask application.
Step 2: Create a Docker Compose YAML File
In this step, you'll define your multi-container application using a docker-compose.yml
file. For demonstration, we'll deploy a simple web application consisting of an Nginx web server and a MySQL database.
Create a project directory:
mkdir my_app && cd my_app
Create the docker-compose.yml
file:
nano docker-compose.yml
Define the services in the docker-compose.yml file:
Here's an example configuration:
services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
db:
image: mysql:9.0
environment:
MYSQL_ROOT_PASSWORD: example_root_password
MYSQL_DATABASE: example_db
MYSQL_USER: example_user
MYSQL_PASSWORD: example_password
volumes:
- db_data:/var/lib/mysql
networks:
- app-network
volumes:
db_data:
networks:
app-network:
- services: Defines the services that make up your application.
- web: Defines the Nginx web server service.
- db: Defines the MySQL database service.
- volumes: Defines persistent data storage for the database.
- networks: Defines the custom network for inter-service communication.
Step 3: Deploy the Application
With the docker-compose.yml file ready, you can now deploy the application.
Start the services:
sudo docker-compose up -d
The -d
flag runs the containers in the background (detached mode).
Verify that the containers are running:
sudo docker-compose ps
You should see the web and db services running.
Test the application:
Open your browser and navigate to your server's IP address. You should see the Nginx welcome page.
Step 4: Manage the Application
Docker Compose makes it easy to manage your multi-container application.
Stop the application:
sudo docker-compose down
This command stops and removes the containers, networks, and volumes defined in your docker-compose.yml file.
Restart the application:
sudo docker-compose up -d
View logs:
To view the logs for a specific service, use:
sudo docker-compose logs <service_name>
For example:
sudo docker-compose logs web
Step 5: Scale the Application
Docker Compose allows you to easily scale your services. For example, to scale the web service to run three instances:
sudo docker-compose up -d --scale web=3
Docker Compose will automatically load balance the requests between the instances.
Advanced Docker Compose Commands
For those looking to dive deeper into Docker Compose, here are some advanced commands and techniques that can help you optimize and manage your multi-container applications more effectively.
1. Viewing Detailed Container Information
To inspect detailed information about a specific service's container, use the following command:
sudo docker-compose exec <service_name> docker inspect <container_id>
This command provides detailed JSON output about the container's configuration, status, and resource usage.
2. Running One-Time Commands
You can execute one-time commands in a running service container. For example, to open a bash shell inside the web container:
sudo docker-compose exec web bash
Or to run a MySQL command inside the db container:
sudo docker-compose exec db mysql -u root -p
Note: Enter the password you have mentioned in docker-compose.yml
file as MYSQL_ROOT_PASSWORD
.
3. Building and Rebuilding Images
If your docker-compose.yml file includes a build context, you can build or rebuild images using:
sudo docker-compose build
To rebuild a specific service:
sudo docker-compose build <service_name>
To force a rebuild without using the cache:
sudo docker-compose build --no-cache
4. Checking Resource Usage
To monitor the CPU, memory, and other resource usage of your containers:
sudo docker-compose top
This command displays the resource usage statistics for each service.
5. Creating and Using Overrides
Docker Compose allows you to define an override file, typically named docker-compose.override.yml, which can be used to customize or extend the base configuration. Docker Compose automatically applies overrides when you run docker-compose up.
Example:
# docker-compose.override.yml
services:
web:
environment:
- DEBUG=true
This override file sets an additional environment variable in the web service, useful for debugging.
6. Removing Orphans
When you update your docker-compose.yml file and remove services, old containers may become "orphans." To remove these orphan containers:
sudo docker-compose up -d --remove-orphans
This ensures that your environment remains clean and free of unused containers.
7. Viewing Configuration
To see how Docker Compose interprets your docker-compose.yml
file, use:
sudo docker-compose config
This command validates your configuration and displays the full, expanded configuration that Docker Compose uses.
8. Using Multiple Compose Files
You can use multiple Docker Compose files together, which is useful for separating base configuration from environment-specific settings (e.g., development, production).
sudo docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
This command merges the configurations from docker-compose.yml and docker-compose.prod.yml and starts the services.
9. Exporting Docker Compose Logs
If you need to analyze logs later, you can export them to a file:
sudo docker-compose logs > logs.txt
This command captures all logs from your services and saves them to logs.txt.
10. Using Health Checks
You can define health checks in your docker-compose.yml
file to ensure that your services are running correctly:
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
Health checks help ensure that only healthy containers receive traffic, improving the reliability of your application.
Conclusion
We've successfully seen how to deploy a multi-container application using Docker Compose. This setup is highly scalable and can be easily adapted to more complex applications. Docker Compose is a powerful tool that simplifies the deployment and management of containerized applications, making it an essential part of modern DevOps practices.
advanced Docker Compose commands offer powerful capabilities for managing and optimizing your multi-container applications. By mastering these commands, you can enhance your DevOps practices, improve application performance, and streamline deployments.