Docker vs Docker Compose: What's the Difference?
Docker runs individual containers; Docker Compose describes and runs a group of containers that work together — your app, its database and a cache — from one YAML file. How they relate, the same setup with and without Compose, and the commands you'll use.
Docker runs containers. Docker Compose is a tool for running several containers together, described in one file. They aren't alternatives — Compose uses Docker. (What is Docker?)
With plain Docker
Running a web app with a Postgres database using only docker commands:
docker network create myapp
docker run -d --name db --network myapp \
-e POSTGRES_PASSWORD=secret \
-v pgdata:/var/lib/postgresql/data \
postgres:18
docker run -d --name web --network myapp \
-p 3000:3000 \
-e DATABASE_URL=postgresql://postgres:secret@db:5432/postgres \
myapp:latest
It works, but you have to remember all those flags, run them in the right order, and type them again every time.
With Docker Compose
The same setup, written down once in docker-compose.yml (or compose.yaml):
services:
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
web:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgresql://postgres:secret@db:5432/postgres
depends_on:
- db
volumes:
pgdata:
Then:
docker compose up -d
Both containers start, on a shared network, where web can reach the database at the hostname db. (Docker Compose for local development, What is YAML?)
Side by side
| Docker | Docker Compose | |
|---|---|---|
| Manages | One container per command | A group of related containers |
| Configuration | Command-line flags | A YAML file in your project |
| Networking | Create networks yourself | Automatic shared network |
| Start everything | Several commands | docker compose up |
| Repeatable / shareable | Hard | Commit the file, anyone runs it |
The commands you'll use
docker compose up -d # start everything in the background
docker compose up -d --build # rebuild images first
docker compose ps # what's running
docker compose logs -f web # follow one service's logs
docker compose exec db psql -U postgres # run a command inside a service
docker compose restart web
docker compose down # stop and remove containers (keeps volumes)
docker compose down -v # also delete volumes — ⚠ deletes database data
"docker-compose" vs "docker compose"
The original was a separate Python program, docker-compose (with a hyphen). It was replaced by Compose v2, built into Docker as docker compose (with a space). Use the space version; the old one is no longer maintained. The YAML format is the same.
When to use which
- One container, quick test:
docker run. - Anything with more than one piece — app + database, app + worker + Redis: Compose.
- Local development: Compose is the standard way to get a project's services running with one command.
- Small production deployments on a single server: Compose works well. (Do you need Kubernetes?)
- Many servers, auto-scaling, self-healing across machines: that's orchestration territory (Kubernetes, Swarm, Nomad).
Common mistakes
- Using
localhostbetween containers. Inside a container,localhostis the container itself. Use the service name (db). (ECONNREFUSED explained) depends_ondoesn't wait for "ready". It starts the database first but doesn't wait until it accepts connections. Add a healthcheck withcondition: service_healthy, or retry in your app.- Secrets in the YAML committed to Git. Use an
.envfile (git-ignored) that Compose reads automatically. (Environment variables) down -vby accident, wiping the database.
EasySpawn runs your app's services together on a server with persistent storage and backups, so you get the convenience of Compose without the server admin. See how it works or join the waitlist.
Related: What Is Docker? · Docker Compose for Local Development · Dockerfile Explained · Docker Volumes vs Bind Mounts
Keep reading
Docker Commands Cheat Sheet: The 40 You'll Actually Use
A practical Docker cheat sheet: running and stopping containers, viewing logs, getting a shell inside, building and tagging images, volumes, networks, Docker Compose, and cleaning up disk space — with what each command does in plain English.
zsh vs bash: What's the Difference and Which Should You Use?
bash and zsh are both shells — the programs that read your terminal commands. Why macOS switched to zsh, the differences you'll actually notice (config files, completion, globbing, arrays), Oh My Zsh, and why scripts should usually still be written for bash.