name: cedar-valley-mesh

x-logging: &default-logging
  logging:
    driver: json-file
    options:
      max-size: 20m
      max-file: "5"

services:
  controller:
    image: ghcr.io/cedar-valley-mesh/mesh-controller:1.18.3
    restart: unless-stopped
    <<: *default-logging
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_started
    ports:
      - "8080:8080"
    environment:
      NODE_ENV: production
      PUBLIC_BASE_URL: https://noc.cedarvalleymesh.net
      COMMUNITY_ASN: "4242421099"
      DEFAULT_MTU: "1420"
      WIREGUARD_PORT: "51820"
      DB_DSN: postgres://mesh:${POSTGRES_PASSWORD}@postgres:5432/meshnet
      REDIS_URL: redis://redis:6379/0
      MAP_TILE_URL: https://tiles.cedarvalleymesh.net/{z}/{x}/{y}.png
      ALERT_EMAIL_FROM: noc@cedarvalleymesh.net
      SMTP_HOST: smtp.mailgun.org
      SMTP_PORT: "587"
      SMTP_USER: ${SMTP_USER}
      SMTP_PASSWORD: ${SMTP_PASSWORD}
    volumes:
      - controller-state:/var/lib/mesh-controller
      - ./config/sites.yaml:/etc/mesh/sites.yaml:ro
      - ./config/radio-profiles.yaml:/etc/mesh/radio-profiles.yaml:ro

  routing-agent:
    image: ghcr.io/cedar-valley-mesh/gateway-agent:0.9.7
    restart: unless-stopped
    network_mode: host
    privileged: false
    cap_add:
      - NET_ADMIN
      - NET_RAW
      - SYS_MODULE
    environment:
      CONTROLLER_URL: http://127.0.0.1:8080
      GATEWAY_ID: gw-downtown-library-01
      BIRD_SOCKET: /run/bird/bird.ctl
      WG_INTERFACE: wg-mesh
      UPLINK_INTERFACE: eth0
      MESH_BRIDGE: br-mesh
      IPV4_POOL: 10.42.0.0/16
      IPV6_POOL: fd42:1099::/48
    volumes:
      - /etc/bird:/etc/bird
      - /run/bird:/run/bird
      - /etc/wireguard:/etc/wireguard
      - gateway-state:/var/lib/gateway-agent

  prometheus:
    image: prom/prometheus:v2.54.1
    restart: unless-stopped
    <<: *default-logging
    ports:
      - "9090:9090"
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.retention.time=45d
      - --web.enable-lifecycle
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus

  grafana:
    image: grafana/grafana:11.2.2
    restart: unless-stopped
    <<: *default-logging
    depends_on:
      - prometheus
    ports:
      - "3000:3000"
    environment:
      GF_SERVER_ROOT_URL: https://grafana.cedarvalleymesh.net
      GF_SECURITY_ADMIN_USER: admin
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
      GF_AUTH_ANONYMOUS_ENABLED: "false"
      GF_INSTALL_PLUGINS: grafana-worldmap-panel
    volumes:
      - grafana-data:/var/lib/grafana
      - ./monitoring/dashboards:/etc/grafana/provisioning/dashboards:ro
      - ./monitoring/datasources:/etc/grafana/provisioning/datasources:ro

  postgres:
    image: postgres:16.4-alpine
    restart: unless-stopped
    <<: *default-logging
    environment:
      POSTGRES_DB: meshnet
      POSTGRES_USER: mesh
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U mesh -d meshnet"]
      interval: 10s
      timeout: 5s
      retries: 6

  redis:
    image: redis:7.4-alpine
    restart: unless-stopped
    <<: *default-logging
    command: ["redis-server", "--appendonly", "yes"]
    volumes:
      - redis-data:/data

volumes:
  controller-state:
  gateway-state:
  prometheus-data:
  grafana-data:
  postgres-data:
  redis-data: