analytics: GoAccess reports from the Caddy logs, public and private tiers

Server-side only, per the privacy policy: no client-side analytics. Rotated
logs ingest exactly once into per-tier DBs; the public tier is anonymized
at ingest and never receives censored paths. Log retention raised to a year.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-08-08 02:50:52 +02:00
commit 8cd4d55d00
6 changed files with 251 additions and 0 deletions

View file

@ -43,6 +43,37 @@ catcrafts.net {
header /styles.css Cross-Origin-Resource-Policy "same-origin"
header /favicon.svg Cross-Origin-Resource-Policy "same-origin"
# ── analytics, two tiers ──────────────────────────────────────────────
#
# GoAccess reports rebuilt hourly by catcrafts-analytics.timer from the
# access logs below. Server-side only: no client-side analytics anywhere
# on the site, per the privacy policy (request logging only).
#
# /analytics/ is public and censored - visitor IPs are anonymized at
# ingest, there is no host panel, and sensitive paths never enter its DB
# (see CENSOR_RE in deploy/catcrafts-analytics). /analytics/private/ is
# the uncensored report. Generate the hash with `caddy hash-password`.
redir /analytics /analytics/ 308
redir /analytics/private /analytics/private/ 308
# The privacy policy's "view previous versions" promise. A redirect so
# the policy text stays short and survives repo or path moves - update
# the target here, never the policy wording.
redir /legal/privacy/history https://forgejo.catcrafts.net/Catcrafts/catcrafts.net/commits/branch/master/shared/interfaces/Catcrafts.Shared-Content.cppm 302
handle_path /analytics/private/* {
basic_auth {
jorijn <bcrypt-hash-here>
}
root * /var/www/analytics-private
header Cache-Control "private, no-store"
file_server
}
handle_path /analytics/* {
root * /var/www/analytics
header Cache-Control "public, max-age=600"
file_server
}
# ── build artifacts: served from disk ─────────────────────────────────
#
# file_server does sendfile, precompressed variants and range requests far
@ -98,4 +129,18 @@ catcrafts.net {
header Cache-Control "no-store"
file_server
}
# ── access log ────────────────────────────────────────────────────────
#
# Feeds the GoAccess analytics (see deploy/catcrafts-analytics). Retention
# sized for that: ~15 MB/day means a roll roughly weekly; 52 compressed
# rolls ~ a year of raw logs (~6 MB each gzipped). roll_keep_for must be
# explicit — lumberjack's default silently deletes after 90 days.
log {
output file /var/log/caddy/catcrafts.net.log {
roll_size 100MiB
roll_keep 52
roll_keep_for 8760h
}
}
}