Add self-hosted usage analytics: pageview tracking + admin stats dashboard
Records pageviews (path, referrer, browser/OS/device, IP, GeoIP country) via a POST /api/track beacon into a new PageView table, and exposes aggregated daily/breakdown stats behind a token-gated GET /api/admin/stats endpoint with brute-force lockout. Frontend gets a /admin dashboard (charts + breakdown tables) built on recharts, with a switchable per-day pageviews chart. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Production stack: built images (no bind mounts), nginx serves the built
|
||||
# frontend + reverse-proxies Socket.IO, Postgres is internal-only.
|
||||
#
|
||||
# Usage:
|
||||
# cp .env.example .env # fill in real secrets
|
||||
# docker compose -f docker-compose.prod.yaml up -d --build
|
||||
|
||||
services:
|
||||
db:
|
||||
image: postgres:18-alpine
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: ${POSTGRES_DB}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql
|
||||
restart: always
|
||||
|
||||
backend:
|
||||
build: .
|
||||
environment:
|
||||
DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
|
||||
CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS}
|
||||
ADMIN_TOKEN: ${ADMIN_TOKEN}
|
||||
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
|
||||
GEOIP_DB_PATH: /app/geoip/GeoLite2-Country.mmdb
|
||||
volumes:
|
||||
- ./geoip:/app/geoip:ro
|
||||
restart: always
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
frontend:
|
||||
build: ./frontend
|
||||
environment:
|
||||
BACKEND_UPSTREAM: backend:5000
|
||||
restart: always
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
Reference in New Issue
Block a user