Docker  

How to Use Docker Compose for Multi-Container Applications

Introduction

When building modern applications, we rarely work with a single service. Most real-world applications include multiple components like a backend API, a database, a frontend, and sometimes a cache or message queue.

Managing all these services manually can quickly become complicated. This is where Docker Compose becomes very useful.

Docker Compose allows you to define and run multiple containers using a single configuration file. With just one command, you can start your entire application stack.

In this guide, you will learn how to use Docker Compose for multi-container applications in a simple, step-by-step, and practical way.

What is Docker Compose?

Docker Compose is a tool that helps you define and manage multi-container Docker applications.

In simple words:

  • You describe all your services in one file (docker-compose.yml)

  • You start everything with a single command

  • All containers can communicate with each other easily

It removes the need to run multiple docker commands manually.

Why Use Docker Compose?

Using Docker Compose gives several advantages:

  • Easy setup for multi-container applications

  • Saves time by managing everything in one place

  • Ensures consistency across development environments

  • Simplifies networking between containers

It is especially useful for developers working on microservices or full-stack applications.

Prerequisites

Before starting, make sure you have:

  • Docker installed on your system

  • Basic understanding of Docker containers

  • A sample application (API + Database)

You can install Docker Desktop to get everything set up easily.

Step 1: Understand the Project Structure

Let’s consider a simple application:

  • ASP.NET Core Web API (Backend)

  • SQL Server (Database)

Your folder structure may look like this:

  
    project-root/
  ├── api/
  │     └── Dockerfile
  ├── docker-compose.yml
  

Step 2: Create Dockerfile for Your Application

Inside your API folder, create a Dockerfile.

  
    FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . .
RUN dotnet publish -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "YourApp.dll"]
  

This Dockerfile builds and runs your ASP.NET Core application inside a container.

Step 3: Create docker-compose.yml File

Now create the main configuration file.

  
    version: '3.8'

services:
  api:
    build: ./api
    ports:
      - "5000:80"
    depends_on:
      - db

  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      SA_PASSWORD: "YourStrong@Password123"
      ACCEPT_EULA: "Y"
    ports:
      - "1433:1433"
  

Explanation in simple words:

  • services → Defines all containers

  • api → Your backend service

  • db → SQL Server container

  • depends_on → Ensures DB starts before API

  • ports → Maps container ports to your machine

Step 4: Run Docker Compose

Now run the following command:

  
    docker-compose up --build
  

What happens here:

  • Docker builds your API image

  • Starts database container

  • Starts API container

  • Connects both services automatically

Now your API is running at:

  
    http://localhost:5000
  

Step 5: Communication Between Containers

Docker Compose creates a default network.

This means your API can talk to the database using the service name.

Example connection string:

  
    Server=db;Database=MyDb;User Id=sa;Password=YourStrong@Password123;
  

Here, db is the service name defined in docker-compose.

Step 6: Stop and Remove Containers

To stop everything:

  
    docker-compose down
  

This will:

  • Stop all containers

  • Remove network

  • Clean up resources

Step 7: Use Volumes (Optional but Important)

To persist database data, use volumes.

  
    db:
  image: mcr.microsoft.com/mssql/server:2022-latest
  volumes:
    - db_data:/var/opt/mssql

volumes:
  db_data:
  

This ensures your data is not lost when containers stop.

Step 8: Environment Variables

You can store configuration using environment variables.

  
    api:
  environment:
    - ASPNETCORE_ENVIRONMENT=Development
  

This makes your application flexible and easier to configure.

Step 9: Best Practices for Docker Compose

Follow these best practices:

  • Keep services small and focused

  • Use environment variables for configuration

  • Use volumes for persistent data

  • Avoid hardcoding secrets

  • Use meaningful service names

Step 10: Real-World Example

In a real-world application, you may have:

  • Backend API

  • Frontend (React/Angular)

  • Database

  • Redis cache

Docker Compose can run all of them together with a single command.

Advantages of Docker Compose

  • Simplifies multi-container management

  • Improves development workflow

  • Ensures consistency across environments

  • Easy to scale services

Summary

Docker Compose is a powerful tool for managing multi-container applications in a simple and efficient way. By defining your services in a single file, you can start, stop, and manage your entire application stack with ease. It is especially useful for modern applications that depend on multiple services like APIs, databases, and frontends. By following this step-by-step approach, you can quickly set up and run your own multi-container application using Docker Compose.