Self-hosted web analytics using Matomo, deployed on Kubernetes with raw manifests. A privacy-first alternative to Google Analytics — all data stays in your infrastructure.
Designed to run on the Kapsule cluster provisioned by scaleway-starter-kit.
- A running Kapsule cluster (from scaleway-starter-kit)
KUBECONFIGset (viasource .envfrom scaleway-starter-kit)- kubectl
./scripts/deploy.shThe script will:
- Create the
matomonamespace - Create MariaDB credentials (prompted interactively)
- Deploy MariaDB (in-cluster, with persistent storage)
- Deploy Matomo (official
matomo:5-apacheimage) - Print the access URL
Matomo is accessed via kubectl port-forward:
kubectl port-forward svc/matomo 8080:80 -n matomoThen open http://localhost:8080 to complete the setup wizard.
This keeps Matomo private (no public exposure) and avoids coupling this project with the starter kit's load balancer configuration. For production use, consider adding a dedicated ingress or a subdomain route on the load balancer.
k8s/
├── namespace.yaml # matomo namespace
├── mariadb.yaml # MariaDB deployment, PVC, and service
└── matomo.yaml # Matomo deployment, PVC, and service
scripts/
└── deploy.sh # Deployment script
sovereign-cloud-wisdom uses server-side tracking via Matomo's Tracking HTTP API. The app calls Matomo directly over the internal Kubernetes network at http://matomo.matomo.svc.cluster.local.
This approach is preferred over client-side JavaScript tracking because:
- No public exposure — Matomo doesn't need to be reachable from the internet
- No browser dependency — tracking works regardless of ad blockers or disabled JavaScript
- Data stays internal — analytics traffic never leaves the cluster
To enable tracking, create the Matomo ConfigMap and auth token secret in the app namespace.
The auth token is required for geolocation to work — Matomo only accepts client IP overrides (cip) with a valid token_auth. You can find your token in Matomo under Settings > Personal > Security > Auth tokens.
If you create a new one, uncheck both check boxes (secure requests and expiration).
kubectl create secret generic matomo-token-auth \
--namespace sovereign-wisdom \
--from-literal=token="<your-matomo-auth-token>" \
--dry-run=client -o yaml | kubectl apply -f -Create the Matomo ConfigMap:
kubectl create configmap matomo-config \
--namespace sovereign-wisdom \
--from-literal=matomo-url="http://matomo.matomo.svc.cluster.local" \
--from-literal=matomo-site-id="1" \
--dry-run=client -o yaml | kubectl apply -f -Then restart the app pods to pick up the new config:
kubectl rollout restart deployment/sovereign-wisdom -n sovereign-wisdomBy default, Matomo determines visitor location from the browser language, which is inaccurate. For IP-based geolocation, install the free DBIP City Lite database:
kubectl exec -n matomo deploy/matomo -- bash -c \
'curl -sL "https://download.db-ip.com/free/dbip-city-lite-2026-02.mmdb.gz" \
| gunzip > /var/www/html/misc/DBIP-City.mmdb'Then in Matomo, go to Administration > System > Geolocation and select DBIP / GeoIP 2 (Php).
The database is persisted on the Matomo PVC. Update the URL monthly (replace 2026-02 with the current year-month) to keep it current.