
Docker Compose orchestrates multi-container applications on a single host. Define all services, networks, and volumes in one YAML file. Use for development, testing, and simple production deployments.
| Item | Syntax | Description |
|---|---|---|
| version | version: '3.9' | Compose file version (3.9 = latest) |
| services | services: | Container definitions |
| image | image: nginx:alpine | Use existing image |
| build | build: . / build: {context:., dockerfile:Dockerfile} | Build from Dockerfile |
| ports | ports: - '8080:80' | Host:container port mapping |
| environment | environment: - NODE_ENV=production | Set environment variables |
| env_file | env_file: .env | Load variables from file |
| volumes | volumes: - ./data:/app/data | Bind mount or named volume |
| depends_on | depends_on: [db, redis] | Start order dependency |
| depends_on condition | depends_on: db: condition: service_healthy | Wait for health check to pass |
| healthcheck | test: ['CMD','curl','-f','http://localhost/health'] | Container health check |
| restart | restart: unless-stopped / always / on-failure | Restart policy |
| networks | networks: - backend | Connect to network |
| network driver | driver: bridge / overlay / host | Network type |
| named volume | volumes: mydata: | Define named volume at top level |
| profiles | profiles: [tools] | Only start with --profile tools |
| deploy | deploy: replicas: 3 resources: limits: | Swarm mode deployment config |
| command | command: python app.py | Override default CMD |
| entrypoint | entrypoint: /docker-entrypoint.sh | Override ENTRYPOINT |
| secrets | secrets: - db_password | Use Docker secrets (Swarm) |
| configs | configs: - nginx_conf | Use Docker configs |
| extend | extends: file: base.yml service: web | Extend another service definition |
| up | docker compose up -d | Start all services detached |
| down | docker compose down -v | Stop and remove containers (and volumes with -v) |
| logs | docker compose logs -f service | Stream logs from service |
| exec | docker compose exec web bash | Shell into running service |
| scale | docker compose up -d --scale web=3 | Run multiple instances |
# docker-compose.yml — Full stack MyWebUniversity
services:
# ── Web / CGI server ────────────────────────────────────────
web:
build:
context: .
dockerfile: Dockerfile
args:
ENVIRONMENT: production
image: mywebuniversity/web:latest
container_name: mywebuniversity_web
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/var/www/React/prod:ro
- ./cgi-bin:/usr/lib/cgi-bin:ro
- ./ssl:/etc/ssl/mywebuniversity:ro
- ./logs:/var/log/apache2
environment:
APACHE_RUN_USER: www-data
APACHE_RUN_GROUP: www-data
depends_on:
db:
condition: service_healthy
cache:
condition: service_started
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
networks:
- frontend
- backend
# ── Database ────────────────────────────────────────────────
db:
image: postgres:16-alpine
container_name: mywebuniversity_db
environment:
POSTGRES_DB: mywebuniversity
POSTGRES_USER: ${DB_USER:-admin}
POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD is required}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./sql/init.sql:/docker-entrypoint-initdb.d/01_init.sql:ro
ports:
- "127.0.0.1:5432:5432" # localhost only
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
# ── Cache ───────────────────────────────────────────────────
cache:
image: redis:7-alpine
container_name: mywebuniversity_cache
command: >
redis-server
--maxmemory 256mb
--maxmemory-policy allkeys-lru
--requirepass ${REDIS_PASSWORD:-changeme}
--save 900 1 --save 300 10
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- backend
# ── Admin tools (only with --profile tools) ─────────────────
pgadmin:
image: dpage/pgadmin4:latest
environment:
PGADMIN_DEFAULT_EMAIL: admin@mywebuniversity.com
PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD:-admin}
ports:
- "127.0.0.1:5050:80"
depends_on: [db]
profiles: [tools]
networks:
- backend
volumes:
postgres_data:
redis_data:
networks:
frontend:
name: mywebuniversity_frontend
backend:
name: mywebuniversity_backend
internal: true # no external access
# ── .env file (never commit!) ─────────────────────────────────
# DB_PASSWORD=supersecretpassword
# REDIS_PASSWORD=redispassword
# PGADMIN_PASSWORD=pgadminpassword
# ── Commands ──────────────────────────────────────────────────
# docker compose up -d # start all services
# docker compose up -d --profile tools # include pgadmin
# docker compose down # stop (keep volumes)
# docker compose down -v # stop + delete volumes
# docker compose logs -f web # stream web logs
# docker compose exec web bash # shell into web
# docker compose ps # show status
# docker compose pull # update images
# docker compose build --no-cache # rebuild images