Skip to content

Logging (GoAccess → Grafana → Loki)

TL;DR / when to use this: My log stack evolved in three stages: GoAccess (lightweight, real-time analytics per proxy host), Grafana + GeoIP (dashboards with country data), and Loki + Promtail (the current setup — log aggregation with LogQL). The classic ELK stack still works but is heavier than Loki for a home server. Pick Loki unless you already have ELK running.

Stage 1 — GoAccess (Nginx Proxy Manager)

Lightweight, real-time analytics. The justsky/goaccess-for-nginxproxymanager image tails NPM's logs:

  goaccess:
    image: justsky/goaccess-for-nginxproxymanager:latest
    restart: unless-stopped
    environment:
      - TZ=America/Denver
    ports:
      - '7880:7880'
    volumes:
      - ./data/npm_data/logs:/opt/log
      # per-host analytics: mount just one proxy host's log
      # - ./data/npm_data/logs/proxy-host-1_access.log:/opt/log/proxy-host-1_access.log

GoAccess can digest all logs, but it can't filter per hostname — for per-host analytics, mount a single proxy-host-N_access.log (NPM writes one per proxy host).

Real IP behind Cloudflare

In the NPM advanced tab, add real_ip_header CF-Connecting-IP; so GoAccess sees the real client IP through a Cloudflare tunnel.

Stage 2 — Grafana + GeoIP

The preconfigured npmGrafStats dashboard adds country-level analytics on top of NPM + GoAccess, fed by a JSON access log with GeoIP fields (the JSON log format is in SWAG). Full setup in the post.

Stage 3 — Loki + Promtail (current)

Follow the official Loki docker-compose (pin the compose file to a version — floating examples go stale). Practical adjustments:

  • Promtail mounts the Nginx logs read-only (:/var/log/nginx:ro) and tails them into Loki.
  • Grafana auto-provisions Loki as the default datasource; anonymous admin is fine for a private LAN instance.
  • Query with LogQL — filter by label, e.g. {job="nginx"}.

This replaced GoAccess for me: structured JSON logs + GeoIP fields make Grafana panels far more useful than GoAccess's fixed analytics view.

Which to pick

Stack Strength Cost
GoAccess Zero-config real-time analytics Fixed views, no per-host filter
Grafana + GeoIP Country dashboards, custom panels Needs JSON logging
Loki + Promtail Full aggregation, LogQL, retention More moving parts
ELK Mature, powerful Heaviest footprint

See also