Docker Compose

Docker Compose is a tool that lets you define and manage multi-container Docker applications using a single configuration file. Instead of manually running multiple docker run commands, you use a docker-compose.yml file to configure your application's services, networks, and volumes all in one place.



In this tutorial, you'll learn what Docker Compose is, how it works, how to write the docker-compose.yml file, and how to build a practical setup using Nginx, PHP, and MySQL, all connected through Docker Compose.

What is Docker Compose?

Docker Compose is a command-line tool that helps you define and run multi-container Docker applications. It uses a docker-compose.yml file to describe the setup:

  • Services – containers like web servers, PHP processors, and databases
  • Networks – how containers communicate with each other
  • Volumes – persistent data outside the containers

Once configured, you can launch your entire stack using:

docker compose up

You can also stop and remove everything with:

docker compose down

Why Use Docker Compose?

Docker Compose simplifies development with multiple containers. Benefits include:

  • Quick setup of complex stacks
  • Consistent development environments
  • Isolated services per project
  • Code-based infrastructure
  • One command to manage everything

How to Install Docker Compose

Docker Compose comes with Docker Desktop for Windows and macOS.

For Linux:

sudo apt update
sudo apt install docker-compose-plugin

Verify installation:

docker compose version

Understanding the docker-compose.yml File

The docker-compose.yml file describes how containers run together. Here's a general format:

version: "3.9"  # Compose file format

services:
  app:
    image: your-image
    build: ./app
    ports:
      - "8000:80"
    volumes:
      - ./app:/app
    environment:
      - ENV_VAR=value
    depends_on:
      - db
    networks:
      - backend

volumes:
  your_volume:

networks:
  backend:

Key Sections Explained

Section Description
version Compose file format version
services Defines containers to run
image Docker image to use
build Path to a Dockerfile to build a custom image
ports Maps host:container ports
volumes Mounts local folders or named volumes
environment Sets environment variables
depends_on Sets startup order for containers
command Overrides the default container command (optional)
networks Assigns the container to custom networks

How to Use Docker Compose

Let's set up a real web stack with:

  • Nginx as the web server
  • PHP-FPM for processing PHP
  • MySQL as the backend database
  • Local project files outside the containers
  • Persistent MySQL data using volumes

Project Setup

Your project directory should look like this:

www/
├── project/
│   └── index.php
├── nginx.conf
└── docker-compose.yml

Step 1: Write a PHP File

Create the file at www/project/index.php:

<?php
$host = 'db';
$db   = 'appdb';
$user = 'webuser';
$pass = 'webpass';

// Attempt MySQL connection
$conn = new mysqli($host, $user, $pass, $db);

// Check the connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

echo "<h1>Connected to MySQL successfully!</h1>";
$conn->close();
?>

Step 2: Nginx Configuration

Create the file www/nginx.conf:

server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
    }
}

Step 3: Define the Compose File

Create www/docker-compose.yml:

version: "3.9"

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./project:/var/www/html
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - php
    networks:
      - backend

  php:
    image: php:8.1-fpm
    volumes:
      - ./project:/var/www/html
    networks:
      - backend

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: appdb
      MYSQL_USER: webuser
      MYSQL_PASSWORD: webpass
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - backend

volumes:
  db_data:

networks:
  backend:

Step 4: Start the Application

Navigate to the www/ folder and run:

docker compose up -d

This will:

  • Start all containers
  • Map port 8080 to your Nginx container
  • Serve PHP files
  • Connect to MySQL using the defined environment

Visit: http://localhost:8080

You should see:  Connected to MySQL successfully!

Step 5: Stop and Remove Everything

To stop and remove containers, networks, and volumes:

docker compose down

MySQL data remains in the named volume db_data.

Essential Docker Compose Commands

Command Description
docker compose up Start all services
docker compose up -d Start in background (detached mode)
docker compose down Stop and remove services and networks
docker compose ps List running containers
docker compose logs Show logs for all services
docker compose logs web Show logs for a specific service
docker compose exec web bash Access a container's shell
docker compose stop Stop services without removing them
docker compose restart Restart services
docker compose build Rebuild service images
docker compose up --force-recreate Recreate containers even if unchanged
docker compose down --volumes Remove volumes with services

Conclusion

In this tutorial, you learned how to:

  • Install and verify Docker Compose
  • Understand the structure of a docker-compose.yml file
  • Use Docker Compose to orchestrate multiple services
  • Set up a full Nginx + PHP + MySQL environment
  • Serve local files and persist database data
  • Use essential Compose commands for control and maintenance


Found This Page Useful? Share It!
Get the Latest Tutorials and Updates
Join us on Telegram

Keep W3schools Growing with Your Support!
❤️ Support W3schools