services:
  # ─── Reverse Proxy ────────────────────────────────────────────────────────
  caddy:
    image: caddy:2-alpine
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp" # HTTP/3
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
      - caddy_logs:/var/log/caddy
      - /opt/void/frontend:/srv/void:ro
    networks:
      - web-net
    depends_on:
      - frontend
      - ntfy
      - gitea
      - portainer

  # ─── Frontend ─────────────────────────────────────────────────────────────
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile
    container_name: frontend
    restart: unless-stopped
    labels:
      - "com.centurylinklabs.watchtower.enable=false"
    networks:
      - web-net

  # ─── Uptime Kuma — uptime.carloselugo.com ─────────────────────────────────
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    restart: unless-stopped
    volumes:
      - uptime_data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - web-net

  # ─── ntfy — ntfy.carloselugo.com ──────────────────────────────────────────
  ntfy:
    image: binwiederhier/ntfy
    container_name: ntfy
    restart: unless-stopped
    command: serve
    environment:
      - TZ=America/Puerto_Rico
    volumes:
      - ./ntfy/config:/etc/ntfy
      - ntfy_cache:/var/cache/ntfy
    networks:
      - web-net
    healthcheck:
      test: ["CMD-SHELL", "wget -q --tries=1 http://localhost:80/v1/health -O /dev/null || exit 1"]
      interval: 60s
      timeout: 10s
      retries: 3

  # ─── Dozzle — logs.carloselugo.com ────────────────────────────────────────
  dozzle:
    image: amir20/dozzle:latest
    container_name: dozzle
    restart: unless-stopped
    volumes:
      - ./dozzle/data:/data
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - web-net

  # ─── Gitea — git.carloselugo.com ──────────────────────────────────────────
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    restart: unless-stopped
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=sqlite3
      - GITEA__database__PATH=/data/gitea/gitea.db
      - GITEA__server__DOMAIN=git.carloselugo.com
      - GITEA__server__ROOT_URL=https://git.carloselugo.com
      - GITEA__server__HTTP_PORT=3000
      - GITEA__server__SSH_DOMAIN=git.carloselugo.com
      - GITEA__server__SSH_PORT=2222
    volumes:
      - gitea_data:/data
    ports:
      - "2222:22"
    networks:
      - web-net

  # ─── Portainer — portainer.carloselugo.com ────────────────────────────────
  portainer:
    image: portainer/portainer-ce:latest
    container_name: portainer
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - portainer_data:/data
    networks:
      - web-net

  # ─── Prometheus — interno, scrape de métricas ─────────────────────────────
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    command:
      - "--config.file=/etc/prometheus/prometheus.yml"
      - "--storage.tsdb.path=/prometheus"
      - "--storage.tsdb.retention.time=15d"
      - "--web.enable-lifecycle"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    networks:
      - web-net
    depends_on:
      - node-exporter
      - cadvisor

  # ─── Node Exporter — métricas del host ────────────────────────────────────
  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    restart: unless-stopped
    pid: host
    command:
      - "--path.rootfs=/host"
    volumes:
      - /:/host:ro,rslave
    networks:
      - web-net

  # ─── cAdvisor — métricas de contenedores ──────────────────────────────────
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    restart: unless-stopped
    privileged: true
    devices:
      - /dev/kmsg
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker:/var/lib/docker:ro
      - /dev/disk:/dev/disk:ro
    networks:
      - web-net

  # ─── Grafana — metrics.carloselugo.com ────────────────────────────────────
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    mem_limit: 512m
    mem_reservation: 256m
    environment:
      - GF_SECURITY_ADMIN_USER=carlos
      - GF_SECURITY_ADMIN_PASSWORD=c233357b0cb8dbdd49e21ab032146e09
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_SECURITY_DISABLE_BRUTE_FORCE_LOGIN_PROTECTION=false
      - GF_SERVER_ROOT_URL=https://metrics.carloselugo.com
      - GF_SECURITY_COOKIE_SECURE=true
    volumes:
      - grafana_data:/var/lib/grafana
    networks:
      - web-net
    depends_on:
      - prometheus

  # ─── Umami Analytics — DESACTIVADO ────────────────────────────────────────
  # Para reactivar: descomentar umami, umami-db, y el volumen umami_db_data
  # umami:
  #   image: ghcr.io/umami-software/umami:postgresql-latest
  #   container_name: umami
  #   restart: unless-stopped
  #   environment:
  #     DATABASE_URL: postgresql://umami:umami_password@umami-db:5432/umami
  #     APP_SECRET: change_this_to_a_random_string_32chars
  #   depends_on:
  #     umami-db:
  #       condition: service_healthy
  #   networks:
  #     - web-net

  # umami-db:
  #   image: postgres:15-alpine
  #   container_name: umami-db
  #   restart: unless-stopped
  #   environment:
  #     POSTGRES_DB: umami
  #     POSTGRES_USER: umami
  #     POSTGRES_PASSWORD: umami_password
  #   volumes:
  #     - umami_db_data:/var/lib/postgresql/data
  #   networks:
  #     - web-net
  #   healthcheck:
  #     test: ["CMD-SHELL", "pg_isready -U umami -d umami"]
  #     interval: 10s
  #     timeout: 5s
  #     retries: 5
  #   sysctls:
  #     - net.ipv6.conf.all.disable_ipv6=1

  # ─── Hit Counter ───────────────────────────────────────────────────────────
  hit-counter:
    build: ./hit-counter
    container_name: hit-counter
    restart: unless-stopped
    volumes:
      - hit_counter_data:/data
    networks:
      - web-net

volumes:
  caddy_data:
  caddy_config:
  caddy_logs:
  uptime_data:
  ntfy_cache:
  gitea_data:
  portainer_data:
  prometheus_data:
  grafana_data:
  hit_counter_data:
  # umami_db_data:

networks:
  web-net:
    driver: bridge