5 docker run commands reduced to 1 docker compose up—Compose transforms multi-container deployment from manual operations to declarative configuration.
1. What You'll Learn
Structure and Syntax of docker-compose.yml
Service Definition and Dependency Control
Declarative Management of Volumes and Networks
Environment Variable Management Strategies
Common Docker Compose Commands
2. A Developer’s True Story
(1) Pain Point: Having to run 5 docker run commands every time I debug
Every time Alice debugs, she has to manually type five docker run commands to start the four containers—Web, DB, Cache, Queue, and Worker—which involves many parameters, requires the correct order, and makes it easy to mistype environment variables. Once, she forgot to include --network app-net and spent an hour troubleshooting why the Web container couldn’t connect to the database.
(2) Solutions for Declarative Configuration in Docker Compose
Bob wrote a docker-compose.yml file, so from now on, Alice only needs to docker compose up -d.
Deployment has been reduced from 5 commands plus manual configuration to just 1 docker compose up -d. Newcomers can get the entire project up and running in 5 minutes.
💡 Tip:depends_on: [db] (default) only waits for the DB container to start; it does not wait for PostgreSQL to be ready. The API may attempt to connect before the DB is ready and fail. condition: service_healthy ensures that the API does not start until PostgreSQL is truly ready.
6. Volumes and Networks Declarations
▶ Example: Declaring Volumes and Networks (Difficulty: ⭐⭐)
📌 Key Point:${VAR:-default} Syntax: If VAR is not set, use the default value. This way, the compose file has default values, which are overridden by the .env file in the production environment.
8. Common Docker Compose Commands
Command
Function
Example
docker compose up -d
Start all services (background)
docker compose up -d
docker compose down
Stop and delete all containers/networks
docker compose down
docker compose down -v
Delete volumes simultaneously
docker compose down -v
docker compose ps
View Service Status
docker compose ps
docker compose logs
View Log
docker compose logs -f api
docker compose exec
Enter Container
docker compose exec api bash
docker compose build
Rebuild Image
docker compose build api
docker compose pull
Fetch the latest image
docker compose pull
docker compose config
Verify and display the merged configuration
docker compose config
▶ Example: Start with docker compose up -d (Difficulty: ⭐)
BASH
# Start all services in detached mode
docker compose up -d
# Follow logs from all services
docker compose logs -f
# Follow logs from a specific service
docker compose logs -f api
▶ Example: Entering a container using docker compose exec (Difficulty: ⭐)
BASH
# Open shell in the api service container
docker compose exec api bash
# Run a one-off command
docker compose exec db psql -U postgres -d myapp
▶ Example: docker compose down cleanup (Difficulty: ⭐)
BASH
# Stop and remove containers + networks
docker compose down
# Also remove named volumes (WARNING: deletes data)
docker compose down -v
# Also remove images
docker compose down --rmi all
# Deploy
docker compose up -d
# Verify
docker compose ps
docker compose logs -f wordpress
# Access WordPress
# Open http://localhost:8080 in browser
# Clean up (keeps data)
docker compose down
# Clean up everything (deletes data)
docker compose down -v
❓ FAQ
Q Which version should I use for docker-compose.yml?
A The new Docker Compose V2 no longer requires the version field. You can start writing directly from services:. If you see version: "3.8" in older tutorials, you can delete it—V2 ignores it.
Q Does depends_on guarantee that the service is ready?
A By default, depends_on: [db] only ensures that the db container starts; it does not guarantee that PostgreSQL is ready. You must add condition: service_healthy to wait until the health check passes. This is the most common pitfall for Compose beginners—the service starts, but the connection fails because the dependency is not ready.
Q How are environment variables managed in Compose files?
A Three-tier management: ① The environment block in docker-compose.yml (non-sensitive default values); ② The .env file (environment-specific values, not committed to Git); ③ The ${VAR:-default} syntax (as a fallback for default values). Do not include sensitive passwords in YAML; use a .env file + .gitignore instead.
Q Does docker compose down delete data volumes?
A By default, it does not. docker compose down Only containers and networks are deleted; Named Volumes are retained. You must add -v to delete the volumes. Do not use down -v in production environments; use only down.
Q What is the purpose of the Compose project name?
A The project name isolates the resources of different Compose applications. By default, it uses the name of the current directory. docker compose -p myproject up You can customize the project name. Multiple Compose projects can run on the same machine without interfering with one another.
📖 Summary
docker-compose.yml: Replaces multiple docker run commands with declarative YAML
The three main fields: services (container definitions), volumes (persistent volumes), and networks (networks)
depends_on + condition: service_healthy Ensure that dependencies are truly ready
Environment variables: Three-tier management using the environment block, env_file, and ${VAR:-default}
docker compose up -d One-click startup, docker compose down One-click cleanup
docker compose config Validate the syntax of configuration files to avoid discovering errors at runtime
📝 Exercises
Basic Problem (Difficulty ⭐): Write a docker-compose.yml file for the Phase 1 LEMP stack (Nginx+PHP+MySQL) and start it using docker compose up -d.
Advanced Exercise (Difficulty: ⭐⭐): Add depends_on and healthcheck to the compose file to ensure that PHP-FPM starts only after MySQL is ready.
Challenge (Difficulty: ⭐⭐⭐): Use docker compose logs to troubleshoot a service that failed to start, analyze the logs to identify the root cause, and fix the issue.
Web-Tutorial Tech Team
A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.