Docker & Containers

Run Multiple Containers Easily

Lesson 7 of 9 · 9 min · Intermediate

Running one container is fine, but real apps usually need a web server, a database, a cache, and an API. Starting each one manually with long docker run commands is painful. Docker Compose solves this instantly.

The "Combo Order" Concept



Docker Compose lets you define and run multi-container Docker applications using a single YAML file. It is heavily used in local development, automated testing, and small-scale production setups.

The Combo Meal

Imagine ordering food: Burger = Web app, Fries = Database, Drink = Cache. Instead of ordering each item one by one, you order a "Combo #1". Docker Compose is the combo order for your containers.

One File to Rule Them All

You declare networks, volumes, environment variables, and startup sequences inside docker-compose.yml. Docker reads it and provisions the entire stack.

The Heart of Compose: docker-compose.yml

docker-compose.yml
version: "3.9"

services:
  web:
    image: nginx
    ports:
      - "80:80"

  db:
    image: mysql:8
    environment:
      MYSQL_ROOT_PASSWORD: root

What happens here?

  • services Each container is called a service (e.g., web and db).
  • image & ports The web service pulls the Nginx image and maps host port 80 to container port 80.
  • environment The DB service spins up MySQL and automatically passes in the required root password.
  • execution Both containers start together and run as a single, cohesive application.

Advanced Compose Features

Networking (Service Discovery)

By default, Compose creates a single bridge network for the app. Containers can talk to each other using their service names as hostnames. The backend can reach the database simply by pinging db. No IP addresses needed!

⏱ Startup Order (depends_on)

You can use depends_on: - db under your web service. This ensures the database container starts first before the web container starts. Note: It only waits for the container to start, not for the DB software to be fully ready.

Build from Source

Instead of using prebuilt images from Docker Hub, you can tell Compose to build a local Dockerfile by using build: . instead of image:. Great for local development.

Volumes (Persistence)

Define a named volume at the bottom of the file, then map it to a service:

volumes:  - db_data:/var/lib/mysql

If you delete the container, your database data remains safe in the volume.

Environment Variables

You can define env vars directly in the file, or use an external .env file (the cleaner way). Compose automatically detects the .env file in the same directory and loads the values.

Compose CLI Cheat Sheet

One command replaces many complex docker run strings. Manage the entire lifecycle of your application stack from this single CLI tool.

terminal

# Start the Application
$ docker compose up              → Start everything (attaches logs to terminal)
$ docker compose up -d           → Start everything in the background (detached)
$ docker compose up --build      → Force a rebuild of custom images before starting

# Stop and Clean Up
$ docker compose down             → Stop and remove containers + networks
$ docker compose down -v          → Stop, remove containers, AND wipe volumes

Docker Compose vs Docker Swarm

FeatureDocker Compose Docker Swarm
PurposeLocal / simple multi-container setupsProduction-grade clustering
ScalingManual (via CLI flags)Automatic & Dynamic
NodesSingle host machineMultiple distributed hosts
ComplexitySimple Medium