# docker-compose.monitoring.yml
# Complete monitoring stack for Waygate MCP Proxy security architecture
version: '3.8'
services:
# Prometheus - Metrics collection and alerting
prometheus:
image: prom/prometheus:v2.47.2
container_name: waygate-prometheus
hostname: prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--storage.tsdb.retention.size=10GB'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
- '--web.enable-admin-api'
- '--log.level=info'
volumes:
- ../monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ../monitoring/alert_rules.yml:/etc/prometheus/alert_rules.yml:ro
- ../monitoring/recording_rules.yml:/etc/prometheus/recording_rules.yml:ro
- prometheus-data:/prometheus
- prometheus-config:/etc/prometheus
ports:
- "127.0.0.1:9090:9090"
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
user: "nobody"
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9090/-/healthy"]
interval: 30s
timeout: 10s
retries: 3
# Grafana - Visualization and dashboards
grafana:
image: grafana/grafana:10.2.0
container_name: waygate-grafana
hostname: grafana
environment:
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_USERS_ALLOW_ORG_CREATE=false
- GF_SECURITY_DISABLE_GRAVATAR=true
- GF_ANALYTICS_REPORTING_ENABLED=false
- GF_ANALYTICS_CHECK_FOR_UPDATES=false
- GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel
volumes:
- grafana-data:/var/lib/grafana
- ../monitoring/grafana-dashboard.json:/var/lib/grafana/dashboards/waygate-dashboard.json:ro
- ../monitoring/grafana-provisioning:/etc/grafana/provisioning:ro
ports:
- "127.0.0.1:3000:3000"
networks:
- waygate-monitoring
depends_on:
- prometheus
restart: unless-stopped
security_opt:
- no-new-privileges:true
user: "472"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
interval: 30s
timeout: 10s
retries: 3
# AlertManager - Alert routing and notification
alertmanager:
image: prom/alertmanager:v0.26.0
container_name: waygate-alertmanager
hostname: alertmanager
command:
- '--config.file=/etc/alertmanager/config.yml'
- '--storage.path=/alertmanager'
- '--web.external-url=http://localhost:9093'
- '--log.level=info'
volumes:
- ../monitoring/alertmanager.yml:/etc/alertmanager/config.yml:ro
- alertmanager-data:/alertmanager
ports:
- "127.0.0.1:9093:9093"
networks:
- waygate-monitoring
depends_on:
- prometheus
restart: unless-stopped
security_opt:
- no-new-privileges:true
user: "nobody"
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9093/-/healthy"]
interval: 30s
timeout: 10s
retries: 3
# Node Exporter - System metrics
node-exporter:
image: prom/node-exporter:v1.6.1
container_name: waygate-node-exporter
hostname: node-exporter
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
- '--collector.systemd'
- '--collector.processes'
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
ports:
- "127.0.0.1:9100:9100"
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
pid: host
# cAdvisor - Container metrics
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.2
container_name: waygate-cadvisor
hostname: cadvisor
privileged: true
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
ports:
- "127.0.0.1:8080:8080"
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
devices:
- /dev/kmsg
# Victoria Metrics - Long-term storage
victoria-metrics:
image: victoriametrics/victoria-metrics:v1.93.8
container_name: waygate-victoria-metrics
hostname: victoria-metrics
command:
- '--storageDataPath=/storage'
- '--httpListenAddr=:8428'
- '--retentionPeriod=2y'
- '--loggerLevel=INFO'
volumes:
- victoria-metrics-data:/storage
ports:
- "127.0.0.1:8428:8428"
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
user: "nobody"
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8428/health"]
interval: 30s
timeout: 10s
retries: 3
# Elasticsearch - Log storage and search
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
container_name: waygate-elasticsearch
hostname: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- xpack.security.enabled=false
- xpack.monitoring.collection.enabled=true
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
ports:
- "127.0.0.1:9200:9200"
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
ulimits:
memlock:
soft: -1
hard: -1
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9200/_cluster/health"]
interval: 30s
timeout: 10s
retries: 5
# Kibana - Log visualization
kibana:
image: docker.elastic.co/kibana/kibana:8.11.0
container_name: waygate-kibana
hostname: kibana
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- SERVER_NAME=waygate-kibana
ports:
- "127.0.0.1:5601:5601"
networks:
- waygate-monitoring
depends_on:
- elasticsearch
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5601/api/status"]
interval: 30s
timeout: 10s
retries: 5
# Jaeger - Distributed tracing
jaeger:
image: jaegertracing/all-in-one:1.51.0
container_name: waygate-jaeger
hostname: jaeger
environment:
- COLLECTOR_OTLP_ENABLED=true
- COLLECTOR_ZIPKIN_HOST_PORT=:9411
ports:
- "127.0.0.1:16686:16686" # Jaeger UI
- "127.0.0.1:14268:14268" # Jaeger collector HTTP
- "127.0.0.1:14250:14250" # Jaeger collector gRPC
- "127.0.0.1:4317:4317" # OTLP gRPC receiver
- "127.0.0.1:4318:4318" # OTLP HTTP receiver
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:16686/"]
interval: 30s
timeout: 10s
retries: 3
# Blackbox Exporter - External endpoint monitoring
blackbox-exporter:
image: prom/blackbox-exporter:v0.24.0
container_name: waygate-blackbox-exporter
hostname: blackbox-exporter
volumes:
- ../monitoring/blackbox.yml:/config/blackbox.yml:ro
ports:
- "127.0.0.1:9115:9115"
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
user: "nobody"
command:
- '--config.file=/config/blackbox.yml'
# Security Information and Event Management (SIEM)
wazuh:
image: wazuh/wazuh-odfe:4.7.0
container_name: waygate-wazuh
hostname: wazuh
environment:
- WAZUH_MANAGER_HOST=wazuh-manager
volumes:
- wazuh-data:/var/ossec/data
- ../monitoring/wazuh-config:/var/ossec/etc:ro
ports:
- "127.0.0.1:5601:5601" # Wazuh UI (alternative to Kibana)
networks:
- waygate-monitoring
restart: unless-stopped
security_opt:
- no-new-privileges:true
volumes:
prometheus-data:
driver: local
prometheus-config:
driver: local
grafana-data:
driver: local
alertmanager-data:
driver: local
victoria-metrics-data:
driver: local
elasticsearch-data:
driver: local
wazuh-data:
driver: local
networks:
waygate-monitoring:
driver: bridge
ipam:
config:
- subnet: 172.31.0.0/16
driver_opts:
com.docker.network.bridge.name: waygate-monitoring