Datenschutzfreundliche Website-Analytik
Datenschutzfreundliche Website-Analytik mit Umami
Inhaltsverzeichnis
Einleitung
Google Analytics ist auf den meisten Websites Standard – doch die Datensammelei und komplexe Cookie-Banner sind längst nicht mehr zeitgemäß. In der EU müssen Websites mit DSGVO konform sein, was Google Analytics regelmäßig in Bedrängnis bringt.
Für matzka.cloud haben wir uns daher für Umami entschieden: ein leichtgewichtiges, datenschutzfreundliches und einfach zu integrierendes Analytics-System, das auf unserem eigenen Server läuft. In diesem Artikel zeige ich, wie wir Umami aufgebaut und integriert haben.
Warum nicht Google Analytics?
Die Probleme mit Google Analytics
- Datenschutz: Google Analytics sammelt umfangreiche Benutzerdaten und sendet diese an amerikanische Server
- DSGVO-Konformität: Viele Datenschutzbehörden stufen Google Analytics als nicht DSGVO-konform ein
- Cookie-Banner: Nervig für Benutzer und rechtlich fragwürdig
- Kosten: Kostenlos für kleine Websites, aber mit vielen Limitierungen
- Vendor Lock-in: Abhängigkeit von Google
Warum Umami?
- ✅ Datenschutzfreundlich – Keine Cookies, keine Benutzer-Tracking, kein Daten-Verkauf
- ✅ DSGVO-konform – Vollständig DSGVO-konform ohne Cookie-Banner nötig
- ✅ Self-Hosted – Läuft auf unserem eigenen Server – volle Kontrolle
- ✅ Open Source – Transparent und frei modifizierbar
- ✅ Leichtgewichtig – JavaScript-Datei ist nur ~2.7 KB (gzipped)
- ✅ Einfach zu integrieren – Ein einzeiliger Script-Tag
- ✅ Kostenlos – Keine Lizenzgebühren
Umami-Architektur auf matzka.cloud
Umami besteht aus zwei Komponenten:
- Umami Server – Ein Node.js-Backend für Datenspeicherung und -verarbeitung
- Umami Script – Ein JavaScript-Snippet, das auf der Website eingebunden wird
Deployment-Architektur
┌─────────────────────┐
│ Benutzer Browser │
├─────────────────────┤
│ Website (Next.js) │
│ + Umami Script Tag │
└──────────┬──────────┘
│ (HTTPS)
▼
┌──────────────────────────┐
│ Traefik (Reverse Proxy) │
│ analytics.matzka.cloud │
└──────────┬───────────────┘
│
▼
┌──────────────────────────┐
│ Umami Server │
│ (Node.js + PostgreSQL) │
└──────────────────────────┘
Docker-Container-Setup
Umami läuft in zwei separaten Containern:
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
container_name: umami
restart: unless-stopped
networks:
- frontend
- umami-backend
environment:
DATABASE_URL: postgresql://umami:${UMAMI_DB_PASSWORD}@postgres-umami:5432/umami
DATABASE_TYPE: postgresql
HASH_SALT: ${UMAMI_HASH_SALT}
DISABLE_TELEMETRY: true
CORS_DOMAINS: https://matzka.cloud
labels:
- "traefik.enable=true"
- "traefik.http.routers.umami.rule=Host(`analytics.matzka.cloud`)"
- "traefik.http.routers.umami.entrypoints=websecure"
- "traefik.http.routers.umami.tls.certresolver=letsencrypt"
- "traefik.http.services.umami.loadbalancer.server.port=3003"
depends_on:
- postgres-umami
postgres-umami:
image: postgres:17-alpine
container_name: postgres-umami
restart: unless-stopped
networks:
- umami-backend
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: ${UMAMI_DB_PASSWORD}
volumes:
- postgres_umami_data:/var/lib/postgresql/data
DATABASE_URL: Verbindung zur PostgreSQL-DatenbankHASH_SALT: Zufällige Zeichenkette zur Hassung von Benutzer-IPsDISABLE_TELEMETRY: Umami sendet keine Telemetrie-DatenCORS_DOMAINS: Whitelisting für unsere Website-Domain
Integration in die Next.js WebApp
Script-Tag einbinden
Das Umami-Tracking wird über einen einfachen Script-Tag eingebunden:
// webapp-deployment/app/app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<head>
{/* ... andere Head-Tags ... */}
{/* Umami Analytics */}
<script
async
src="https://analytics.matzka.cloud/script.js"
data-website-id="d1234567-89ab-cdef-0123-abcdef456789"
/>
</head>
<body>{children}</body>
</html>
);
}
data-website-id: Eindeutige ID für die Website (aus Umami-Dashboard)async: Script wird asynchron geladen – blockiert Seite nicht
Custom Events tracken
Neben automatischen Seitenaufrufen können wir auch benutzerdefinierte Events tracken:
// Beispiel: Formular-Submission in Contact-Form
import { useCallback } from 'react';
export function ContactForm() {
const handleSubmit = useCallback(async (e: React.FormEvent) => {
e.preventDefault();
// Custom Event an Umami senden
if (typeof window !== 'undefined' && 'umami' in window) {
(window as any).umami.track('form_submitted', {
form_type: 'contact',
form_section: 'homepage',
});
}
// Formular-Logik...
}, []);
return <form onSubmit={handleSubmit}>{/* ... */}</form>;
}
Automatisch getrackte Events
Umami trackt automatisch:
- Seitenaufrufe – Jeder Seitenwechsel
- Referrer – Woher der Benutzer kam
- Browser & OS – Automatische Erkennung
- Geolocation – Land/Stadt (aus IP-Adresse)
- Bildschirmauflösung – Screen Size
- Gerätetyp – Desktop, Tablet, Mobile
Cookie-Policy & Datenschutz
Warum Umami DSGVO-konform ist
- Keine Cookies: Umami nutzt keine Cookies – daher kein Cookie-Banner nötig
- Anonymisierte IPs: Nur die letzte Ziffer der IP wird gespeichert (z.B. 192.168.1.x)
- Keine Benutzer-Tracking: Benutzer können nicht über Sessions identifiziert werden
- Keine 3rd-Party-Daten: Daten verlassen unseren Server nicht
- Keine Profilbildung: Keine Data-Broker oder Retargeting
- ✅ Erfordernis 1: Rechtliche Grundlage (legitimes Interesse)
- ✅ Erfordernis 2: Datenschutzerklärung (transparent dokumentiert)
- ✅ Erfordernis 3: Benutzerrechte (IP-Anonymisierung)
Umami-Dashboard nutzen
Zugriff auf das Analytics-Dashboard
Das Umami-Dashboard ist unter https://analytics.matzka.cloud erreichbar und zeigt:
1. Übersichts-Dashboard
- Besucher (24h): 127 Besucher
- Seitenaufrufe (24h): 453 Aufrufe
- Bounce Rate: 34%
- Session-Länge: ∅ 2:15 Minuten
2. Echtzeit-Daten
- Aktive Besucher jetzt
- Aktuelle Seitenaufrufe
- Live-Besucherverhalten
3. Seitenanalyse
- Top Pages (nach Aufrufen)
- Conversion-Funnel
- Top Entry Pages
4. Besucheranalyse
- Browser & OS
- Gerätetypen (Desktop/Mobile/Tablet)
- Länder/Regionen
- Bildschirmauflösungen
5. Events
- Custom Events pro Seite
- Event-Tracking über Zeit
- Event-Conversion-Rate
Performance-Auswirkungen
Lighthouse-Scores mit/ohne Umami
| Metrik | Ohne Umami | Mit Umami | Differenz |
|---|---|---|---|
| Performance | 94 | 92 | -2 |
| Accessibility | 98 | 98 | — |
| Best Practices | 96 | 96 | — |
| SEO | 100 | 100 | — |
Optimierungen
- Asynchrones Laden:
asyncAttribut im Script-Tag - Script Defer:
deferkann zusätzlich verwendet werden - Server-Side Events: Optional möglich, aber nicht nötig
Sicherheit
Authentifizierung
Das Umami-Dashboard ist mit Standard-Benutzern geschützt:
Netzwerk-Sicherheit
- HTTPS Only: Alle Verbindungen via TLS verschlüsselt
- CORS: Nur
matzka.clouderlaubt (andere Domains können nicht tracken) - Firewall: Analytics-Port nur über Traefik erreichbar
- Database: PostgreSQL-Passwort aus
.env(nicht in Git)
Regelmäßige Backups
Umami-Daten werden täglich gesichert:
- PostgreSQL-Datenbank:
postgres_umami_dataVolume - Retention: 30 Tage (wie alle anderen Services)
Migration von Google Analytics
Schritt-für-Schritt Anleitung
-
Umami einrichten
docker-compose up -d postgres-umami umami -
Website registrieren
Dashboard:https://analytics.matzka.cloud
Admin-Login → "Add Website" → Domain hinzufügen → Website-ID kopieren -
Script-Tag einbinden
<script async src="https://analytics.matzka.cloud/script.js" data-website-id="YOUR_WEBSITE_ID" ></script> -
Altes Google Analytics entfernen
<!-- Alten gtag.js Script entfernen --> <!-- <script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script> --> -
Neue Daten warten
Nach 24 Stunden sind genug Daten für Vergleiche vorhanden. Nach 7 Tagen haben Sie statistische Signifikanz.
Best Practices
1. Events sinnvoll nutzen
Schlecht:
umami.track('click', { clicked: true });
Gut:
umami.track('form_submitted', {
form_type: 'contact',
success: true
});
umami.track('blog_article_read', {
article_id: 'umami-analytics',
reading_time: 8
});
2. Regelmäßig Reports überprüfen
- Wöchentlich: Top Pages & Bounce Rate
- Monatlich: Browser/Device Mix & Conversion Rates
- Quartal: Traffic Trends & Neue Benutzer
3. Häufige Probleme
Problem: Keine Daten werden trackt
- Script-ID in HTML überprüfen:
<script data-website-id="..."> - Browser-Konsole auf Fehler prüfen: F12 → Console → Errors
- Network-Tab prüfen: Rufen nach
analytics.matzka.cloud/collect? - CORS überprüfen:
curl -H "Origin: https://matzka.cloud" \ -H "Access-Control-Request-Method: POST" \ https://analytics.matzka.cloud/ - Umami-Logs:
docker logs umami | tail -50
Problem: Extrem hohe Page-View-Zahlen
Mögliche Ursachen:
- Bot-Traffic (Search-Engine Crawlers)
- Mehrfaches Script-Laden
- CORS-Fehler mit Wiederholungen
Lösung – Bot-Traffic filtern:
<script
async
src="https://analytics.matzka.cloud/script.js"
data-website-id="..."
data-exclude="/admin/*"
/>
Kosten und Ressourcen
Hardware-Anforderungen
- RAM: ~100-150 MB (Umami + PostgreSQL)
- CPU: Minimal (1-2% bei normalem Traffic)
- Storage: ~500 MB pro Jahr (~42 MB/Monat)
Mit 50.000 monatlichen Seitenaufrufen = ~75 MB/Jahr
Kostenaufschlüsselung
| Item | Kosten |
|---|---|
| Umami Software | 0€ (Open Source) |
| PostgreSQL | 0€ (Open Source) |
| Server-Ressourcen | Bereits vorhanden |
| Manuelle Konfiguration | ~2 Stunden |
| Gesamt | 0€ |
vs. Google Analytics:
- GA kostenlos: 0€ (aber Daten gehört Google)
- GA 360: ~150.000€/Jahr (für Unternehmen)
Fazit
- ✅ Datenschutzfreundlich ist – DSGVO-konform ohne Cookies
- ✅ Selbstgehostet läuft – Volle Kontrolle über Daten
- ✅ Einfach zu nutzen ist – Minimaler Overhead
- ✅ Kostenlos ist – Keine Lizenzgebühren
- ✅ Transparent ist – Open Source Code
Die Integration war einfach (30 Minuten Arbeit) und die Performance-Auswirkung minimal. Das Dashboard gibt uns alle nötigen Insights zur Website-Optimierung.
Für Website-Betreiber, die Datenschutz ernst nehmen, ist Umami eine exzellente Alternative zu Google Analytics.
Weiterführende Links
- Umami Dokumentation: https://umami.is/docs
- GitHub Repository: https://github.com/umami-software/umami
- Docker Hub: https://hub.docker.com/r/umami-software/umami
- Community Forum: https://github.com/umami-software/umami/discussions
- Datenschutz-Generator: https://www.iubenda.com/privacy-policy-generator