Back to Blog

Docker Compose Tutorial: Deploy 10 Services in One File

Master Docker Compose by deploying a complete homelab stack. Learn to configure multiple services, networks, volumes, and environment variables in a single compose file.

Posted by

Docker Compose multi-service deployment

The Power of Docker Compose

Docker Compose transforms complex multi-container deployments into a single YAML file. Instead of running multiple docker commands, you define your entire infrastructure as code and deploy it with one command.

In this tutorial, we'll build a complete homelab stack with 10 services that work together seamlessly.

Complete Homelab Stack

This Docker Compose file includes: Traefik (reverse proxy), Portainer, Nextcloud, Jellyfin, Vaultwarden, Pi-hole, Uptime Kuma, Heimdall, Watchtower, and Wireguard.

version: "3.8"

networks:
  homelab:
    driver: bridge

services:
  # Reverse Proxy
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik:/etc/traefik
    networks:
      - homelab

  # Container Management
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    networks:
      - homelab

  # Cloud Storage
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud
    restart: unless-stopped
    volumes:
      - nextcloud_data:/var/www/html
    environment:
      - MYSQL_HOST=nextcloud-db
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=${DB_PASSWORD}
    networks:
      - homelab

  # Media Server
  jellyfin:
    image: jellyfin/jellyfin:latest
    container_name: jellyfin
    restart: unless-stopped
    volumes:
      - jellyfin_config:/config
      - ./media:/media
    networks:
      - homelab

  # Password Manager
  vaultwarden:
    image: vaultwarden/server:latest
    container_name: vaultwarden
    restart: unless-stopped
    volumes:
      - vaultwarden_data:/data
    environment:
      - WEBSOCKET_ENABLED=true
    networks:
      - homelab

Environment Variables

Create a .env file for sensitive configuration:

# .env file
DB_PASSWORD=your_secure_database_password
DOMAIN=homelab.local
[email protected]
TIMEZONE=America/New_York

Essential Commands

# Start all services
docker compose up -d

# View logs
docker compose logs -f

# Stop all services
docker compose down

# Update all images
docker compose pull && docker compose up -d

# Restart single service
docker compose restart jellyfin

Best Practices

  • Always use named volumes for persistent data
  • Keep secrets in .env files (never commit them)
  • Use a dedicated network for inter-service communication
  • Set restart policies for automatic recovery
  • Pin image versions in production

Continue Reading