Docker Compose — First Compose File
Time to write your first compose.yml from scratch. We’ll create a simple Nginx web server — no Dockerfile needed, just a compose file.
Step 1 — Create a Project Directory
mkdir ~/compose-demo && cd ~/compose-demo
Step 2 — Create an HTML File
mkdir html
cat > html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Docker Compose Demo</title></head>
<body>
<h1>Hello from Docker Compose!</h1>
<p>This page is served by Nginx running in a Docker container,
managed by Docker Compose.</p>
</body>
</html>
EOF
Step 3 — Write the Compose File
cat > compose.yml << 'EOF'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
EOF
Let’s break down every line:
services: # Top-level key — defines containers
web: # Service name (you choose this)
image: nginx:alpine # Docker image to use
ports:
- "8080:80" # Map host:8080 → container:80
volumes:
- ./html:/usr/share/nginx/html:ro # Mount local html/ folder
Step 4 — Your Project Structure
compose-demo/
├── compose.yml
└── html/
└── index.html
That’s it — two files. The compose file tells Docker what to run, and the HTML folder has your content.
Step 5 — Start the Stack
docker compose up -d
Expected output:
[+] Running 2/2
✔ Network compose-demo_default Created
✔ Container compose-demo-web-1 Started
Notice what Compose created automatically:
- Network:
compose-demo_default(default network for the project) - Container:
compose-demo-web-1(project name + service name + instance number)
Step 6 — Test It
Open your browser to http://localhost:8080 or use curl:
curl http://localhost:8080
Expected output:
<!DOCTYPE html>
<html>
<head><title>Docker Compose Demo</title></head>
<body>
<h1>Hello from Docker Compose!</h1>
<p>This page is served by Nginx running in a Docker container,
managed by Docker Compose.</p>
</body>
</html>
Step 7 — Check Status
docker compose ps
NAME STATUS PORTS
compose-demo-web-1 Up 0.0.0.0:8080->80/tcp
Step 8 — View Logs
docker compose logs web
web-1 | /docker-entrypoint.sh: Configuration complete; ready for start up
web-1 | 172.18.0.1 - - [01/Jan/2025:00:00:00 +0000] "GET / HTTP/1.1" 200 ...
Step 9 — Clean Up
docker compose down
[+] Running 2/2
✔ Container compose-demo-web-1 Removed
✔ Network compose-demo_default Removed
What Just Happened
compose.yml ──→ docker compose up ──→ ┌──────────────┐
│ Network │
│ (default) │
├──────────────┤
│ Container │
│ nginx:alpine │
│ port 8080→80 │
│ volume mount │
└──────────────┘
docker compose down ──→ Everything removed ✓
Summary
| Step | Command / File |
|---|---|
| Create project dir | mkdir ~/compose-demo && cd ~/compose-demo |
| Write compose file | compose.yml with services, image, ports, volumes |
| Start | docker compose up -d |
| Test | curl http://localhost:8080 |
| Check status | docker compose ps |
| View logs | docker compose logs web |
| Stop | docker compose down |
Quick Reference
| Item | Detail |
|---|---|
| Minimum compose file | services: + one service with image: |
| Start in background | docker compose up -d |
| Check status | docker compose ps |
| View logs | docker compose logs service-name |
| Stop and clean | docker compose down |
| Volume mount | ./local:/container/path:ro |