Plausible Analytics ist eine datenschutzfreundliche Alternative zu Google Analytics — kein Cookie-Banner nötig, DSGVO-konform, und man kann es selbst hosten. Version 3 bringt ein komplett neues Frontend (Phoenix LiveView), was einige Dinge ändert, die in keiner Dokumentation stehen.

Hier sind die vier Probleme, auf die ich beim Setup gestoßen bin.

TL;DR

ProblemSymptomFix
ClickHouse 24.12: User-Settings verbotenContainer startet nichtUser-level Settings aus XML entfernen
ClickHouse Default User: kein NetzwerkzugangCLICKHOUSE_DATABASE_URL schlägt fehlCLICKHOUSE_PASSWORD env var setzen
docker compose restart liest env_file nicht neuEnv-Änderungen haben keine Wirkungdocker compose up -d statt restart
Phoenix LiveView braucht WebSocketLogin-Button reagiert nichtlocation /live/websocket in nginx

Fallstrick 1: ClickHouse 24.12 — User-level Settings verboten

Die offizielle Plausible-Dokumentation empfiehlt, ClickHouse mit einer low-resources.xml auf kleineren Servern zu betreiben. Ältere Versionen dieser Config enthielten Settings wie max_bytes_before_external_group_by oder max_bytes_before_external_sort. In ClickHouse 24.12 sind diese Settings auf User-Ebene verboten.

Symptom: Der ClickHouse-Container startet nicht. In den Logs:

Exception: Setting max_bytes_before_external_group_by is not allowed in user profiles.

Fix: Diese Settings aus der XML entfernen. Eine funktionierende low-resources.xml für ClickHouse 24.12 sieht so aus:

<clickhouse>
    <max_concurrent_queries>10</max_concurrent_queries>
    <max_server_memory_usage_to_ram_ratio>0.4</max_server_memory_usage_to_ram_ratio>
    <mark_cache_size>536870912</mark_cache_size>
</clickhouse>

Fallstrick 2: ClickHouse Default User hat keinen Netzwerkzugang

Nach dem Fix aus Fallstrick 1 startet ClickHouse — aber Plausible kann sich trotzdem nicht verbinden. Der Default User in ClickHouse 24.12 hat ohne explizites Passwort keinen Netzwerkzugang.

Symptom: Plausible startet, aber alle Event-Anfragen schlagen fehl. In den Logs:

[error] Clickhouse.Error: Code: 516. DB::Exception: default: Authentication failed

Fix: Die CLICKHOUSE_PASSWORD Umgebungsvariable in der compose.yml setzen:

plausible_events_db:
  image: clickhouse/clickhouse-server:24.12-alpine
  environment:
    - CLICKHOUSE_PASSWORD=dein-sicheres-passwort

Und entsprechend in der Plausible-Konfiguration:

CLICKHOUSE_DATABASE_URL=http://default:dein-sicheres-passwort@plausible_events_db:8123/plausible_events

Fallstrick 3: docker compose restart liest env_file nicht neu ein

Wenn man etwas in der .env-Datei oder plausible-conf.env ändert und dann docker compose restart ausführt, hat das keine Wirkung. Der Container wird neu gestartet, aber die Umgebungsvariablen kommen aus dem bestehenden Container-State.

Symptom: Änderungen an DISABLE_REGISTRATION, SECRET_KEY_BASE, Datenbank-URLs — nichts davon wirkt nach docker compose restart.

Das betrifft zum Beispiel das Henne-Ei-Problem beim ersten Setup: DISABLE_REGISTRATION=invite_only verhindert, dass man den ersten Account anlegen kann. Man ändert es auf false — aber restart liest die Änderung nicht ein.

Fix: docker compose up -d statt restart:

# FALSCH: Container wird neugestartet, aber env_file NICHT neu eingelesen
docker compose restart

# RICHTIG: Container wird recreated, env_file wird neu eingelesen
docker compose up -d

up -d erkennt Änderungen an compose.yml und env_file und recreated nur die betroffenen Container. restart macht das explizit nicht — das ist kein Bug, sondern by design.


Fallstrick 4: Phoenix LiveView braucht WebSocket in nginx

Plausible v3 wurde mit dem Elixir/Phoenix-Framework neu geschrieben und nutzt Phoenix LiveView für das interaktive Frontend. LiveView kommuniziert über WebSockets statt über normale HTTP-Requests.

Symptom: Das Plausible-Dashboard ist erreichbar, die Loginseite lädt — aber ein Klick auf “Login” oder “Create Account” passiert nichts. Kein HTTP-Fehler, kein Redirect, einfach nichts. Im Browser-DevTools sieht man einen WebSocket-Verbindungsversuch auf /live/websocket, der fehlschlägt.

Fix: In der nginx-Konfiguration muss /live/websocket explizit mit WebSocket-Upgrade-Headers proxied werden:

server {
    listen 443 ssl http2;
    server_name stats.example.com;

    # WebSocket für Phoenix LiveView
    location /live/websocket {
        proxy_pass http://plausible-backend:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
    }

    # Rest der Requests
    location / {
        proxy_pass http://plausible-backend:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Ohne den location /live/websocket-Block upgradet nginx die Verbindung nicht auf WebSocket, und alle Form-Submits in Plausible v3 schlagen stillschweigend fehl.


Verifikation

# 1. Alle Container laufen und sind healthy?
docker compose ps

# 2. Plausible erreichbar?
curl -s -o /dev/null -w "%{http_code}" https://stats.example.com
# Erwarteter Output: 200

# 3. Manuell einen Pageview senden (falls Adblocker das Script blockiert)
curl -s -o /dev/null -w "%{http_code}" \
  "https://stats.homelab-guide.de/api/event" \
  -H "Content-Type: application/json" \
  -d '{"name":"pageview","url":"https://example.com/","domain":"example.com"}'
# Erwarteter Output: 202

Fazit

Plausible v3 selbst zu hosten ist machbar, aber die Kombination aus ClickHouse 24.12 Breaking Changes und dem neuen Phoenix LiveView Frontend schafft ein paar Probleme, die in der Dokumentation (noch) nicht dokumentiert sind.

Der wichtigste Take-away: Immer docker compose up -d statt restart wenn man Umgebungsvariablen ändert, und immer WebSocket-Support in nginx prüfen wenn man LiveView-Apps proxied.