Skip to main content

Docker Compose Quick Start

When you start repeatedly copying long docker run commands, or when you have more than one service, continuing to stitch together commands on the command line is usually not a good idea. At that point, writing the configuration into compose.yaml is more stable.

When Should You Switch to Compose​

I consider switching to Compose when any of the following appear:

  • More than one service
  • Need to pin ports, environment variables, and volumes
  • Want others to be able to start everything with one command
  • You've already written the startup commands into notes or scripts

A Minimal Usable compose.yaml​

services:
web:
image: nginx:stable
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped

redis:
image: redis:7
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
restart: unless-stopped

volumes:
redis-data:

This configuration does a few things:

  • Starts an nginx service, exposing port 8080
  • Mounts local ./html as the static page directory
  • Starts a redis service with data persisted to a named volume

Most Commonly Used Compose Commands​

Start​

docker compose up -d

Check Service Status​

docker compose ps

Follow Logs​

docker compose logs -f
docker compose logs -f web

Enter a Service Container​

docker compose exec web sh
docker compose exec redis redis-cli ping

Stop and Remove Containers​

docker compose down

If you also want to remove data volumes:

docker compose down -v

down -v will delete named volumes created by Compose. If you still need your database or cache data, don't run this casually.

A Command I Highly Recommend Using Often​

Before actually starting, preview the parsed Compose result:

docker compose config

This command is especially useful for troubleshooting:

  • YAML indentation issues
  • Environment variables not taking effect
  • Whether the final mounts and ports are what you intended

Relationship with docker run​

You can think of Compose as: consolidating the parameters needed for multiple docker run commands into a versionable file.

It is not opposed to docker run; rather, once the following information stabilizes, it moves them from the command line into YAML:

  • Image
  • Container name
  • Ports
  • Environment variables
  • Volumes
  • Network

Naming and File Location​

The current recommendation is to use:

compose.yaml

And the unified command:

docker compose ...

Rather than the older standalone docker-compose command.

A Practical Migration Rule of Thumb​

If your docker run has already grown to something like this:

docker run -d --name web \
--restart unless-stopped \
-p 8080:80 \
-e APP_ENV=prod \
-v app-data:/data \
--network app-net \
my-app:latest

Then it's already worth migrating to Compose.