name: maple-mesh-noc

services:
  mesh-controller:
    image: ghcr.io/community-isp/mesh-controller:1.8.4
    restart: unless-stopped
    command: ["serve", "--config", "/etc/mesh/controller.yaml"]
    environment:
      TZ: America/Toronto
      MESH_ASN: "4242420187"
      MESH_DOMAIN: mesh.maplelan.ca
      WIREGUARD_ENDPOINT: gw1.maplelan.ca:51820
      POSTGRES_DSN: postgres://mesh:${POSTGRES_PASSWORD}@postgres:5432/mesh?sslmode=disable
      REDIS_URL: redis://redis:6379/0
      PROMETHEUS_URL: http://prometheus:9090
      DEFAULT_SITE_CODE: east-downtown
    volumes:
      - ./config/controller.yaml:/etc/mesh/controller.yaml:ro
      - ./state/keys:/var/lib/mesh-controller/keys
    ports:
      - "8443:8443"
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    networks:
      - noc

  gateway-agent:
    image: ghcr.io/community-isp/gateway-agent:0.12.1
    restart: unless-stopped
    network_mode: host
    privileged: true
    environment:
      TZ: America/Toronto
      NODE_ID: gw1-east-downtown
      CONTROLLER_URL: https://mesh-controller:8443
      BATMAN_IFACE: bat0
      WAN_IFACE: enp1s0
      LAN_IFACE: enp2s0
      WG_IFACE: wg-mesh
      DHCP_LEASE_FILE: /var/lib/misc/dnsmasq.leases
    volumes:
      - ./config/gateway-agent.yaml:/etc/mesh/gateway-agent.yaml:ro
      - /etc/wireguard:/etc/wireguard
      - /var/lib/misc:/var/lib/misc:ro
      - /run/bird:/run/bird
      - /sys/class/net:/sys/class/net:ro

  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: mesh
      POSTGRES_USER: mesh
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mesh -d mesh"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - noc

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis-data:/data
    networks:
      - noc

  prometheus:
    image: prom/prometheus:v2.54.1
    restart: unless-stopped
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.retention.time=180d
      - --web.enable-lifecycle
    volumes:
      - ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus
    ports:
      - "9090:9090"
    networks:
      - noc
      - telemetry

  alertmanager:
    image: prom/alertmanager:v0.27.0
    restart: unless-stopped
    command: ["--config.file=/etc/alertmanager/alertmanager.yml"]
    volumes:
      - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
      - alertmanager-data:/alertmanager
    ports:
      - "9093:9093"
    networks:
      - noc

  grafana:
    image: grafana/grafana:11.2.0
    restart: unless-stopped
    environment:
      GF_SERVER_ROOT_URL: https://noc.maplelan.ca/grafana
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
      GF_AUTH_ANONYMOUS_ENABLED: "false"
    volumes:
      - grafana-data:/var/lib/grafana
      - ./config/grafana/provisioning:/etc/grafana/provisioning:ro
    ports:
      - "3000:3000"
    networks:
      - noc

  node-exporter:
    image: prom/node-exporter:v1.8.2
    restart: unless-stopped
    pid: host
    command:
      - --path.rootfs=/host
      - --collector.systemd
      - --collector.ethtool
    volumes:
      - /:/host:ro,rslave
    networks:
      - telemetry

  bird-exporter:
    image: ghcr.io/czerwonk/bird_exporter:1.4.3
    restart: unless-stopped
    command: ["-bird.socket", "/run/bird/bird.ctl"]
    volumes:
      - /run/bird:/run/bird:ro
    ports:
      - "9324:9324"
    networks:
      - telemetry

networks:
  noc:
    driver: bridge
  telemetry:
    driver: bridge
    internal: true

volumes:
  postgres-data:
  redis-data:
  prometheus-data:
  alertmanager-data:
  grafana-data: