Paperlive
HOME / BLOG / DOCKER COMPOSE TUTORIAL: RUN MULTI-CONTAINER APPS EASILY

Docker Compose Tutorial: Run Multi-Container Apps Easily

Docker Compose Tutorial: Run Multi-Container Apps Easily

Most real applications are not a single container. A typical web app needs an API, a database, a cache and perhaps a background worker. Starting each of these with long docker run commands, creating networks by hand and remembering the right environment variables quickly becomes error-prone. Docker Compose solves this by letting you describe the whole stack in one YAML file and start it with a single command.

This Docker Compose tutorial explains what Compose is, how the compose.yaml file is structured, the commands you will use every day, and the best practices that keep multi-container development fast and reliable.

What Is Docker Compose?

Docker Compose is a tool for defining and running multi-container applications. You declare services, networks and volumes in a YAML file, and Compose creates and connects everything for you. The same file can be shared with your team, committed to Git and reused in CI pipelines, so every developer runs an identical environment.

Modern Compose (version 2) ships as a plugin of the Docker CLI, so you run it as docker compose with a space. The older standalone docker-compose binary written in Python is no longer maintained, and the top-level version key in compose files is now optional and ignored.

If you are new to containers, start with our guide What Is Docker? before continuing.

Why Use Docker Compose?

  • One command for the whole stack: docker compose up starts every service in the right order.
  • Configuration as code: the Compose file documents how the application fits together and is version-controlled like any other code.
  • Automatic networking: services reach each other by name, without manual network setup.
  • Consistent environments: new team members can run the full application within minutes.
  • Easy testing: CI pipelines can spin up databases and dependencies with Compose, run integration tests and tear everything down.
Ready to become a DevOps engineer?
Industry-certified DevOps training online · 100% job-opportunity guarantee
Get Curriculum →

Key Concepts in Docker Compose

Services

A service is a container definition: the image or build context, ports, environment variables, volumes and dependencies. Compose can run one or many replicas of each service.

Networks

By default, Compose creates a single network for the project and attaches every service to it. Each service is reachable by its service name through built-in DNS, so the API can connect to the database at the hostname db.

Volumes

Named volumes keep data such as database files outside the container lifecycle, so it survives restarts and rebuilds. Bind mounts map a host folder into a container, which is useful for live code reloading in development.

Projects

A project is the set of containers, networks and volumes created from one compose file. Compose uses the folder name as the project name by default, which lets you run several isolated copies of a stack on one machine.

Docker Compose File Example

Here is a Compose file for a Node.js API with PostgreSQL and Redis:

services:
  api:
    build: ./api
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://app:secret@db:5432/appdb
      REDIS_URL: redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d appdb"]
      interval: 5s
      timeout: 3s
      retries: 10

  cache:
    image: redis:7-alpine

volumes:
  db-data:

Notice three things. The API connects to the hostnames db and cache, which are simply service names. The depends_on block with condition: service_healthy makes Compose wait until PostgreSQL passes its health check before starting the API. And the named volume db-data keeps database files safe when containers are recreated. The password is inline only for local demonstration; real credentials belong in an env file or secrets.

Essential Docker Compose Commands

  • docker compose up -d: build or pull images and start all services in the background.
  • docker compose ps: list the project's containers and their status.
  • docker compose logs -f api: follow the logs of one service.
  • docker compose exec db psql -U app: run a command inside a running service.
  • docker compose build: rebuild images after changing a Dockerfile.
  • docker compose down: stop and remove containers and networks. Add -v to also delete named volumes.
  • docker compose config: validate the file and print the fully resolved configuration.
  • docker compose watch: sync code changes into running containers automatically during development.

For broader Docker CLI usage, see our list of top Docker commands.

Environment Variables and Secrets in Compose

Compose reads a .env file in the project folder automatically and substitutes values written as ${VARIABLE} in the compose file. You can also load variables into a container with the env_file key. Keep .env files out of Git and commit a .env.example with placeholder values instead.

For sensitive values, Compose supports a top-level secrets section that mounts secrets as files inside the container rather than exposing them as environment variables. Learn more in our guide on how to secure secrets in Docker containers.

Profiles and Multiple Compose Files

As projects grow, one file rarely fits every situation. Compose offers two features for this:

  • Profiles: mark optional services, such as an admin UI or a load generator, with a profile. They start only when you run docker compose --profile tools up.
  • Override files: Compose automatically merges compose.override.yaml on top of compose.yaml, which is a neat way to add development-only settings like bind mounts and debug ports. You can also pass several files explicitly with -f.

Docker Compose in CI/CD Pipelines

Compose is a natural fit for integration testing. A pipeline job can run docker compose up -d --wait to start the application and its dependencies, wait for health checks to pass, run the test suite, and finish with docker compose down -v to clean up. Because the same file runs on laptops and build agents, tests behave consistently everywhere. See our guide on building a CI/CD pipeline from scratch for the bigger picture.

Docker Compose vs Kubernetes

Compose runs containers on a single host. It is ideal for local development, testing, demos and small single-server deployments. Kubernetes is a cluster orchestrator built for production at scale, with self-healing, rolling updates and autoscaling across many nodes. Many teams use Compose on developer machines and Kubernetes in production. Tools like Kompose can convert a Compose file into Kubernetes manifests as a starting point. Read Docker vs Kubernetes for a deeper comparison.

Docker Compose Best Practices

  1. Pin image versions. Use postgres:16 rather than latest so environments stay reproducible.
  2. Add health checks and use depends_on conditions so services start in a reliable order.
  3. Use named volumes for data and bind mounts only for source code in development.
  4. Keep secrets out of the compose file. Use .env files, the secrets section or a secrets manager.
  5. Set resource limits on heavy services so one container cannot starve the host.
  6. Keep images small with multi-stage builds. Our guide on reducing Docker image size shows how.
  7. Validate with docker compose config in CI to catch syntax errors early.

Common Docker Compose Mistakes

  • Using localhost to reach another service. Inside a container, localhost means the container itself; use the service name instead.
  • Expecting depends_on alone to wait for readiness. Without a health check condition, Compose only waits for the container to start.
  • Running docker compose down -v by habit and deleting database volumes by accident.
  • Publishing database ports to the host when only other services need them.
  • Treating Compose as a high-availability production platform for large systems.

Conclusion

Docker Compose turns a collection of containers into one reproducible application you can start, stop and share with a single command. Learn the core concepts of services, networks and volumes, add health checks, keep secrets out of your files and use profiles and overrides as the project grows. Once you are comfortable with Compose, the natural next step is container orchestration with our Kubernetes tutorial for beginners.

Get the curriculum

DevOps Course Online

100% secure · no spam · callback in 30 min

Recommended Course

Online DevOps course
BESTSELLER
AWSAzureGCPGen AI
Online DevOps Course
Job-Ready Program

Learn from Microsoft-certified experts with real projects, internship certification and dedicated placement support to help you land your next DevOps role.

6 Months
Duration
5–45 LPA
Opportunity range
300+ Hrs
Live sessions
IIT Patna
Certification
Next batch closing soon — limited seats
Live classes · 23 Nov
View full curriculum
© 2025 PAPERLIVE, All rights reserved

Disclaimer: PaperLive Learning offers skill-based training and professional upskilling courses only. Our programs are not postgraduate (PG) programs, diploma courses, or formal academic qualifications and do not award degrees or diplomas.

We strive to ensure that the information and pricing displayed on our website are accurate. However, course fees, content, duration, and promotional offers may change without prior notice. Applicable pricing at the time of enrollment will be communicated clearly.

Career outcomes depend on individual skills, effort, experience, performance, and market conditions. Placement statistics, salary figures, and success stories are for informational purposes only and do not guarantee similar results.

References to third-party platforms, certifications, and tools are for educational purposes only and do not imply endorsement or affiliation unless explicitly stated.