Files
devops/hostinger/system-stack.yaml
Felix FaerberandClaude Opus 4.7 7fcd9df9d3 grafana: provision Loki/Prometheus datasources + log dashboards
Bind two ready-to-use dashboards at grafana.t4t-gateway.com:

- Logs — All services: per-service log volume timeseries + live tail,
  with a service selector and a free-text search box.
- Hosted-gateway API — errors & PSS inbox: error rate, ack/deliver
  counters, and a live tail filtered to PSS inbox traffic so the
  webhook fallback is observable.

Datasources + dashboard providers are mounted via Docker configs from
hostinger/grafana/ so they survive grafana container restarts and live
in git rather than the Grafana UI.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 10:53:26 +03:00

252 lines
7.3 KiB
YAML

version: '3.8'
networks:
public:
name: public
driver: overlay
internal:
name: internal
driver: overlay
volumes:
traefik-letsencrypt:
driver: local
traefik-logs:
driver: local
grafana-data:
driver: local
loki-data:
driver: local
prometheus-data:
driver: local
configs:
loki_config:
file: ./loki.yaml
prometheus_config:
file: ./prometheus.yml
grafana_datasources:
file: ./grafana/datasources.yaml
grafana_dashboard_providers:
file: ./grafana/dashboards.yaml
grafana_dashboard_logs:
file: ./grafana/dashboards/logs-overview.json
grafana_dashboard_api:
file: ./grafana/dashboards/api-errors.json
services:
traefik:
image: traefik:v3.7.1
ports:
- "80:80"
- "443:443"
command:
- --providers.swarm.endpoint=unix:///var/run/docker.sock
- --providers.swarm.network=public
- --providers.swarm.constraints=Label(`traefik.constraint-label`, `public`)
- --providers.swarm.exposedByDefault=false
- --entrypoints.web.address=:80
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
- --entrypoints.websecure.address=:443
- --certificatesresolvers.le.acme.email=t4t-gateway@proton.me
- --certificatesresolvers.le.acme.storage=/certificates/acme.json
- --certificatesresolvers.le.acme.tlschallenge=true
- --api=true
- --api.dashboard=true
- --metrics.prometheus=true
- --accesslog=true
- --log=true
networks:
- public
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- traefik-letsencrypt:/certificates
- traefik-logs:/var/log/traefik
deploy:
placement:
constraints:
- node.role == manager
resources:
limits:
memory: 256M
reservations:
memory: 128M
labels:
- "traefik.enable=true"
- "traefik.docker.network=public"
- "traefik.constraint-label=public"
- "traefik.http.routers.dashboard.service=api@internal"
- "traefik.http.routers.traefikk.rule=Host(`traefik.t4t-gateway.com`)"
- "traefik.http.routers.traefikk.entrypoints=websecure"
- "traefik.http.routers.traefikk.tls.certresolver=le"
- "traefik.http.routers.traefikk.middlewares=admin-auth"
- "traefik.http.services.traefikk.loadbalancer.server.port=8080"
- "traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$w3jsONTx$$8byZ1a/GOfoKumowv773P."
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
logging:
driver: loki
options:
loki-url: "https://loki.t4t-gateway.com/loki/api/v1/push"
grafana:
image: grafana/grafana:12.4.2
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:3000/api/health || exit 1"]
interval: 10s
timeout: 3s
retries: 3
start_period: 10s
networks:
- public
- internal
volumes:
- grafana-data:/var/lib/grafana
configs:
- source: grafana_datasources
target: /etc/grafana/provisioning/datasources/datasources.yaml
- source: grafana_dashboard_providers
target: /etc/grafana/provisioning/dashboards/dashboards.yaml
- source: grafana_dashboard_logs
target: /etc/grafana/dashboards/logs-overview.json
- source: grafana_dashboard_api
target: /etc/grafana/dashboards/api-errors.json
environment:
- GF_AUTH_DISABLE_LOGIN_FORM=true
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_SECURITY_ALLOW_EMBEDDING=true
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
labels:
- "traefik.enable=true"
- "traefik.http.routers.grafana.rule=Host(`grafana.t4t-gateway.com`)"
- "traefik.http.routers.grafana.entrypoints=websecure"
- "traefik.http.routers.grafana.tls.certresolver=le"
- "traefik.docker.network=public"
- "traefik.constraint-label=public"
- "traefik.http.services.grafana.loadbalancer.server.port=3000"
- "traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$w3jsONTx$$8byZ1a/GOfoKumowv773P."
- "traefik.http.routers.grafana.middlewares=admin-auth,redirect-to-https"
logging:
driver: loki
options:
loki-url: "https://loki.t4t-gateway.com/loki/api/v1/push"
loki:
image: grafana/loki:2.9.7
networks:
- public
- internal
configs:
- source: loki_config
target: /etc/loki/loki.yaml
volumes:
- loki-data:/loki
command: -config.file=/etc/loki/loki.yaml
deploy:
resources:
limits:
memory: 256M
reservations:
memory: 128M
labels:
- "traefik.enable=true"
- "traefik.http.routers.loki.rule=Host(`loki.t4t-gateway.com`)"
- "traefik.http.routers.loki.entrypoints=websecure"
- "traefik.http.routers.loki.tls.certresolver=le"
- "traefik.docker.network=public"
- "traefik.constraint-label=public"
- "traefik.http.services.loki.loadbalancer.server.port=3100"
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
prometheus:
image: prom/prometheus:v3.7.2
networks:
- public
- internal
configs:
- source: prometheus_config
target: /etc/prometheus/prometheus.yml
volumes:
- prometheus-data:/prometheus
command: --config.file=/etc/prometheus/prometheus.yml
deploy:
resources:
limits:
memory: 1024M
reservations:
memory: 512M
labels:
- "traefik.enable=true"
- "traefik.http.routers.prometheus.rule=Host(`prometheus.t4t-gateway.com`)"
- "traefik.http.routers.prometheus.entrypoints=websecure"
- "traefik.http.routers.prometheus.tls.certresolver=le"
- "traefik.docker.network=public"
- "traefik.constraint-label=public"
- "traefik.http.services.prometheus.loadbalancer.server.port=9090"
- "traefik.http.middlewares.admin-auth.basicauth.users=admin:$$apr1$$w3jsONTx$$8byZ1a/GOfoKumowv773P."
- "traefik.http.routers.prometheus.middlewares=admin-auth"
logging:
driver: loki
options:
loki-url: "https://loki.t4t-gateway.com/loki/api/v1/push"
node-exporter:
image: prom/node-exporter:master
command: --path.rootfs=/host
networks:
- internal
deploy:
mode: global
resources:
limits:
memory: 32M
reservations:
memory: 24M
logging:
driver: loki
options:
loki-url: "https://loki.t4t-gateway.com/loki/api/v1/push"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
networks:
- internal
volumes:
- /:/rootfs:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /sys/fs/cgroup:/sys/fs/cgroup:ro
deploy:
mode: global
resources:
limits:
memory: 128M
reservations:
memory: 65M
logging:
driver: loki
options:
loki-url: "https://loki.t4t-gateway.com/loki/api/v1/push"