services:
  postgres:
    image: postgis/postgis:16-3.4
    container_name: goodgo-postgres
    restart: unless-stopped
    ports:
      - '${DB_PORT:-5432}:5432'
    environment:
      POSTGRES_DB: ${DB_NAME:-goodgo}
      POSTGRES_USER: ${DB_USER:-goodgo}
      POSTGRES_PASSWORD: ${DB_PASSWORD:-goodgo_secret}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U ${DB_USER:-goodgo} -d ${DB_NAME:-goodgo}']
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - goodgo-net

  redis:
    image: redis:7-alpine
    container_name: goodgo-redis
    restart: unless-stopped
    ports:
      - '${REDIS_PORT:-6379}:6379'
    command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru --requirepass ${REDIS_PASSWORD:-changeme}
    volumes:
      - redis_data:/data
    healthcheck:
      test: ['CMD', 'redis-cli', '-a', '${REDIS_PASSWORD:-changeme}', '--no-auth-warning', 'ping']
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    networks:
      - goodgo-net

  typesense:
    image: typesense/typesense:27.1
    container_name: goodgo-typesense
    restart: unless-stopped
    ports:
      - '${TYPESENSE_PORT:-8108}:8108'
    environment:
      TYPESENSE_API_KEY: ${TYPESENSE_API_KEY:-ts_dev_key_change_me}
      TYPESENSE_DATA_DIR: /data
      TYPESENSE_ENABLE_CORS: 'true'
    volumes:
      - typesense_data:/data
    healthcheck:
      test: ['CMD-SHELL', 'bash -c "echo > /dev/tcp/localhost/8108"']
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s
    networks:
      - goodgo-net

  minio:
    image: minio/minio:latest
    container_name: goodgo-minio
    restart: unless-stopped
    ports:
      - '${MINIO_API_PORT:-9000}:9000'
      - '${MINIO_CONSOLE_PORT:-9001}:9001'
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY is required}
      MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?MINIO_SECRET_KEY is required}
      MINIO_API_CORS_ALLOW_ORIGIN: 'http://localhost:3000,http://localhost:3001'
    volumes:
      - minio_data:/data
    healthcheck:
      test: ['CMD', 'curl', '-sf', 'http://localhost:9000/minio/health/live']
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 15s
    networks:
      - goodgo-net

  minio-init:
    image: minio/mc:latest
    container_name: goodgo-minio-init
    restart: 'no'
    depends_on:
      minio:
        condition: service_healthy
    entrypoint: /bin/sh
    command:
      - -c
      - |
        mc alias set local http://minio:9000 $${MINIO_ROOT_USER} $${MINIO_ROOT_PASSWORD}
        mc mb --ignore-existing local/$${MINIO_BUCKET}
        mc anonymous set download local/$${MINIO_BUCKET}
        echo "MinIO init complete: bucket=$${MINIO_BUCKET}, public read enabled"
    environment:
      MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:?MINIO_ACCESS_KEY is required}
      MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:?MINIO_SECRET_KEY is required}
      MINIO_BUCKET: ${MINIO_BUCKET:-goodgo-media}
    networks:
      - goodgo-net

  ai-services:
    build:
      context: ./libs/ai-services
      dockerfile: Dockerfile
    container_name: goodgo-ai-services
    restart: unless-stopped
    ports:
      - '${AI_SERVICES_PORT:-8000}:8000'
    environment:
      AI_DEBUG: ${AI_DEBUG:-false}
      AI_LOG_LEVEL: ${AI_LOG_LEVEL:-info}
    healthcheck:
      test: ['CMD', 'python', '-c', 'import httpx; httpx.get("http://localhost:8000/health").raise_for_status()']
      interval: 30s
      timeout: 5s
      retries: 5
      start_period: 30s
    networks:
      - goodgo-net

  # ── Database Backup ──
  pg-backup:
    image: postgis/postgis:16-3.4
    container_name: goodgo-pg-backup
    restart: unless-stopped
    entrypoint: /bin/bash
    command:
      - -c
      - |
        apt-get update -qq && apt-get install -y -qq cron > /dev/null 2>&1
        (echo "0 2 * * * PGHOST=postgres PGPORT=5432 PGUSER=${DB_USER:-goodgo} PGDATABASE=${DB_NAME:-goodgo} PGPASSWORD=${DB_PASSWORD:-goodgo_secret} BACKUP_DIR=/backups RETENTION_DAYS=${BACKUP_RETENTION_DAYS:-7} /scripts/pg-backup.sh >> /var/log/pg-backup.log 2>&1"; echo "0 4 * * * PGHOST=postgres PGPORT=5432 PGUSER=${DB_USER:-goodgo} PGDATABASE=${DB_NAME:-goodgo} PGPASSWORD=${DB_PASSWORD:-goodgo_secret} BACKUP_DIR=/backups REPORT_FILE=/backups/verify-latest.json /scripts/pg-verify-backup.sh >> /var/log/pg-verify-backup.log 2>&1") | crontab -
        /scripts/pg-backup.sh
        cron -f
    environment:
      PGHOST: postgres
      PGPORT: '5432'
      PGUSER: ${DB_USER:-goodgo}
      PGDATABASE: ${DB_NAME:-goodgo}
      PGPASSWORD: ${DB_PASSWORD:-goodgo_secret}
      BACKUP_DIR: /backups
      RETENTION_DAYS: ${BACKUP_RETENTION_DAYS:-7}
    volumes:
      - ./scripts/backup:/scripts:ro
      - pg_backups:/backups
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - goodgo-net

  # ── Backup Verification (on-demand) ──
  # Run manually: docker compose run --rm pg-verify-backup
  pg-verify-backup:
    image: postgis/postgis:16-3.4
    container_name: goodgo-pg-verify-backup
    profiles:
      - tools
    entrypoint: /bin/bash
    command:
      - -c
      - /scripts/pg-verify-backup.sh
    environment:
      PGHOST: postgres
      PGPORT: '5432'
      PGUSER: ${DB_USER:-goodgo}
      PGDATABASE: ${DB_NAME:-goodgo}
      PGPASSWORD: ${DB_PASSWORD:-goodgo_secret}
      BACKUP_DIR: /backups
      REPORT_FILE: /backups/verify-report.json
    volumes:
      - ./scripts/backup:/scripts:ro
      - pg_backups:/backups
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - goodgo-net

  # ── Log Aggregation ──
  loki:
    image: grafana/loki:3.0.0
    container_name: goodgo-loki
    restart: unless-stopped
    ports:
      - '${LOKI_PORT:-3100}:3100'
    command: -config.file=/etc/loki/loki-config.yml
    volumes:
      - ./monitoring/loki/loki-config.yml:/etc/loki/loki-config.yml:ro
      - loki_data:/loki
    healthcheck:
      test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:3100/ready']
      interval: 15s
      timeout: 5s
      retries: 5
      start_period: 20s
    networks:
      - goodgo-net

  promtail:
    image: grafana/promtail:3.0.0
    container_name: goodgo-promtail
    restart: unless-stopped
    command: -config.file=/etc/promtail/promtail-config.yml
    volumes:
      - ./monitoring/promtail/promtail-config.yml:/etc/promtail/promtail-config.yml:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
    depends_on:
      loki:
        condition: service_healthy
    networks:
      - goodgo-net

  prometheus:
    image: prom/prometheus:v2.51.0
    container_name: goodgo-prometheus
    restart: unless-stopped
    ports:
      - '${PROMETHEUS_PORT:-9090}:9090'
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=15d'
      - '--web.enable-lifecycle'
    volumes:
      - ./monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus_data:/prometheus
    extra_hosts:
      - 'host.docker.internal:host-gateway'
    healthcheck:
      test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:9090/-/healthy']
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 10s
    networks:
      - goodgo-net

  grafana:
    image: grafana/grafana:10.4.1
    container_name: goodgo-grafana
    restart: unless-stopped
    ports:
      - '${GRAFANA_PORT:-3002}:3000'
    environment:
      GF_SECURITY_ADMIN_USER: ${GRAFANA_ADMIN_USER:-admin}
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:-admin}
      GF_USERS_ALLOW_SIGN_UP: 'false'
    volumes:
      - ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro
      - ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro
      - grafana_data:/var/lib/grafana
    depends_on:
      prometheus:
        condition: service_healthy
      loki:
        condition: service_healthy
    healthcheck:
      test: ['CMD', 'wget', '--spider', '-q', 'http://localhost:3000/api/health']
      interval: 15s
      timeout: 5s
      retries: 3
      start_period: 15s
    networks:
      - goodgo-net

volumes:
  pgdata:
    driver: local
  redis_data:
    driver: local
  typesense_data:
    driver: local
  minio_data:
    driver: local
  pg_backups:
    driver: local
  loki_data:
    driver: local
  prometheus_data:
    driver: local
  grafana_data:
    driver: local

networks:
  goodgo-net:
    driver: bridge
    name: goodgo-net
