# Synor Testnet Docker Compose Configuration
# Deploys 3 seed nodes for initial testnet bootstrap

services:
  # ==========================================================================
  # Seed Node 1 (Primary Bootstrap)
  # ==========================================================================
  seed1:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: synor-seed1
    hostname: seed1
    restart: unless-stopped
    command:
      - "run"
      - "--p2p-host=0.0.0.0"
      - "--p2p-port=17511"
      - "--rpc-host=0.0.0.0"
      - "--rpc-port=17110"
      - "--ws-port=17111"
      - "--mine"
      - "--coinbase=tsynor1qz232pysw8kezv2f4qxnhdufrlx5cmq78522mpuf8x5qlxu6j8sgcp05get"
    ports:
      - "17511:17511"   # P2P
      - "17110:17110"   # HTTP RPC
      - "17111:17111"   # WebSocket RPC
    volumes:
      - seed1-data:/data/synor
    networks:
      synor-testnet:
        ipv4_address: 172.20.0.10
    environment:
      - RUST_LOG=info
      - SYNOR_DATA_DIR=/data/synor
      - SYNOR_NETWORK=testnet
    healthcheck:
      test: ["CMD", "synord", "version"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  # ==========================================================================
  # Seed Node 2
  # ==========================================================================
  seed2:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: synor-seed2
    hostname: seed2
    restart: unless-stopped
    command:
      - "run"
      - "--p2p-host=0.0.0.0"
      - "--p2p-port=17511"
      - "--rpc-host=0.0.0.0"
      - "--rpc-port=17110"
      - "--ws-port=17111"
      - "--seeds=172.20.0.10:17511"
      - "--mine"
      - "--coinbase=tsynor1qrjdvz69xxc3gyq24d0ejp73wxxxz0nqxjp2zklw3nx6zljunwe75zele44"
    ports:
      - "17521:17511"   # P2P (offset port)
      - "17120:17110"   # HTTP RPC
      - "17121:17111"   # WebSocket RPC
    volumes:
      - seed2-data:/data/synor
    networks:
      synor-testnet:
        ipv4_address: 172.20.0.11
    environment:
      - RUST_LOG=info
      - SYNOR_DATA_DIR=/data/synor
      - SYNOR_NETWORK=testnet
    depends_on:
      seed1:
        condition: service_healthy

  # ==========================================================================
  # Seed Node 3
  # ==========================================================================
  seed3:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: synor-seed3
    hostname: seed3
    restart: unless-stopped
    command:
      - "run"
      - "--p2p-host=0.0.0.0"
      - "--p2p-port=17511"
      - "--rpc-host=0.0.0.0"
      - "--rpc-port=17110"
      - "--ws-port=17111"
      - "--seeds=172.20.0.10:17511,172.20.0.11:17511"
      - "--mine"
      - "--coinbase=tsynor1qq0mt7lhwckdz3hg69dpcv3vxw8j56d7un7z8x93vrjmjqyel5u5yf77vt8"
    ports:
      - "17531:17511"   # P2P (offset port)
      - "17130:17110"   # HTTP RPC
      - "17131:17111"   # WebSocket RPC
    volumes:
      - seed3-data:/data/synor
    networks:
      synor-testnet:
        ipv4_address: 172.20.0.12
    environment:
      - RUST_LOG=info
      - SYNOR_DATA_DIR=/data/synor
      - SYNOR_NETWORK=testnet
    depends_on:
      seed1:
        condition: service_healthy

  # ==========================================================================
  # Web Wallet (React + Vite)
  # ==========================================================================
  web-wallet:
    build:
      context: ./apps/web
      dockerfile: Dockerfile
    container_name: synor-web-wallet
    hostname: web-wallet
    restart: unless-stopped
    ports:
      - "17300:80"
    networks:
      - synor-testnet
    depends_on:
      seed1:
        condition: service_healthy

  # ==========================================================================
  # Testnet Faucet Service
  # ==========================================================================
  faucet:
    build:
      context: .
      dockerfile: Dockerfile.faucet
    container_name: synor-faucet
    hostname: faucet
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      - SYNOR_RPC_URL=http://seed1:17110
      - FAUCET_AMOUNT=1000000000  # 10 SYNOR in sompi
      - FAUCET_COOLDOWN=3600      # 1 hour between requests per address
      - RUST_LOG=info
    networks:
      - synor-testnet
    depends_on:
      seed1:
        condition: service_healthy

  # ==========================================================================
  # Block Explorer Backend (optional)
  # ==========================================================================
  explorer-api:
    build:
      context: .
      dockerfile: Dockerfile.explorer
    container_name: synor-explorer-api
    hostname: explorer-api
    restart: unless-stopped
    ports:
      - "17200:3000"
    environment:
      - SYNOR_RPC_URL=http://seed1:17110
      - SYNOR_WS_URL=ws://seed1:17111
      - DATABASE_URL=postgres://synor:synor@postgres:5432/explorer
      - EXPLORER_STATIC_DIR=/var/www/explorer
      - EXPLORER_CORS_ORIGINS=*
      - RUST_LOG=info
    networks:
      - synor-testnet
    depends_on:
      seed1:
        condition: service_healthy
      postgres:
        condition: service_healthy
    profiles:
      - explorer

  # ==========================================================================
  # Block Explorer Web Frontend (React)
  # ==========================================================================
  explorer-web:
    build:
      context: ./apps/explorer-web
      dockerfile: Dockerfile
    container_name: synor-explorer-web
    hostname: explorer-web
    restart: unless-stopped
    ports:
      - "17201:80"
    networks:
      - synor-testnet
    depends_on:
      explorer-api:
        condition: service_started
    profiles:
      - explorer

  # ==========================================================================
  # PostgreSQL for Explorer
  # ==========================================================================
  postgres:
    image: postgres:16-alpine
    container_name: synor-postgres
    restart: unless-stopped
    environment:
      - POSTGRES_USER=synor
      - POSTGRES_PASSWORD=synor
      - POSTGRES_DB=explorer
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - synor-testnet
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U synor -d explorer"]
      interval: 10s
      timeout: 5s
      retries: 5
    profiles:
      - explorer

  # ==========================================================================
  # Security Audit Service
  # ==========================================================================
  security-audit:
    build:
      context: .
      dockerfile: Dockerfile.security
    container_name: synor-security-audit
    volumes:
      - .:/app:ro
    profiles:
      - security

  # ==========================================================================
  # Prometheus - Metrics Collection
  # ==========================================================================
  prometheus:
    image: prom/prometheus:v2.48.0
    container_name: synor-prometheus
    hostname: prometheus
    restart: unless-stopped
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./monitoring/alerts.yml:/etc/prometheus/alerts.yml:ro
      - prometheus-data:/prometheus
    networks:
      - synor-testnet
    profiles:
      - monitoring

  # ==========================================================================
  # Grafana - Visualization & Dashboards
  # ==========================================================================
  grafana:
    image: grafana/grafana:10.2.2
    container_name: synor-grafana
    hostname: grafana
    restart: unless-stopped
    ports:
      - "3001:3000"  # Using 3001 to avoid conflict with explorer-api
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=synor123
      - GF_USERS_ALLOW_SIGN_UP=false
      - GF_SERVER_ROOT_URL=http://localhost:3000
    volumes:
      - ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro
      - ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro
      - grafana-data:/var/lib/grafana
    networks:
      - synor-testnet
    depends_on:
      - prometheus
    profiles:
      - monitoring

  # ==========================================================================
  # Alertmanager - Alert Routing & Notifications
  # ==========================================================================
  alertmanager:
    image: prom/alertmanager:v0.26.0
    container_name: synor-alertmanager
    hostname: alertmanager
    restart: unless-stopped
    command:
      - '--config.file=/etc/alertmanager/alertmanager.yml'
      - '--storage.path=/alertmanager'
    ports:
      - "9093:9093"
    volumes:
      - ./monitoring/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
      - alertmanager-data:/alertmanager
    networks:
      - synor-testnet
    profiles:
      - monitoring

  # ==========================================================================
  # Node Exporter - System Metrics (optional but useful)
  # Note: Limited functionality on macOS Docker Desktop
  # ==========================================================================
  node-exporter:
    image: prom/node-exporter:v1.7.0
    container_name: synor-node-exporter
    hostname: node-exporter
    restart: unless-stopped
    ports:
      - "9100:9100"
    # Note: Root filesystem mount doesn't work on macOS Docker Desktop
    # volumes:
    #   - /:/host:ro,rslave
    # command:
    #   - '--path.rootfs=/host'
    networks:
      - synor-testnet
    profiles:
      - monitoring

  # ==========================================================================
  # Redis - API Gateway Cache & Rate Limiting
  # ==========================================================================
  redis:
    image: redis:7-alpine
    container_name: synor-redis
    hostname: redis
    restart: unless-stopped
    ports:
      - "17379:6379"
    volumes:
      - redis-data:/data
    networks:
      - synor-testnet
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3
    profiles:
      - api

  # ==========================================================================
  # Public API Gateway - Rate-limited RPC Access
  # ==========================================================================
  api-gateway:
    build:
      context: ./apps/api-gateway
      dockerfile: Dockerfile
    container_name: synor-api-gateway
    hostname: api-gateway
    restart: unless-stopped
    ports:
      - "17400:3100"
    environment:
      - PORT=3100
      - REDIS_URL=redis://redis:6379
      - RPC_TARGET=http://seed1:17110
      - ADMIN_KEY=${API_ADMIN_KEY:-admin-secret-key}
    networks:
      - synor-testnet
    depends_on:
      redis:
        condition: service_healthy
      seed1:
        condition: service_healthy
    profiles:
      - api

  # ==========================================================================
  # Synor.cc Marketing Website
  # ==========================================================================
  website:
    build:
      context: ./apps/website
      dockerfile: Dockerfile
    container_name: synor-website
    hostname: website
    restart: unless-stopped
    ports:
      - "17000:80"
    networks:
      - synor-testnet
    profiles:
      - website

# =============================================================================
# Networks
# =============================================================================
networks:
  synor-testnet:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.20.0.0/16

# =============================================================================
# Volumes
# =============================================================================
volumes:
  seed1-data:
  seed2-data:
  seed3-data:
  postgres-data:
  prometheus-data:
  grafana-data:
  alertmanager-data:
  redis-data:
