From aeeed293af53b8c96058b691959c5910d5267e1e Mon Sep 17 00:00:00 2001 From: Michael Schiemer Date: Wed, 5 Nov 2025 04:42:17 +0100 Subject: [PATCH] feat(monitoring): Add direct VPN access configuration - Add docker-compose-direct-access.yml for VPN-only admin access - Configure Portainer on port 9002 (avoid MinIO conflict) - Add grafana.ini to disable external plugin update checks - Bind services to 10.8.0.1 (WireGuard VPN gateway) This configuration enables direct access to admin services via WireGuard VPN while removing Traefik routing overhead. Services are bound exclusively to the VPN gateway IP to prevent public access. --- .../docker-compose-direct-access.yml | 141 ++++++++++++++++++ .../stacks/monitoring/grafana/grafana.ini | 26 ++++ 2 files changed, 167 insertions(+) create mode 100644 deployment/stacks/monitoring/docker-compose-direct-access.yml create mode 100644 deployment/stacks/monitoring/grafana/grafana.ini diff --git a/deployment/stacks/monitoring/docker-compose-direct-access.yml b/deployment/stacks/monitoring/docker-compose-direct-access.yml new file mode 100644 index 00000000..441c9376 --- /dev/null +++ b/deployment/stacks/monitoring/docker-compose-direct-access.yml @@ -0,0 +1,141 @@ +services: + portainer: + image: portainer/portainer-ce:latest + container_name: portainer + restart: unless-stopped + # DIRECT ACCESS: Bind only to VPN gateway IP + ports: + - "10.8.0.1:9002:9000" # Port 9002 to avoid conflict with MinIO (port 9000) + networks: + - monitoring-internal + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - portainer-data:/data + # Removed Traefik labels - direct access only + + prometheus: + image: prom/prometheus:latest + container_name: prometheus + restart: unless-stopped + user: "65534:65534" + # DIRECT ACCESS: Bind only to VPN gateway IP + ports: + - "10.8.0.1:9090:9090" + networks: + - monitoring-internal + - app-internal + volumes: + - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro + - ./prometheus/alerts.yml:/etc/prometheus/alerts.yml:ro + - prometheus-data:/prometheus + command: + - '--config.file=/etc/prometheus/prometheus.yml' + - '--storage.tsdb.path=/prometheus' + - '--storage.tsdb.retention.time=30d' + - '--web.console.libraries=/usr/share/prometheus/console_libraries' + - '--web.console.templates=/usr/share/prometheus/consoles' + - '--web.enable-lifecycle' + # Removed Traefik labels - direct access only + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9090/-/healthy"] + interval: 30s + timeout: 10s + retries: 3 + + grafana: + image: grafana/grafana:latest + container_name: grafana + restart: unless-stopped + # DIRECT ACCESS: Bind only to VPN gateway IP + ports: + - "10.8.0.1:3001:3000" + networks: + - monitoring-internal + - app-internal + environment: + # Updated root URL for direct IP access + - GF_SERVER_ROOT_URL=http://10.8.0.1:3001 + - GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER} + - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD} + - GF_USERS_ALLOW_SIGN_UP=false + - GF_INSTALL_PLUGINS=${GRAFANA_PLUGINS} + - GF_LOG_LEVEL=info + - GF_ANALYTICS_REPORTING_ENABLED=false + # Performance: Disable external connections to grafana.com + - GF_PLUGIN_GRAFANA_COM_URL= + - GF_CHECK_FOR_UPDATES=false + - GF_CHECK_FOR_PLUGIN_UPDATES=false + # Disable background plugin installer completely + - GF_FEATURE_TOGGLES_ENABLE=disablePluginInstaller + - GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS= + volumes: + - grafana-data:/var/lib/grafana + - ./grafana/grafana.ini:/etc/grafana/grafana.ini:ro + - ./grafana/provisioning:/etc/grafana/provisioning:ro + - ./grafana/dashboards:/var/lib/grafana/dashboards:ro + # Removed Traefik labels - direct access only + depends_on: + prometheus: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/api/health"] + interval: 30s + timeout: 10s + retries: 3 + + node-exporter: + image: prom/node-exporter:latest + container_name: node-exporter + restart: unless-stopped + networks: + - app-internal + volumes: + - /proc:/host/proc:ro + - /sys:/host/sys:ro + - /:/rootfs:ro + command: + - '--path.procfs=/host/proc' + - '--path.sysfs=/host/sys' + - '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)' + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9100/metrics"] + interval: 30s + timeout: 10s + retries: 3 + + cadvisor: + image: gcr.io/cadvisor/cadvisor:latest + container_name: cadvisor + restart: unless-stopped + privileged: true + networks: + - app-internal + volumes: + - /:/rootfs:ro + - /var/run:/var/run:ro + - /sys:/sys:ro + - /var/lib/docker/:/var/lib/docker:ro + - /dev/disk/:/dev/disk:ro + devices: + - /dev/kmsg + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/healthz"] + interval: 30s + timeout: 10s + retries: 3 + +volumes: + portainer-data: + name: portainer-data + prometheus-data: + name: prometheus-data + grafana-data: + name: grafana-data + +networks: + # New internal network for monitoring services + monitoring-internal: + name: monitoring-internal + driver: bridge + app-internal: + external: true diff --git a/deployment/stacks/monitoring/grafana/grafana.ini b/deployment/stacks/monitoring/grafana/grafana.ini new file mode 100644 index 00000000..67364262 --- /dev/null +++ b/deployment/stacks/monitoring/grafana/grafana.ini @@ -0,0 +1,26 @@ +[analytics] +reporting_enabled = false +check_for_updates = false + +[plugins] +enable_alpha = false +plugin_admin_enabled = false +plugin_admin_external_manage_enabled = false +# Completely disable plugin catalog access +grafana_com_url = +# Disable background installer +allow_loading_unsigned_plugins = +# Disable plugin installation completely +plugin_catalog_hidden_plugins = * + +[plugin_management] +check_for_updates = false +enable_background_install = false +# Disable all plugin management +enabled = false + +[log] +level = info + +[server] +# Will be overridden by environment variable GF_SERVER_ROOT_URL