Ejemplos de Docker Compose

Ejemplos de configuración Docker Compose para orquestación de contenedores y aplicaciones multi-servicio

⚙️ Aplicación Web Básica

🟢 simple

Configuración simple de aplicación frontend-backend separada

# Basic Web Application Stack
version: '3.8'

services:
  # Frontend - React Application
  frontend:
    image: node:18-alpine
    container_name: react_frontend
    working_dir: /app
    command: npm start
    environment:
      - REACT_APP_API_URL=http://localhost:3001
      - NODE_ENV=development
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      - backend
    networks:
      - app_network

  # Backend - Node.js API
  backend:
    image: node:18-alpine
    container_name: node_backend
    working_dir: /app
    command: npm run dev
    environment:
      - NODE_ENV=development
      - PORT=3001
      - MONGODB_URL=mongodb://mongo:27017/myapp
      - JWT_SECRET=your-secret-key
    ports:
      - "3001:3001"
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      - mongo
    networks:
      - app_network

  # Database - MongoDB
  mongo:
    image: mongo:6
    container_name: mongodb
    restart: always
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=password
      - MONGO_INITDB_DATABASE=myapp
    ports:
      - "27017:27017"
    volumes:
      - mongo_data:/data/db
      - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
    networks:
      - app_network

volumes:
  mongo_data:

networks:
  app_network:
    driver: bridge

⚙️ Entorno de Desarrollo

🟡 intermediate

Configuración de entorno de desarrollo con recarga en caliente

# Development Environment with Hot Reload
version: '3.8'

services:
  # Frontend Development Server
  frontend-dev:
    image: node:18-alpine
    container_name: frontend_dev
    working_dir: /app
    command: npm run dev
    environment:
      - CHOKIDAR_USEPOLLING=true
      - REACT_APP_API_URL=http://localhost:3001
      - FAST_REFRESH=true
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
      - /app/node_modules
    stdin_open: true
    tty: true
    networks:
      - dev_network

  # Backend Development Server
  backend-dev:
    image: node:18-alpine
    container_name: backend_dev
    working_dir: /app
    command: npm run dev
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
      - PORT=3001
      - MONGODB_URL=mongodb://mongo-dev:27017/devdb
      - REDIS_URL=redis://redis-dev:6379
    ports:
      - "3001:3001"
      - "9229:9229"  # Node.js debugging port
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      - mongo-dev
      - redis-dev
    networks:
      - dev_network

  # Development Database
  mongo-dev:
    image: mongo:6
    container_name: mongo_dev
    environment:
      - MONGO_INITDB_DATABASE=devdb
    ports:
      - "27017:27017"
    volumes:
      - mongo_dev_data:/data/db
      - ./scripts/mongo-init.js:/docker-entrypoint-initdb.d/init.js:ro
    networks:
      - dev_network

  # Redis for Development
  redis-dev:
    image: redis:7-alpine
    container_name: redis_dev
    ports:
      - "6379:6379"
    volumes:
      - redis_dev_data:/data
    networks:
      - dev_network

  # Database Management Tool
  mongo-express:
    image: mongo-express:latest
    container_name: mongo_express
    environment:
      - ME_CONFIG_MONGODB_SERVER=mongo-dev
      - ME_CONFIG_MONGODB_PORT=27017
      - ME_CONFIG_MONGODB_ENABLE_ADMIN=true
      - ME_CONFIG_BASICAUTH_USERNAME=admin
      - ME_CONFIG_BASICAUTH_PASSWORD=admin123
    ports:
      - "8081:8081"
    depends_on:
      - mongo-dev
    networks:
      - dev_network

  # Redis Management Tool
  redis-commander:
    image: rediscommander/redis-commander:latest
    container_name: redis_commander
    environment:
      - REDIS_HOSTS=local:redis-dev:6379
    ports:
      - "8082:8081"
    depends_on:
      - redis-dev
    networks:
      - dev_network

  # API Documentation
  swagger-ui:
    image: swaggerapi/swagger-ui:latest
    container_name: swagger_ui
    environment:
      - SWAGGER_JSON_URL=http://localhost:3001/api-docs
    ports:
      - "8083:8080"
    depends_on:
      - backend-dev
    networks:
      - dev_network

  # Mail Testing Service
  mailhog:
    image: mailhog/mailhog:latest
    container_name: mail_hog
    ports:
      - "1025:1025"  # SMTP port
      - "8025:8025"  # Web interface
    networks:
      - dev_network

volumes:
  mongo_dev_data:
  redis_dev_data:

networks:
  dev_network:
    driver: bridge

⚙️ Sistema de Gestión de Contenidos

🟡 intermediate

Configuración de sistema CMS con WordPress + MySQL

# WordPress CMS with MySQL and Redis
version: '3.8'

services:
  # WordPress Application
  wordpress:
    image: wordpress:6.2-php8.1-fpm-alpine
    container_name: wordpress_app
    environment:
      WORDPRESS_DB_HOST: mysql-db:3306
      WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
      WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
      WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      WORDPRESS_TABLE_PREFIX: wp_
      WORDPRESS_DEBUG: ${WORDPRESS_DEBUG:-false}
      WP_REDIS_HOST: redis-cache
      WP_REDIS_PORT: 6379
      WP_CACHE_KEY_SALT: ${WP_CACHE_KEY_SALT}
    volumes:
      - wordpress_data:/var/www/html
      - ./wordpress/php.ini:/usr/local/etc/php/conf.d/custom.ini:ro
      - ./wordpress/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini:ro
    depends_on:
      - mysql-db
      - redis-cache
    restart: unless-stopped
    networks:
      - wordpress_network

  # Nginx Web Server
  nginx:
    image: nginx:alpine
    container_name: nginx_web
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - wordpress_data:/var/www/html:ro
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - nginx_logs:/var/log/nginx
    depends_on:
      - wordpress
    restart: unless-stopped
    networks:
      - wordpress_network

  # MySQL Database
  mysql-db:
    image: mysql:8.0
    container_name: mysql_database
    environment:
      MYSQL_DATABASE: ${WORDPRESS_DB_NAME}
      MYSQL_USER: ${WORDPRESS_DB_USER}
      MYSQL_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    volumes:
      - mysql_data:/var/lib/mysql
      - ./mysql/my.cnf:/etc/mysql/conf.d/custom.cnf:ro
      - ./mysql/init:/docker-entrypoint-initdb.d:ro
    restart: unless-stopped
    networks:
      - wordpress_network

  # Redis Cache
  redis-cache:
    image: redis:7-alpine
    container_name: redis_wordpress_cache
    command: redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data
    restart: unless-stopped
    networks:
      - wordpress_network

  # phpMyAdmin for Database Management
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    container_name: phpmyadmin
    environment:
      PMA_HOST: mysql-db
      PMA_PORT: 3306
      PMA_USER: ${WORDPRESS_DB_USER}
      PMA_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    ports:
      - "8080:80"
    depends_on:
      - mysql-db
    restart: unless-stopped
    networks:
      - wordpress_network

  # WordPress CLI for management
  wp-cli:
    image: wordpress:cli
    container_name: wp_cli
    environment:
      WORDPRESS_DB_HOST: mysql-db:3306
      WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
      WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
      WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
    volumes:
      - wordpress_data:/var/www/html
    depends_on:
      - mysql-db
      - wordpress
    networks:
      - wordpress_network
    entrypoint: wp
    command: "--info"

  # Filestash for File Management
  filestash:
    image: machines/filestash:latest
    container_name: filestash
    ports:
      - "8334:8334"
    environment:
      - ADMIN_PASSWORD=${FILESTASH_PASSWORD}
    volumes:
      - wordpress_data:/data
    depends_on:
      - wordpress
    restart: unless-stopped
    networks:
      - wordpress_network

  # Backup Service
  backup:
    image: frappe/mysql-backup:latest
    container_name: mysql_backup
    environment:
      MYSQL_HOST: mysql-db
      MYSQL_USER: ${WORDPRESS_DB_USER}
      MYSQL_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      MYSQL_DATABASE: ${WORDPRESS_DB_NAME}
      BACKUP_DIR: /backups
      SCHEDULE: "0 2 * * *"  # Daily at 2 AM
      RETENTION_DAYS: 7
    volumes:
      - backup_data:/backups
      - ./backup/backup.sh:/backup.sh:ro
    depends_on:
      - mysql-db
    restart: unless-stopped
    networks:
      - wordpress_network

  # SSL Certificate Auto-renewal with Let's Encrypt
  certbot:
    image: certbot/certbot:latest
    container_name: certbot
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    command: >
      sh -c "while :; do
        certbot renew --nginx --non-interactive --agree-tos --email ${CERT_EMAIL};
        sleep 12h;
      done"
    restart: unless-stopped
    depends_on:
      - nginx
    networks:
      - wordpress_network

  # Monitoring with Prometheus (optional)
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus_wp
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    restart: unless-stopped
    networks:
      - wordpress_network

  # WordPress Exporter for Prometheus
  wordpress-exporter:
    image: superbrothers/prometheus-wp-exporter:latest
    container_name: wp_exporter
    environment:
      WP_HOST: wordpress
      WP_PATH: /var/www/html
    depends_on:
      - wordpress
    restart: unless-stopped
    networks:
      - wordpress_network

volumes:
  wordpress_data:
  mysql_data:
  redis_data:
  backup_data:
  prometheus_data:
  nginx_logs:

networks:
  wordpress_network:
    driver: bridge

⚙️ Arquitectura de Microservicios

🔴 complex

Ejemplo completo de configuración de sistema microservicios

# Microservices Architecture
version: '3.8'

services:
  # API Gateway
  api-gateway:
    image: nginx:alpine
    container_name: api_gateway
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    depends_on:
      - user-service
      - product-service
      - order-service
    networks:
      - frontend
      - backend

  # User Service
  user-service:
    build:
      context: ./user-service
      dockerfile: Dockerfile
    container_name: user_service
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:password@user-db:5432/users
      - REDIS_URL=redis://redis:6379
      - JWT_SECRET=your-jwt-secret
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    depends_on:
      - user-db
      - redis
    networks:
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3002/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Product Service
  product-service:
    build:
      context: ./product-service
      dockerfile: Dockerfile
    container_name: product_service
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://product:password@product-db:5432/products
      - ELASTICSEARCH_URL=http://elasticsearch:9200
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    depends_on:
      - product-db
      - elasticsearch
    networks:
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3003/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Order Service
  order-service:
    build:
      context: ./order-service
      dockerfile: Dockerfile
    container_name: order_service
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://order:password@order-db:5432/orders
      - KAFKA_BROKERS=kafka:9092
      - USER_SERVICE_URL=http://user-service:3002
      - PRODUCT_SERVICE_URL=http://product-service:3003
    deploy:
      replicas: 2
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    depends_on:
      - order-db
      - kafka
      - user-service
      - product-service
    networks:
      - backend

  # Message Queue - Apache Kafka
  zookeeper:
    image: confluentinc/cp-zookeeper:7.3.0
    container_name: zookeeper
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    networks:
      - backend

  kafka:
    image: confluentinc/cp-kafka:7.3.0
    container_name: kafka
    depends_on:
      - zookeeper
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    networks:
      - backend

  # Search Engine - Elasticsearch
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - xpack.security.enabled=false
    ports:
      - "9200:9200"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    networks:
      - backend

  # Cache - Redis
  redis:
    image: redis:7-alpine
    container_name: redis_cache
    command: redis-server --appendonly yes --requirepass redis-password
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    networks:
      - backend

  # User Database
  user-db:
    image: postgres:15
    container_name: user_database
    environment:
      POSTGRES_DB: users
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - user_db_data:/var/lib/postgresql/data
    networks:
      - backend

  # Product Database
  product-db:
    image: postgres:15
    container_name: product_database
    environment:
      POSTGRES_DB: products
      POSTGRES_USER: product
      POSTGRES_PASSWORD: password
    volumes:
      - product_db_data:/var/lib/postgresql/data
    networks:
      - backend

  # Order Database
  order-db:
    image: postgres:15
    container_name: order_database
    environment:
      POSTGRES_DB: orders
      POSTGRES_USER: order
      POSTGRES_PASSWORD: password
    volumes:
      - order_db_data:/var/lib/postgresql/data
    networks:
      - backend

volumes:
  user_db_data:
  product_db_data:
  order_db_data:
  elasticsearch_data:
  redis_data:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge

⚙️ Entorno de Producción

🔴 complex

Configuración de orquestación de contenedores a nivel de producción

# Production Environment Configuration
version: '3.8'

services:
  # Load Balancer
  nginx:
    image: nginx:alpine
    container_name: nginx_lb
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - nginx_logs:/var/log/nginx
    depends_on:
      - app1
      - app2
      - app3
    restart: unless-stopped
    networks:
      - frontend
    healthcheck:
      test: ["CMD", "nginx", "-t"]
      interval: 30s
      timeout: 10s
      retries: 3

  # Application Instances (Blue-Green Deployment)
  app1:
    image: myregistry/myapp:${APP_VERSION:-latest}
    container_name: app_instance_1
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DATABASE_URL=postgresql://app:${DB_PASSWORD}@postgres-primary:5432/myapp
      - REDIS_URL=redis://redis-cluster:6379
      - ELASTICSEARCH_URL=http://elasticsearch:9200
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M
    restart: unless-stopped
    depends_on:
      - postgres-primary
      - redis-cluster
      - elasticsearch
    networks:
      - frontend
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  app2:
    image: myregistry/myapp:${APP_VERSION:-latest}
    container_name: app_instance_2
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DATABASE_URL=postgresql://app:${DB_PASSWORD}@postgres-primary:5432/myapp
      - REDIS_URL=redis://redis-cluster:6379
      - ELASTICSEARCH_URL=http://elasticsearch:9200
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
    restart: unless-stopped
    depends_on:
      - postgres-primary
      - redis-cluster
      - elasticsearch
    networks:
      - frontend
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  app3:
    image: myregistry/myapp:${APP_VERSION:-latest}
    container_name: app_instance_3
    environment:
      - NODE_ENV=production
      - PORT=3000
      - DATABASE_URL=postgresql://app:${DB_PASSWORD}@postgres-primary:5432/myapp
      - REDIS_URL=redis://redis-cluster:6379
      - ELASTICSEARCH_URL=http://elasticsearch:9200
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
    restart: unless-stopped
    depends_on:
      - postgres-primary
      - redis-cluster
      - elasticsearch
    networks:
      - frontend
      - backend
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  # Primary Database (PostgreSQL with Replication)
  postgres-primary:
    image: postgres:15
    container_name: postgres_primary
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_REPLICATION_USER: replicator
      POSTGRES_REPLICATION_PASSWORD: ${REPLICATION_PASSWORD}
    volumes:
      - postgres_primary_data:/var/lib/postgresql/data
      - ./postgresql/postgresql.conf:/etc/postgresql/postgresql.conf:ro
      - ./postgresql/pg_hba.conf:/etc/postgresql/pg_hba.conf:ro
    command: postgres -c config_file=/etc/postgresql/postgresql.conf
    restart: unless-stopped
    networks:
      - backend

  postgres-replica:
    image: postgres:15
    container_name: postgres_replica
    environment:
      PGUSER: postgres
      POSTGRES_MASTER_SERVICE: postgres-primary
      POSTGRES_REPLICATION_USER: replicator
      POSTGRES_REPLICATION_PASSWORD: ${REPLICATION_PASSWORD}
    volumes:
      - postgres_replica_data:/var/lib/postgresql/data
    restart: unless-stopped
    depends_on:
      - postgres-primary
    networks:
      - backend

  # Redis Cluster
  redis-cluster:
    image: redis:7-alpine
    container_name: redis_cluster
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis_cluster_data:/data
    restart: unless-stopped
    networks:
      - backend

  # Elasticsearch for Logging and Search
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0
    container_name: elasticsearch
    environment:
      - cluster.name=production-cluster
      - node.name=elasticsearch-node
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
      - xpack.security.enabled=true
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    restart: unless-stopped
    networks:
      - backend

  # Logstash for Log Processing
  logstash:
    image: docker.elastic.co/logstash/logstash:8.8.0
    container_name: logstash
    environment:
      - "LS_JAVA_OPTS=-Xmx1g -Xms1g"
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
    depends_on:
      - elasticsearch
    restart: unless-stopped
    networks:
      - backend

  # Kibana for Log Visualization
  kibana:
    image: docker.elastic.co/kibana/kibana:8.8.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch
    restart: unless-stopped
    networks:
      - backend

  # Prometheus for Metrics Collection
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    restart: unless-stopped
    networks:
      - monitoring

  # Grafana for Metrics Visualization
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
    ports:
      - "3001:3000"
    depends_on:
      - prometheus
    restart: unless-stopped
    networks:
      - monitoring

  # Filebeat for Log Collection
  filebeat:
    image: docker.elastic.co/beats/filebeat:8.8.0
    container_name: filebeat
    user: root
    environment:
      - ELASTICSEARCH_HOST=elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - nginx_logs:/var/log/nginx:ro
    depends_on:
      - elasticsearch
    restart: unless-stopped
    networks:
      - backend

volumes:
  postgres_primary_data:
  postgres_replica_data:
  redis_cluster_data:
  elasticsearch_data:
  prometheus_data:
  grafana_data:
  nginx_logs:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    internal: true
  monitoring:
    driver: bridge

⚙️ Monitoreo y Logs

🔴 complex

Configuración de sistema con monitoreo y recolección de logs

# Monitoring and Logging Stack
version: '3.8'

services:
  # Prometheus - Metrics Collection
  prometheus:
    image: prom/prometheus:v2.45.0
    container_name: prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'
      - '--web.enable-admin-api'
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./prometheus/rules:/etc/prometheus/rules:ro
      - prometheus_data:/prometheus
    ports:
      - "9090:9090"
    restart: unless-stopped
    networks:
      - monitoring

  # Grafana - Metrics Visualization
  grafana:
    image: grafana/grafana:10.0.0
    container_name: grafana
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD}
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning:ro
      - ./grafana/dashboards:/var/lib/grafana/dashboards:ro
    ports:
      - "3000:3000"
    restart: unless-stopped
    depends_on:
      - prometheus
    networks:
      - monitoring

  # AlertManager - Alert Management
  alertmanager:
    image: prom/alertmanager:v0.25.0
    container_name: alertmanager
    volumes:
      - ./alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
      - alertmanager_data:/alertmanager
    ports:
      - "9093:9093"
    restart: unless-stopped
    networks:
      - monitoring

  # Node Exporter - System Metrics
  node-exporter:
    image: prom/node-exporter:v1.6.0
    container_name: node_exporter
    command:
      - '--path.procfs=/host/proc'
      - '--path.rootfs=/rootfs'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    ports:
      - "9100:9100"
    restart: unless-stopped
    networks:
      - monitoring

  # cAdvisor - Container Metrics
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.47.0
    container_name: cadvisor
    command:
      - '--port=8080'
      - '--docker_only=true'
      - '--housekeeping_interval=30s'
      - '--max_housekeeping_interval=300s'
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
      - /dev/disk/:/dev/disk:ro
    ports:
      - "8080:8080"
    restart: unless-stopped
    networks:
      - monitoring

  # Elasticsearch - Log Storage and Search
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0
    container_name: elasticsearch
    environment:
      - node.name=elasticsearch
      - cluster.name=logging-cluster
      - discovery.type=single-node
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms2g -Xmx2g"
      - xpack.security.enabled=true
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - xpack.security.enrollment.enabled=false
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    restart: unless-stopped
    networks:
      - logging

  # Logstash - Log Processing
  logstash:
    image: docker.elastic.co/logstash/logstash:8.8.0
    container_name: logstash
    environment:
      - "LS_JAVA_OPTS=-Xmx1g -Xms1g"
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline:ro
      - ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
      - ./logstash/config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
    ports:
      - "5044:5044"  # Beats input
      - "5000:5000"  # TCP input
      - "9600:9600"  # API
    restart: unless-stopped
    depends_on:
      - elasticsearch
    networks:
      - logging

  # Kibana - Log Visualization
  kibana:
    image: docker.elastic.co/kibana/kibana:8.8.0
    container_name: kibana
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - ELASTICSEARCH_USERNAME=kibana_system
      - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
      - SERVER_NAME=kibana.example.com
      - SERVER_HOST=0.0.0.0
    ports:
      - "5601:5601"
    restart: unless-stopped
    depends_on:
      - elasticsearch
    networks:
      - logging

  # Filebeat - Log Collection from Files
  filebeat:
    image: docker.elastic.co/beats/filebeat:8.8.0
    container_name: filebeat
    user: root
    environment:
      - ELASTICSEARCH_HOST=elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
      - LOGSTASH_HOST=logstash:5044
    volumes:
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
      - /var/lib/docker/containers:/var/lib/docker/containers:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /var/log:/var/log:ro
    restart: unless-stopped
    depends_on:
      - elasticsearch
      - logstash
    networks:
      - logging

  # Metricbeat - Infrastructure Metrics
  metricbeat:
    image: docker.elastic.co/beats/metricbeat:8.8.0
    container_name: metricbeat
    user: root
    environment:
      - ELASTICSEARCH_HOST=elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
    volumes:
      - ./metricbeat/metricbeat.yml:/usr/share/metricbeat/metricbeat.yml:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /sys/fs/cgroup:/hostfs/sys/fs/cgroup:ro
      - /proc:/hostfs/proc:ro
      - /:/hostfs:ro
    restart: unless-stopped
    depends_on:
      - elasticsearch
    networks:
      - logging

  # APM Server - Application Performance Monitoring
  apm-server:
    image: docker.elastic.co/apm/apm-server:8.8.0
    container_name: apm_server
    environment:
      - ELASTICSEARCH_HOST=elasticsearch:9200
      - ELASTICSEARCH_USERNAME=elastic
      - ELASTICSEARCH_PASSWORD=${ELASTIC_PASSWORD}
    volumes:
      - ./apm-server/apm-server.yml:/usr/share/apm-server/apm-server.yml:ro
    ports:
      - "8200:8200"
    restart: unless-stopped
    depends_on:
      - elasticsearch
    networks:
      - logging

  # Jaeger - Distributed Tracing
  jaeger:
    image: jaegertracing/all-in-one:1.47
    container_name: jaeger
    environment:
      - COLLECTOR_OTLP_ENABLED=true
      - SPAN_STORAGE_TYPE=elasticsearch
      - ES_SERVER_URLS=http://elasticsearch:9200
      - ES_USERNAME=elastic
      - ES_PASSWORD=${ELASTIC_PASSWORD}
    ports:
      - "16686:16686"  # Jaeger UI
      - "4317:4317"    # OTLP gRPC receiver
      - "4318:4318"    # OTLP HTTP receiver
    restart: unless-stopped
    depends_on:
      - elasticsearch
    networks:
      - logging

volumes:
  prometheus_data:
  grafana_data:
  alertmanager_data:
  elasticsearch_data:

networks:
  monitoring:
    driver: bridge
  logging:
    driver: bridge