Multi-Container Applications with Docker Compose

By Anurag Singh

Updated on Aug 22, 2024

Multi-Container Applications with Docker Compose

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.