Configuration
Tally is configured entirely through environment variables. No config files, no UI settings — just environment variables, the way infrastructure should be.
Required
ADMIN_PASSWORD # Dashboard login password (min 16 chars in production)
SITES # JSON map of sites: {"domain.com":{"token":"secret"}}
Production safety:
If
NODE_ENV=production
, the server refuses to start with the default password or any password shorter than 16
characters.
Server
PORT # HTTP port (default: 3000)
DB_PATH # SQLite database path (default: ./data/analytics.db)
GEOLITE2_PATH # MaxMind GeoLite2-City.mmdb path (default: ./data/GeoLite2-City.mmdb)
TRUST_PROXY_AUTH # Trust X-Forwarded-For/X-Real-Ip headers (default: false)
API_KEY # API authentication key (falls back to ADMIN_PASSWORD)
Sites configuration
The
SITES
variable is a JSON object mapping site IDs to their tokens. The site ID is passed via the
data-site
attribute on the tracker script. The token is passed via
data-token
and used for origin validation.
SITES='{
"blog.example.com": { "token": "sk-blog-abc123" },
"docs.example.com": { "token": "sk-docs-def456" }
}'
GeoIP (optional)
MAXMIND_ACCOUNT_ID # MaxMind account ID for GeoLite2 downloads
MAXMIND_LICENSE_KEY # MaxMind license key
If both are provided, the Docker entrypoint automatically downloads the GeoLite2 City database on first start. Without GeoIP, country/city/region data will be unavailable.
Origin validation
The
ALLOWED_ORIGINS
variable controls which origins can send events:
ALLOWED_ORIGINS="https://example.com,https://www.example.com"
If empty, the server accepts events from any origin (useful for development). In production, set this to your site's origins.
Defaults (no configuration needed)
These work out of the box:
- SQLite database with WAL mode (automatic journaling and crash recovery)
- Daily aggregation rollups (runs every 6 hours)
- Session duration: 30 days (set by the tracker cookie)
- Ping interval: 15 seconds (for realtime tracking)
- Scroll beacon interval: 5 seconds (throttled)