Zurück zum Blog

Datenschutzfreundliche Website-Analytik

Datenschutzfreundliche Website-Analytik mit Umami

Datenschutzfreundliche Website-Analytik mit Umami

Kategorie Analytics & Privacy
Datum 6. Januar 2025
Lesezeit 10 Minuten

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

  1. Datenschutz: Google Analytics sammelt umfangreiche Benutzerdaten und sendet diese an amerikanische Server
  2. DSGVO-Konformität: Viele Datenschutzbehörden stufen Google Analytics als nicht DSGVO-konform ein
  3. Cookie-Banner: Nervig für Benutzer und rechtlich fragwürdig
  4. Kosten: Kostenlos für kleine Websites, aber mit vielen Limitierungen
  5. Vendor Lock-in: Abhängigkeit von Google

Warum Umami?

Vorteile von 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:

  1. Umami Server – Ein Node.js-Backend für Datenspeicherung und -verarbeitung
  2. 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
Wichtige Konfigurationen:
  • DATABASE_URL: Verbindung zur PostgreSQL-Datenbank
  • HASH_SALT: Zufällige Zeichenkette zur Hassung von Benutzer-IPs
  • DISABLE_TELEMETRY: Umami sendet keine Telemetrie-Daten
  • CORS_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>
  );
}
Parameter:
  • 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

  1. Keine Cookies: Umami nutzt keine Cookies – daher kein Cookie-Banner nötig
  2. Anonymisierte IPs: Nur die letzte Ziffer der IP wird gespeichert (z.B. 192.168.1.x)
  3. Keine Benutzer-Tracking: Benutzer können nicht über Sessions identifiziert werden
  4. Keine 3rd-Party-Daten: Daten verlassen unseren Server nicht
  5. Keine Profilbildung: Keine Data-Broker oder Retargeting
DSGVO-Compliance:
  • ✅ 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

  1. Asynchrones Laden: async Attribut im Script-Tag
  2. Script Defer: defer kann zusätzlich verwendet werden
  3. Server-Side Events: Optional möglich, aber nicht nötig
Analyse: Umami-Script (2,7 KB gzipped) hat minimale Auswirkung. Asynchrones Laden verhindert Blockierung. LCP (Largest Contentful Paint) bleibt unverändert.

Sicherheit

Authentifizierung

Das Umami-Dashboard ist mit Standard-Benutzern geschützt:

Admin-Benutzer: admin@matzka.cloud
Passwort: [aus .env]
Best Practice: Authentik-SSO könnte integriert werden für zusätzliche Sicherheit.

Netzwerk-Sicherheit

  • HTTPS Only: Alle Verbindungen via TLS verschlüsselt
  • CORS: Nur matzka.cloud erlaubt (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_data Volume
  • Retention: 30 Tage (wie alle anderen Services)

Migration von Google Analytics

Schritt-für-Schritt Anleitung

  1. Umami einrichten
    docker-compose up -d postgres-umami umami
  2. Website registrieren
    Dashboard: https://analytics.matzka.cloud
    Admin-Login → "Add Website" → Domain hinzufügen → Website-ID kopieren
  3. Script-Tag einbinden
    <script
      async
      src="https://analytics.matzka.cloud/script.js"
      data-website-id="YOUR_WEBSITE_ID"
    ></script>
  4. Altes Google Analytics entfernen
    <!-- Alten gtag.js Script entfernen -->
    <!-- <script async src="https://www.googletagmanager.com/gtag/js?id=GA_ID"></script> -->
  5. 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

Symptom: Analytics zeigt 0 Seitenaufrufe
  1. Script-ID in HTML überprüfen: <script data-website-id="...">
  2. Browser-Konsole auf Fehler prüfen: F12 → Console → Errors
  3. Network-Tab prüfen: Rufen nach analytics.matzka.cloud/collect?
  4. CORS überprüfen:
    curl -H "Origin: https://matzka.cloud" \
      -H "Access-Control-Request-Method: POST" \
      https://analytics.matzka.cloud/
  5. Umami-Logs: docker logs umami | tail -50

Problem: Extrem hohe Page-View-Zahlen

Symptom: Dashboard zeigt unrealistisch hohe 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

Mit Umami haben wir ein Analytics-System implementiert, das:
  • ✅ 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