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.