Skip to content

Runbook: Störungen ​

Was ein Alert bedeutet, wie man ihn prüft und behebt. Jeder Alert aus deploy/monitoring/server/prometheus/rules/pollyou.yml hat hier einen Abschnitt; Mail und Chat-Nachricht verlinken direkt dorthin (#<alertname>). Aufbau des Monitorings: Monitoring und Statusseite, Betrieb allgemein: Deployment.

Beispiele verwenden die Staging-Namen von CapRover (srv-captain--pollyou-staging-…); für Produktion staging durch production ersetzen.

Ablauf bei einer Störung ​

  1. Bestätigen: Im Chat-Thread des Alerts kurz „übernehme“ schreiben, damit nicht zwei Leute gleichzeitig eingreifen.
  2. Ausmaß prüfen: Statusseite, Grafana „PollYou – Betrieb“, Sentry (neue Fehler seit dem Alert), CapRover → Apps (Container neu gestartet?).
  3. Statusseite pflegen: Sind Kunden betroffen (jeder critical-Alert ausser reinen Infrastruktur-Warnungen), in Uptime Kuma unter Statusseite → Bearbeiten → Vorfall erstellen einen kurzen Hinweis veröffentlichen („Wir untersuchen Störungen bei …“). Bei geplanten Arbeiten vorher ein Wartungsfenster anlegen, dann zeigt die Seite „Wartung“ statt „Störung“ und monitor_status ist 3 (kein Alert).
  4. Beheben nach den Abschnitten unten. Änderungen (Neustart, Skalierung, Rollback) im Thread notieren.
  5. Abschließen: Entwarnung abwarten (Mail/Chat „[BEHOBEN]“), Vorfall auf der Statusseite auflösen, bei critical eine kurze Nachbetrachtung (Ursache, Dauer, Maßnahmen) im Wiki.

Eskalation ​

StufeWerWann
1Bereitschaft (Alert-Mailverteiler/Chat)sofort; critical innerhalb von 15 Minuten bestätigen, warning am selben Arbeitstag
2Technische Leitungcritical nach 30 Minuten nicht behoben, Datenverlust möglich, Sicherheitsvorfall
3Hosting-Anbieter (Support-Ticket)Server/Netz/Platte des Anbieters defekt, Server nicht erreichbar
–Kundenkommunikation (Support)Ausfall > 15 Minuten oder Datenverlust: Statusseite + ggf. Mail an betroffene Kunden

Datenschutzvorfälle (z. B. Daten einer Organisation für eine andere sichtbar) sind immer Stufe 2 und unterliegen der 72-Stunden-Meldepflicht (Art. 33 DSGVO).

Häufige Befehle ​

bash
# Container einer App (CapRover/Swarm)
docker ps --filter name=srv-captain--pollyou-staging-api
docker service logs --tail 200 srv-captain--pollyou-staging-api
docker service ps srv-captain--pollyou-staging-worker          # Neustarts, Fehler beim Start

# Konsole: Wartungsbefehle im Worker-Container (Rolle pollyou_worker, System-Scope)
docker exec -it $(docker ps -qf name=srv-captain--pollyou-staging-worker | head -n1) sh
php bin/console app:monitoring:collect                         # Betriebsmetriken jetzt
php bin/console messenger:stats                                # Queue-Längen
php bin/console messenger:failed:show                          # gescheiterte Nachrichten
php bin/console app:database:check-role --expect=worker        # Row-Level Security der Rolle

# Redis (Queue-Instanz)
redis-cli -h srv-captain--pollyou-staging-redis -a … XLEN messages
redis-cli … XINFO GROUPS messages
redis-cli … XINFO CONSUMERS messages_priority symfony           # ein Consumer je Worker-Container, idle in ms

Verfügbarkeit ​

PollYouApiDown – API nicht erreichbar ​

Bedeutung: Kein API-Container beantwortet die Abfrage des Agenten. Abstimmen, Direktlinks, Dashboard und API v1 fallen aus; Kuma meldet zusätzlich PollYouEndpointDown[API].

Prüfen:

  • CapRover → pollyou-…-api: läuft der Container, startet er in Schleife? docker service ps srv-captain--pollyou-staging-api --no-trunc zeigt den Fehler des letzten Starts.
  • Logs (docker service logs): Der Entrypoint bricht mit klarer Meldung ab bei
    • fehlenden Variablen oder Platzhaltern (missing required environment variables, development placeholder),
    • nicht erreichbarer Datenbank (database not reachable after 60s) → PollYouPostgresDown,
    • fehlgeschlagener Migration (--all-or-nothing: nichts wurde geändert) → Migration korrigieren oder Rollback,
    • falscher Datenbankrolle: app:database:check-role --strict meldet, dass DATABASE_URL die Row-Level Security umgeht (Schema-Eigentümer oder BYPASSRLS eingetragen). Die API muss sich als pollyou_app anmelden (Datenbankrollen).
  • Healthcheck: curl -s https://api.…/health liefert {"status":"degraded","checks":{"database":"unavailable"}} mit 503, wenn nur die Datenbank fehlt.

Beheben: Ursache aus dem Log beseitigen. Bei einem fehlerhaften Deployment die vorige Version ausrollen (CapRover → Deployment → Version History). Hängt der Container ohne Fehlermeldung (Healthcheck schlägt fehl, Swarm startet neu), Speicher prüfen (PollYouMemoryLow) und FRANKENPHP_WORKER_COUNT (ca. 50 MB je Worker).

PollYouApiInstanceDown – ein API-Container antwortet nicht ​

Bedeutung: Bei mehreren Instanzen ist einer ausgefallen oder hängt, die anderen tragen die Last.

Prüfen/Beheben: docker service ps srv-captain--pollyou-staging-api; den betroffenen Container (instance-Label = IP) neu starten lassen (docker rm -f <id>, Swarm ersetzt ihn). Tritt es wiederholt auf: Logs des Containers vor dem Ausfall, Speicherverbrauch.

PollYouEndpointDown – von außen nicht erreichbar ​

Bedeutung: Uptime Kuma erreicht eine öffentliche URL nicht (Label monitor_name); die Statusseite zeigt die Störung bereits.

Prüfen: Gibt es parallel Alerts vom Agenten? Wenn nicht, liegt das Problem vor den Containern:

  • TLS/DNS/Routing: curl -v https://api.…/health von einem anderen Netz aus. Zertifikat abgelaufen? CapRover-nginx (captain-nginx) läuft? DNS-Record geändert?
  • API → PollYouApiDown. Dashboard: pollyou-…-dashboard läuft? (statische Dateien, /healthz). Einbettungen (CDN): pollyou-…-embed, /v1/embed.js → 200? Fällt das CDN aus, laden eingebettete Umfragen auf Kundenseiten nicht; die API ist dann unschuldig.
  • Umfrage-Direktlink: Liefert /s/<publicId> 404, wurde die Beispielumfrage geschlossen/gelöscht → wieder veröffentlichen bzw. CHECK_DIRECT_LINK_URL anpassen und kuma-provision erneut ausführen. 5xx → Sentry.
  • Kuma selbst: Fallen alle Monitore gleichzeitig aus, ist eher das Netz des Monitoring-Servers gestört (Gegenprobe von einem anderen Netz).

PollYouMercureDown – Live-Ergebnisse nicht erreichbar ​

Bedeutung: Der Mercure-Hub (rt.…/healthz) antwortet nicht. Live-Ergebnisse in Embeds und das Live-Dashboard aktualisieren sich nicht; Abstimmen, Auswertungen und Exporte funktionieren weiter (Veröffentlichungen an Mercure schlagen fehl und werden geloggt, blockieren aber nichts Wesentliches).

Prüfen/Beheben: CapRover → pollyou-…-rt neu starten. Mercure läuft mit transport local: Updates liegen nur im Speicher, ein Neustart verliert nichts, was Clients bräuchten. Sie holen nach dem Wiederverbinden den aktuellen Stand neu (Deployment). Nicht auf den bolt-Transport umstellen: der schreibt jedes Update mit fsync und blockiert unter Last die Worker. Nach dem Neustart prüfen, dass MERCURE_PUBLISHER_JWT_KEY gleich MERCURE_JWT_SECRET der API ist (sonst 401 beim Veröffentlichen, sichtbar in den Worker-Logs).

PollYouMonitoringAgentSilent – keine Metriken vom App-Server ​

Bedeutung: Seit 3 Minuten kommt nichts vom Agenten. Entweder ist der App-Server weg (dann melden auch Kumas Monitore Störungen), oder nur das Monitoring ist blind.

Prüfen/Beheben:

  • Kuma grün? Dann läuft die App, nur der Agent nicht: auf dem App-Server cd deploy/monitoring/agent && docker compose ps, docker compose logs prometheus-agent (Remote-Write-Fehler 401 → Basic-Auth-Passwort; Verbindungsfehler → DNS/Firewall des Monitoring-Servers, Caddy auf dem Monitoring-Server läuft?).
  • Der Agent puffert bis zu einige Stunden im WAL und schickt nach, sobald der Server wieder erreichbar ist.
  • Kuma rot → App-Server prüfen (Anbieter-Konsole), Eskalationsstufe 3.

PollYouGotenbergDown – PDF-Dienst nicht erreichbar ​

Bedeutung: Gotenberg antwortet nicht. PDF-Berichte und geplante Berichte mit PDF-Anhang schlagen fehl (die Nutzer sehen eine Fehlermeldung bzw. der Bericht wird ohne PDF zugestellt); CSV/XLSX/SPSS funktionieren.

Prüfen/Beheben: CapRover → pollyou-…-gotenberg neu starten. Speicher (Chromium braucht 300–500 MB; OOM-Kills in docker service ps). Gotenberg ist zustandslos, ein Neustart ist gefahrlos. Der Worker erreicht es unter GOTENBERG_URL (app:…-Befehle zeigen beim PDF-Export die Fehlermeldung).

PollYouExporterDown – Exporter liefert nichts ​

Bedeutung: Ein Exporter des Agenten (PostgreSQL, Redis, Node) liefert keine Daten; die zugehörigen Alerts sind blind.

Prüfen/Beheben: docker compose -f deploy/monitoring/agent/docker-compose.yml logs <exporter>. Häufig: geändertes Passwort (Redis/pollyou_monitor), App-Name geändert. Fällt postgres aus, weil die Datenbank selbst weg ist, kommt zusätzlich PollYouPostgresDown.

HTTP ​

PollYouHttp5xxRate – hohe Fehlerquote ​

Bedeutung: Über 2 % der Requests enden seit 5 Minuten mit 5xx.

Prüfen:

  • Grafana: welche Routenklasse (collect, dashboard, …)? Seit dem letzten Deployment?
  • Sentry: neue Ausnahmen, Release-Zuordnung.
  • Typische Ursachen: Datenbank am Limit (PollYouDbConnectionsHigh), Redis nicht erreichbar (Rate-Limiter und Cache werfen), Migration nicht ausgeführt (doctrine:migrations:up-to-date im API-Container), Row-Level Security: Fehlermeldungen new row violates row-level security policy oder leere Ergebnisse nach einem Deployment deuten auf eine falsche Rolle oder einen Codepfad ohne Organisation hin. Niemals als Abhilfe der API BYPASSRLS geben oder sie als Schema-Eigentümer anmelden; stattdessen Rollback und Fehler beheben.
  • Kunden-Domains: 5xx nur bei Requests über den TLS-Edge (X-PollYou-Edge-Secret falsch → 403, nicht 5xx; Edge nicht erreichbar → 502 am Edge, nicht in diesen Metriken).

Beheben: Bei Zusammenhang mit einem Deployment: Rollback. Sonst Ursache nach Sentry beheben.

PollYouCollectLatencyHigh – Embeds/Direktlinks langsam ​

Bedeutung: p95 der Collector-API oder der öffentlichen Seiten > 500 ms. Teilnehmende warten, Embeds wirken träge.

Prüfen: Grafana: FrankenPHP-Auslastung (PollYouPhpWorkersSaturated), DB-Verbindungen, CPU des Hosts. PostgreSQL-Log: Sperren > 1 s, Abfragen > 1 s, checkpoints are occurring too frequently. Lastspitze einer einzelnen Umfrage? (Anomalie-Erkennung im Log.)

Beheben: API-Instanzen erhöhen (CapRover → Instanzen) oder FRANKENPHP_WORKER_COUNT anheben (RAM!). Bei Sperren: Rollups und Collector konkurrieren um dieselben Zeilen, siehe docs/guide/security-testing.md (Lasttest-Ergebnisse) und COLLECT_ASYNC_COMMIT.

PollYouApiLatencyHigh – Dashboard/API v1 langsam ​

Bedeutung: p95 von Dashboard, API v1 oder Login > 2 s.

Prüfen/Beheben: Wie oben. Zusätzlich: Analytics-Abfragen ohne Rollup (Zeitzonen mit halben Stunden, sehr lange Zeiträume) sind teuer; der Analytics-Cache liegt im Cache-Redis. Fällt der aus, rechnet jede Ansicht neu. Login: Argon2 kostet bewusst ~100 ms je Versuch; viele Logins (Angriff?) → Rate-Limiter-Logs.

PollYouPhpWorkersSaturated – PHP-Worker ausgelastet ​

Bedeutung: ≥ 90 % der FrankenPHP-Worker eines Containers sind belegt, neue Requests warten.

Beheben: API-Instanzen erhöhen oder FRANKENPHP_WORKER_COUNT (ca. 50 MB je Worker; DB-Verbindungen: jeder Worker hält eine). Lange Requests (Exporte bis 1000 Zeilen laufen synchron, PDF-Download) im Log suchen.

Queues und Hintergrundverarbeitung ​

Die Messenger-Queue liegt in der Queue-Redis-Instanz (persistent, AOF, noeviction), getrennt vom Cache-Redis (Rate-Limiter, Captcha, Live-Zähler, Analytics-Cache, Betriebsmetriken; flüchtig, LRU). Worker lesen async_priority (Mails, Webhooks, Benachrichtigungen) vor async (Rollups, Live-Ergebnisse, Exporte, KI-Analysen).

PollYouNoWorker – kein Worker aktiv ​

Bedeutung: Kein Worker hat seit 2 Minuten die Queue gelesen. Mails (Registrierung, Passwort), Webhooks, Rollups (Auswertungen), Live-Ergebnisse und Exporte stehen. Abstimmen funktioniert, die Nachrichten sammeln sich in Redis.

Prüfen:

  • CapRover → pollyou-…-worker: Instanzen > 0? docker service ps zeigt Neustarts (Exit-Code 137 = OOM-Kill → WORKER_MEMORY_LIMIT/Container-Speicher).
  • Start scheitert an app:database:check-role --expect=worker --strict: Der Worker muss sich als pollyou_worker anmelden (nicht pollyou_app, nicht Schema-Eigentümer).
  • XINFO CONSUMERS messages_priority symfony: ein Eintrag je Container, idle klein = aktiv.

Beheben: Worker neu starten/skalieren. Der Rückstand wird danach automatisch abgearbeitet; Nachrichten eines abgestürzten Workers übernimmt ein anderer nach redeliver_timeout (300 s).

PollYouSchedulerDown – Scheduler läuft nicht ​

Bedeutung: Der Scheduler hat seit über 3 Minuten keinen Snapshot geschrieben. Ohne ihn: keine Webhook-Wiederholungen, keine geplanten Berichte, keine Alert-Regeln der Kunden, keine Umfrage-Zeitpläne (Start/Ende), kein nächtlicher Rollup-Abgleich, keine Partitionen für den nächsten Monat, keine Aufbewahrungsfristen. Die Betriebsmetriken (Rollup-Verzug, Jobs, Webhooks) frieren ein.

Prüfen:

  • CapRover → pollyou-…-scheduler: genau 1 Instanz. Mehr als eine würde jede Aufgabe doppelt ausführen (doppelte Berichte); 0 = Ausfall.
  • Logs: Datenbankrolle muss pollyou_worker sein (geplante Aufgaben arbeiten organisationsübergreifend im System-Scope; mit pollyou_app sehen sie nichts und der Snapshot scheitert mit einer Exception).
  • Läuft er, aber der Snapshot fehlt: Cache-Redis (REDIS_URL) erreichbar? php bin/console app:monitoring:collect --store im Scheduler-Container zeigt die Fehlermeldung.

Beheben: Scheduler neu starten (Instanzen 1). Verpasste Läufe holt er nach (zustandsbehafteter Zeitplan, jeweils der letzte verpasste Lauf).

PollYouSchedulerSnapshotMissing – kein Snapshot ​

Bedeutung: Seit über einer Stunde (oder nach einem Neustart des Cache-Redis noch nie) liegt kein Snapshot vor. Vorgehen wie PollYouSchedulerDown. Direkt nach einem Neustart des Cache-Redis verschwindet der Alert nach dem nächsten Lauf (30 s).

PollYouMessengerRedisDown – Queue-Redis nicht erreichbar ​

Bedeutung: Die API erreicht den Queue-Redis (MESSENGER_TRANSPORT_DSN) nicht. Abstimmungen werden in PostgreSQL gespeichert, aber das Einreihen der Folgenachrichten schlägt fehl (Fehler in Sentry). Die nächtliche Rollup-Neuberechnung holt verlorene Rollups nach; Mails und Webhooks können verloren gehen.

Beheben: → PollYouRedisDown (redis="queue"). Nicht auf den Cache-Redis umstellen: Er verwirft bei Speicherdruck Daten (LRU) und hat kein AOF.

PollYouQueueBacklog – Queue im Verzug ​

Bedeutung: Die älteste Nachricht in async wartet seit über 5 Minuten. Auswertungen und Live-Ergebnisse hinken hinterher.

Prüfen: Grafana: Zulauf (Requests/s collect) vs. Abarbeitung; aktive Worker; einzelne lange Nachrichten (Export, KI-Analyse belegen einen Worker minutenlang). Hohe pending-Zahl bei wenig messages = Worker hängen an etwas (Datenbank-Sperren, Gotenberg, Claude-API).

Beheben: Worker-Instanzen erhöhen (jeder Container hat seinen Consumer-Namen, Skalieren ist gefahrlos). Bei Datenbank-Sperren → PostgreSQL-Log.

PollYouQueueBacklogCritical – Queue stark im Verzug ​

Wie PollYouQueueBacklog, aber über 15 Minuten. Sofort Worker skalieren. Liegt der Queue-Redis zudem nahe an maxmemory → PollYouRedisQueueMemoryHigh.

PollYouPriorityQueueDelayed – Mails/Webhooks verzögert ​

Bedeutung: Nachrichten in async_priority warten über 60 s. Registrierungs-/Passwortmails kommen spät, Webhooks verzögern sich.

Prüfen/Beheben: Hängen alle Worker in langen async-Nachrichten (Exporte)? Ein Worker nimmt async_priority erst nach der laufenden Nachricht wieder auf → mehr Worker. SMTP langsam/nicht erreichbar (Worker-Log Connection could not be established)? Webhook-Ziele, die bis zum Timeout hängen?

PollYouQueueGrowing – Queue wächst ​

Bedeutung: Seit 15 Minuten kommen mehr Nachrichten hinein als hinaus (> 1000 wartend). Frühwarnung vor PollYouQueueBacklog.

Beheben: Worker skalieren, Ursache des Zulaufs prüfen (Lastspitze, Angriff auf den Collector → Rate-Limiter/Anomalie-Erkennung).

PollYouRollupLag – Rollup-Verzug ​

Bedeutung: Ereignisse (Impressionen, Seitenaufrufe, Abschlüsse im Trichter) sind seit über 10 Minuten nicht gezählt. Auswertungen zeigen zu wenig.

Prüfen: Gleichzeitig PollYouQueueBacklog? Dann ist es dieselbe Ursache. Sonst wurde eine SurveyEventsPending-Nachricht verloren (Redis-Neustart ohne AOF, gelöschte Nachricht): Die Ereignisse bleiben liegen, bis die nächste Ereignis-Anfrage der Umfrage oder der nächtliche Abgleich sie zählt.

Beheben: Sofort nachzählen im Worker-Container: php bin/console app:analytics:rebuild --from=yesterday --to=today (idempotent, sperrt pro Umfrage).

PollYouFailedMessages – Nachrichten im Failure-Transport ​

Bedeutung: Nachrichten sind nach allen Wiederholungen gescheitert (Tabelle messenger_messages, Queue failed).

Prüfen/Beheben: php bin/console messenger:failed:show (Worker-Container), Ursache in Sentry. Nach der Behebung messenger:failed:retry; dauerhaft unzustellbare mit messenger:failed:remove <id>. Rollup-Nachrichten muss man nicht zwingend wiederholen, der nächtliche Abgleich korrigiert die Zahlen.

PollYouWebhooksOverdue – Webhooks überfällig ​

Bedeutung: Fällige Webhook-Zustellungen liegen seit über 5 Minuten unversucht. Normalerweise holt der Scheduler sie jede Minute ab (DispatchDueWebhooks).

Prüfen/Beheben: Scheduler und Worker laufen? (PollYouSchedulerDown, PollYouNoWorker) Priority-Queue im Verzug? Danach arbeiten sie die Zustellungen von selbst ab.

PollYouWebhookFailures – viele gescheiterte Webhooks ​

Bedeutung: > 20 Zustellungen in der letzten Stunde endgültig gescheitert.

Prüfen: Meist ein einzelner Kundenendpunkt (Dashboard → Webhooks → Zustellungen bzw. webhook_delivery, gruppiert nach endpoint_id). Betrifft es alle Endpunkte: ausgehendes Netz/DNS des Workers, SSRF-Schutz (WEBHOOK_ALLOWED_PRIVATE_NETWORKS) nach Netzänderungen. Kunden selbst sehen den Fehler im Zustellprotokoll; ggf. Support informieren.

PollYouJobStuck – Export/KI-Analyse hängt ​

Bedeutung: Ein Export oder eine KI-Analyse läuft seit über 30 Minuten (kind).

Prüfen/Beheben: Worker-Logs; Export: Gotenberg (PDF) erreichbar, Platz in /var/lib/pollyou/exports? KI: Claude-API-Fehler/Timeouts. Abgestürzte Exporte markiert app:analytics:purge-exports (stündlich) als gescheitert; Nutzer können neu anfordern.

PollYouJobsQueued – Jobs starten nicht ​

Bedeutung: Ein angeforderter Export/eine KI-Analyse wartet seit über 15 Minuten auf den Start. Fast immer PollYouQueueBacklog oder PollYouNoWorker.

PollYouNotificationFailures – Berichte/Alert-Mails scheitern ​

Bedeutung: Geplante Berichte oder Alert-Benachrichtigungen der Kunden wurden nicht zugestellt (notification_delivery.status = failed, Fehlertext in error).

Prüfen/Beheben: SMTP (MAILER_DSN) erreichbar, Kontingent beim Mail-Anbieter? Gotenberg für PDF-Anhänge? Slack-Kanäle der Kunden (abgelaufene Webhooks) sind Kundenprobleme.

Datenhaltung ​

PollYouPostgresDown – Datenbank nicht erreichbar ​

Bedeutung: PostgreSQL ist nicht erreichbar. Alles außer statischen Dateien fällt aus.

Prüfen: CapRover → pollyou-…-db, docker service logs. Platte voll (PollYouDiskSpaceCritical)? Recovery nach Absturz (Log database system was interrupted; last known up at …, dauert je nach WAL-Menge Minuten, nicht abbrechen)?

Beheben: Platz schaffen, Container neu starten. Daten beschädigt → Wiederherstellung im Ernstfall. Nach dem Restore: Rollen pollyou_app/pollyou_worker sind clusterweit und kommen mit deploy/postgres/10-pollyou-roles.sh bzw. der Migration zurück. Prüfen mit app:database:check-role in API und Worker.

PollYouDbConnectionsHigh – viele Datenbankverbindungen ​

Bedeutung: > 80 % von max_connections. Darüber lehnt PostgreSQL neue Verbindungen ab (5xx).

Prüfen: pollyou_db_connections{role} (Grafana): Jeder FrankenPHP-Worker × API-Container hält eine Verbindung (Rolle pollyou_app), jeder Worker-Container und der Scheduler eine (pollyou_worker). idle in transaction in pg_stat_activity deutet auf hängende Requests.

Beheben: Weniger FRANKENPHP_WORKER_COUNT bei mehr Instanzen ist nicht gratis: Summe der Worker beachten. max_connections erhöhen (Neustart der DB, RAM je Verbindung) oder einen Pooler (PgBouncer, Transaktionsmodus) vorschalten. Achtung: Row-Level Security setzt die Einstellungen pro Transaktion (SET LOCAL), das verträgt Transaktions-Pooling.

PollYouRedisDown – Redis nicht erreichbar ​

Bedeutung: Eine Redis-Instanz antwortet nicht (Label redis):

  • queue: keine Hintergrundverarbeitung (siehe PollYouMessengerRedisDown).
  • cache: Rate-Limiter, Captcha-Replay-Schutz, Live-Zähler, Analytics-Cache und Betriebsmetriken fallen aus; Registrierung und Login schlagen fehl (Rate-Limiter), Abstimmen ist eingeschränkt.

Beheben: Container neu starten. Die Queue-Instanz lädt beim Start das AOF (bei großer Queue dauert das), die Cache-Instanz startet leer bzw. aus dem letzten RDB-Snapshot. Beide Instanzen sind absichtlich getrennt und verschieden konfiguriert (deploy/redis/redis-queue.conf, redis-cache.conf): nie zusammenlegen, nie die Queue mit Eviction betreiben.

PollYouRedisQueueMemoryHigh – Queue-Redis fast voll ​

Bedeutung: Die Queue-Instanz liegt über 80 % von maxmemory. Sie verwirft nichts (noeviction); bei 100 % schlägt jedes Einreihen fehl.

Beheben: Rückstand abbauen (Worker skalieren, siehe PollYouQueueBacklog). Kurzfristig maxmemory erhöhen (redis-cli CONFIG SET maxmemory 4gb, dauerhaft in deploy/redis/redis-queue.conf), sofern der Host Speicher hat. Niemals Streams von Hand löschen.

Host ​

PollYouDiskSpaceLow – Platte wird voll ​

Bedeutung: < 15 % frei auf einem Dateisystem.

Prüfen: df -h, docker system df. Große Posten: alte Docker-Images (jeder Deploy), PostgreSQL-WAL (Replikations-Slots? Backups hängen?), Redis-AOF, Exporte in /var/lib/pollyou/exports (7 Tage).

Beheben: docker image prune -a --filter until=168h (CapRover behält ohnehin die letzten Versionen), alte Backups lokal entfernen (Retention BACKUP_RETENTION_DAYS), ggf. Volume vergrößern.

PollYouDiskSpaceCritical – Platte fast voll ​

Wie PollYouDiskSpaceLow, aber < 5 %: sofort handeln. Läuft die Platte voll, stoppen PostgreSQL (kann nicht mehr schreiben, auch kein Checkpoint) und der Queue-Redis (AOF).

PollYouDiskFillsWithin24h – Platte in 24 h voll ​

Hochrechnung der letzten 6 Stunden. Ursache des Wachstums suchen (siehe oben), oft ein hängendes Backup-/WAL-Archiv oder ein Export-Sturm.

PollYouMemoryLow – Arbeitsspeicher knapp ​

Bedeutung: < 10 % RAM verfügbar. Der OOM-Killer beendet bald Container.

Prüfen/Beheben: docker stats --no-stream: Ausreißer? Gotenberg (Chromium), Worker mit großen Exporten (WORKER_MEMORY_LIMIT begrenzt PHP, nicht den Container), FrankenPHP-Worker × Instanzen. Instanzen verringern oder Server vergrößern.

Besondere Komponenten ​

  • Row-Level Security: Drei Rollen. Der Schema-Eigentümer pollyou macht nur Migrationen und Backups. pollyou_app ist die API, nur ihre Organisation. pollyou_worker sind Worker, Scheduler und Konsole, organisationsübergreifend nur im System-Scope. Fehlerbilder: falsche Rolle → Start scheitert (DATABASE_ROLE_STRICT=1) oder leere/fehlende Daten; Abhilfe ist immer die richtige Rolle, nie BYPASSRLS. Details: backend/src/Tenancy/README.md.
  • Scheduler: genau eine Instanz, Rolle pollyou_worker. Zwei Instanzen → doppelte Berichte, doppelte Webhook-Wiederholungen.
  • Redis-Aufteilung: Queue (persistent, noeviction) und Cache (flüchtig, LRU) sind getrennte Instanzen; die Betriebsmetriken liegen im Cache.
  • Mercure: transport local, kein Verlauf; ein Neustart ist gefahrlos.
  • Gotenberg: zustandslos, nur der Worker ruft es auf; ohne Gotenberg fehlen nur PDFs.
  • TLS-Edge für Kunden-Domains: eigener Caddy mit On-Demand-TLS (deploy/edge). Fällt er aus, sind nur Umfragen auf Kunden-Domains betroffen. Prüfen: curl -v https://<Test-Kunden-Domain>/s/<publicId>, Edge-Logs (ask-Abfragen an /internal/domains/allowed müssen 200 liefern: 403 = CUSTOM_DOMAIN_EDGE_SECRET stimmt nicht überein; 429 = mehr als 20 Zertifikatsanfragen pro Stunde für einen Host). Let's-Encrypt-Limits nicht durch wiederholte Neustarts mit leerem /data reißen. Details: Eigene Domains, Deployment.