Appearance
Self-hosting
Eureka Analytics runs on your own infrastructure as a set of containers. Every component is stateless except ClickHouse (analytics data), PostgreSQL (accounts and settings) and Redpanda/Kafka (the event log), which can be self-hosted or replaced by managed services.
Components
| Service | Role | Port |
|---|---|---|
collector | Receives tag and server hits (/v1/c, /v1/p.gif, /v1/s, /v1/config/{pid}.json) | 8080 |
processor | Classifies actors, builds sessions, writes to ClickHouse in batches | — |
api | Admin and reporting API, public API v1, prompt reporting | 3000 (container 8080) |
ui | Web app | 5173 (container 80) |
tag-cdn | Serves ah.js | 8081 |
clickhouse, postgres, redpanda | Storage and event log | 8123, —, 19092 |
Single server with Docker Compose
bash
cp deploy/.env.example deploy/.env # set every secret
docker compose -f deploy/docker-compose.yml --env-file deploy/.env up -d --build
# Collector http://localhost:8080 · Tag http://localhost:8081/ah.js · API http://localhost:3000 · App http://localhost:5173The ClickHouse schema is created on first start. The API applies the PostgreSQL migrations on start.
With the demo data
bash
docker compose -f deploy/docker-compose.yml --env-file deploy/.env --profile demo up -d --build
# then open http://localhost:5173/demoThe demo-data service generates 120 days of Summit Supply traffic (about 3.8 million events) the first time, then keeps generating live traffic.
Kubernetes
bash
kubectl create namespace ah
kubectl -n ah apply -k deploy/k8sThe manifests deploy the collector (with a horizontal autoscaler, 3 to 60 pods), the processor (keep replicas at or below the number of Kafka partitions, 12 by default), the API, the app, the tag CDN, the demo traffic and an ingress for three hostnames (collect., cdn., app.). ClickHouse, Kafka and PostgreSQL are expected to be managed services (ClickHouse Cloud or the Altinity operator, Redpanda Cloud or MSK, Cloud SQL or RDS); set their URLs in the secret (deploy/k8s/secret.example.yaml, to replace with your secret manager).
Environment variables
Main settings in deploy/.env:
| Variable | Purpose |
|---|---|
CLICKHOUSE_PASSWORD, POSTGRES_PASSWORD | Database passwords |
JWT_SECRET | Signs app sessions (32+ characters) |
AH_IP_SALT_SECRET | Derives the daily salts used to hash IPs and cookieless visitor IDs. Required in production. |
ANTHROPIC_API_KEY | Enables questions in plain English (Claude). AH_DISABLE_ASK=1 turns the feature off. AH_ANTHROPIC_MODEL and AH_ANTHROPIC_EFFORT tune it. |
AH_INTERNAL_TOKEN | Protects internal endpoints (collection status) |
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRICE_<PLAN>_<PERIOD> | Billing. Without them, plan changes apply immediately (development mode). |
DEMO_ENABLED, DEMO_ASK_PER_HOUR, DEMO_ASK_DAILY_CAP | Public demo |
Collector and processor (AH_ variables):
| Variable | Default | Purpose |
|---|---|---|
AH_MODE | standalone | collector, processor or standalone (both in one process, no Kafka: for small installs) |
AH_PROPERTIES_FILE | properties.yaml | Properties, allowed hostnames, ingest keys, tag configuration. Reload with SIGHUP. |
AH_KAFKA_BROKERS | localhost:9092 | Kafka / Redpanda brokers |
AH_CLICKHOUSE_DSN | clickhouse://default:@localhost:9000/ah | ClickHouse (native protocol) |
AH_TRUST_PROXY_HEADERS | false | Read the client IP from CF-Connecting-IP / X-Forwarded-For behind a load balancer or CDN |
AH_GEOIP_CITY_DB, AH_GEOIP_ASN_DB | — | MaxMind databases for geography and network |
AH_FETCH_IP_RANGES | true | Download the bots' published IP ranges daily |
AH_FLUSH_INTERVAL, AH_FLUSH_MAX_ROWS | 1s, 50000 | Batch size of database writes |
AH_SESSION_TIMEOUT | 30m | Server-side session split |
Scaling
- The collector handles tens of thousands of requests per second per vCPU and scales horizontally.
- The processor scales with the Kafka partitions; events of a visitor stay in order within a partition.
- ClickHouse scales by shards (by property) and replicas; one cluster per region keeps data in its region.