🌐 Detecting your location…
📢 Advertisement — Configure AdSense in Appearance → Customize → AdSense Settings

Docker Compose Complete Guide 2026: Multi-Container Apps and Production

⏱️4 min read  ·  812 words

Docker Compose is the standard tool for running multi-container applications in development and production. In 2026, Docker Compose v2 with the new include directive, profiles, secrets management, and GPU support has made it more powerful than ever. This guide takes you from a single container to a full production stack.

Docker Compose v2 — What Changed

  • docker compose (no hyphen) — built-in to Docker CLI
  • Include directive — split compose files across multiple files
  • Profiles — selective service startup (dev vs prod)
  • Service dependencieshealthcheck-based startup ordering
  • Watch mode — auto-sync code changes without rebuilding
  • GPU supportdeploy.resources.reservations.devices

Basic compose.yaml

# compose.yaml (preferred name in 2026, Docker auto-discovers)
services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
      - REDIS_URL=redis://cache:6379/0
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    volumes:
      - .:/app
    networks:
      - backend

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: secret
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - backend

  cache:
    image: redis:7-alpine
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    networks:
      - backend

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - certs:/etc/nginx/certs
    depends_on:
      - web
    networks:
      - backend

volumes:
  postgres_data:
  redis_data:
  certs:

networks:
  backend:
    driver: bridge

Essential Docker Compose Commands

# Start all services
docker compose up -d

# View logs
docker compose logs -f            # all services
docker compose logs -f web        # specific service

# Rebuild and restart
docker compose up -d --build web

# Stop all
docker compose down

# Stop + remove volumes
docker compose down -v

# Execute command in running container
docker compose exec web bash
docker compose exec db psql -U postgres myapp

# Scale a service
docker compose up -d --scale worker=3

# Check service status
docker compose ps
docker compose top

# Validate compose file
docker compose config

Profiles: Dev vs Prod

services:
  web:
    build: .
    ports:
      - "8000:8000"
    # No profile = always started

  debug:
    image: busybox
    profiles: [dev]            # only with --profile dev
    network_mode: "service:web"

  flower:
    image: mher/flower
    profiles: [monitoring]
    ports: ["5555:5555"]
    environment:
      CELERY_BROKER_URL: redis://cache:6379/0

  prometheus:
    image: prom/prometheus
    profiles: [monitoring]
    ports: ["9090:9090"]

  grafana:
    image: grafana/grafana
    profiles: [monitoring]
    ports: ["3000:3000"]

# Start with dev profile
docker compose --profile dev up -d

# Start with monitoring
docker compose --profile monitoring up -d

# Combine profiles
docker compose --profile dev --profile monitoring up -d

Secrets Management

# Don't use plain environment variables for passwords in production!
services:
  web:
    environment:
      - DATABASE_URL=postgresql://postgres@db:5432/myapp
    secrets:
      - db_password
      - jwt_secret

  db:
    image: postgres:16-alpine
    secrets:
      - db_password
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt  # or use external: true for Docker Swarm secrets
  jwt_secret:
    environment: JWT_SECRET          # pull from host environment

Dockerfile Best Practices

# Multi-stage build for Python (production image)
FROM python:3.12-slim AS builder

WORKDIR /app
COPY requirements.txt .

# Install in a venv to isolate
RUN python -m venv /opt/venv &&     /opt/venv/bin/pip install --no-cache-dir -r requirements.txt

# Production image
FROM python:3.12-slim

# Security: don't run as root
RUN useradd --create-home appuser
WORKDIR /home/appuser

COPY --from=builder /opt/venv /opt/venv
COPY . .

ENV PATH="/opt/venv/bin:$PATH"
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

USER appuser
EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3   CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"

CMD ["gunicorn", "main:app", "--workers", "4", "--bind", "0.0.0.0:8000"]

Watch Mode (Development)

# compose.yaml — watch configuration
services:
  web:
    build: .
    develop:
      watch:
        - action: sync
          path: ./src
          target: /app/src
          ignore:
            - node_modules/
        - action: rebuild
          path: requirements.txt
        - action: rebuild
          path: Dockerfile

# Enable watch mode (auto-sync code changes)
docker compose watch

Production Compose Stack

# Use multiple compose files for environment overrides
docker compose   -f compose.yaml   -f compose.prod.yaml   up -d

# compose.prod.yaml overrides:
# - Remove bind mounts (no source code)
# - Use external secrets
# - Add resource limits
# - Set restart policies

# compose.prod.yaml
services:
  web:
    image: myapp:1.2.3          # specific image tag, not build
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: '3'

Docker Compose in 2026 covers the full development-to-production lifecycle. Use compose watch for fast local development, profiles for optional services, and multi-file composition to keep dev and prod configs clean.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা