Coolify-Deployment-Fails – fünf Patterns aus echten Projekten
OOM-Kill, Disk-Full, Build-Cache-Drift, Permission-Mismatch, Nixpacks-Regression — fünf Coolify-Deployment-Patterns, die wir wiederholt sehen, mit Frühwarnsignalen.

Coolify-Instanzen laufen monatelang grün — bis sie das nicht mehr tun. Wenn der Kunde dann anruft, ist meistens nicht der Build kaputt, sondern das Monitoring. Das Web-Panel sagt „running", die App ist im Restart-Loop, und niemand hat es gemerkt, weil keiner den Browser-Tab offen hatte.
Wir betreiben seit etwa eineinhalb Jahren mehrere Coolify-Hosts für eigene Projekte und Kundenstacks. In dieser Zeit kommen ein paar Fehlermuster wiederholt vor, und sie werden im Coolify-Dashboard regelmäßig trügerisch grün angezeigt, bevor sie laut werden. Hier sind fünf davon — mit Symptom, Coolify-Sicht, was tatsächlich passiert, und wie früh man das praktisch sehen kann.
1. OOM-Kill mitten im Build
Symptom. Der Deploy startet, läuft die ersten Stages durch, hängt dann zwei Minuten auf „Building image" und bricht mit generischem „build failed" ab. Manchmal hängt der Spinner stundenlang.
Coolify-Sicht. Web-Panel zeigt einen unspezifischen Fehler oder Timeout. Der eigentliche Auslöser steht nur in dmesg auf dem Host: Out of memory: Killed process 4711 (node).
Was wirklich passiert. npm run build für ein modernes Next.js- oder Nuxt-Projekt braucht oft 1,5 bis 3 GB nur fürs Bundling. Auf einem 1- oder 2-GB-VPS reicht das nicht. Der Linux-OOM-Killer terminiert den Build, BuildKit gibt einen unklaren Exit-Code zurück, Coolify weiß nicht warum.
Wie früh sichtbar. Push-Notification auf „Deployment failed" innerhalb von Sekunden, alternativ ein Memory-Watch auf dem Host mit Alarm bei über 90 % während aktiver Builds.
Prävention. Aus unserer Sicht drei Optionen in dieser Reihenfolge: Multi-Stage-Dockerfile mit schlanker Build-Stage, Swap auf dem Host einrichten, oder den Build in eine CI auslagern und nur das fertige Image pullen. Das letzte Setup ist am stabilsten — Coolify wird zum Image-Deployer statt Image-Builder, und die Server-Größe wird ausschließlich von der Runtime bestimmt, nicht vom Build-Peak.
2. Disk-Full durch Docker-Build-Cache
Symptom. Monatelang läuft alles, dann failen plötzlich alle Deployments mit no space left on device. Auch der Restart bestehender Container hängt — neue Container-Layer können nicht geschrieben werden.
Coolify-Sicht. Deploy-Fail mit Disk-Fehler im Log. Was Coolify nicht zeigt: dass /var/lib/docker über Wochen langsam vollgelaufen ist und jetzt 95 % der Partition belegt.
Was wirklich passiert. Jeder Coolify-Build hinterlässt Build-Cache, dangling Images und alte Layer. Ohne Pruning füllt sich die Docker-Datenpartition vorhersehbar in zwei bis vier Wochen — bei aktiv entwickelten Projekten schneller. Die Coolify-UI zeigt davon nichts, weil sie auf Application-Ebene operiert, nicht auf Host-Ebene.
Wie früh sichtbar. Disk-Watcher auf den Host packen (Schwelle 15 % free als Warning, 5 % als Critical) — gibt mehrere Tage Vorwarnzeit, in denen Builds noch durchgehen. Deploir hat das als Server-Health-Check eingebaut und alarmiert genau auf diese Schwellen.
Prävention. Wöchentlicher Host-Cron mit docker system prune -af (ohne --volumes, sonst sind persistente Daten weg). Bei größeren Hosts zusätzlich docker builder prune und eine Image-Retention-Policy in der Registry.
3. Nixpacks-Detection-Drift
Symptom. Ein Build, der vorher unter einer Minute lief, dauert plötzlich 30 oder mehr Minuten. Keine Fehler, alles geht durch, aber der Deploy-Cycle ist unbenutzbar.
Coolify-Sicht. Im Build-Pack-Setting steht „Auto" oder „Nixpacks", obwohl im Repo ein Dockerfile liegt. Nichts blinkt rot, der Build läuft technisch erfolgreich.
Was wirklich passiert. Coolify-Auto-Detect priorisiert manchmal Nixpacks gegenüber dem vorhandenen Dockerfile — das passiert besonders nach Coolify-Updates oder wenn das Dockerfile nicht im Repo-Root liegt. Nixpacks baut funktional, ignoriert aber alle BuildKit-Cache-Mounts und Multi-Stage-Optimierungen, weil es selbst eine generische Buildpack-Pipeline aufzieht.
Wie früh sichtbar. Build-Dauer als Metrik mitloggen — sobald ein Job fünfmal so lange braucht wie der Median, ist etwas systemisch falsch. Ein simpler Cron, der Coolify-API-Build-Times in eine Zeitreihe schreibt, reicht aus.
Prävention. Build-Pack pro App explizit auf „Dockerfile" pinnen, nicht „Auto". Wir haben das nach einem 37-Minuten-Build statt der gewohnten 60 Sekunden zur internen Hard-Rule gemacht — Coolify-Auto-Detection ist bequem, aber nicht stabil genug für Produktiv-Stacks.
4. NEXT_PUBLIC_* erreicht den Client-Bundle nicht
Symptom. Du setzt einen neuen NEXT_PUBLIC_FEATURE_X in der Coolify-UI, der Deploy läuft grün durch, aber im Browser ist die Variable undefined und Features brechen lautlos im Client.
Coolify-Sicht. Alles grün. Build erfolgreich, Container läuft, Health-Check passt. Nichts deutet darauf hin, dass die env vars beim Build nicht eingebaut wurden.
Was wirklich passiert. NEXT_PUBLIC_* werden in Next.js zur Build-Zeit in den Client-Bundle inlined, nicht zur Laufzeit gelesen. Wenn Coolify den vorigen Build-Cache wiederverwendet, wird die Compile-Stage übersprungen — die alten Werte (oder undefined) bleiben im Bundle. Das ist kein Coolify-Bug, sondern wie BuildKit funktioniert. Ohne explizites Cache-Bust merkt der Build nicht, dass sich ein build-time-Wert geändert hat.
Wie früh sichtbar. Browser-Console oder ein Health-Check auf einer Seite, die die env-Var tatsächlich rendert. Server-seitig schwer zu sehen, weil der Container „läuft" — du brauchst echtes Client-Side-Monitoring.
Prävention. Beim Hinzufügen oder Ändern eines NEXT_PUBLIC_* einmalig „Force deploy (without cache)" in Coolify ticken. Konvention: jede neue public-env-Var in derselben PR mit einer Notiz im Deploy-Checklist erwähnen, sonst vergisst es jemand drei Releases später.
5. Persistent-Volume-Permission-Mismatch
Symptom. Container läuft (laut Coolify), aber jede zweite Anfrage failt mit Schreibfehlern. Logs zeigen EACCES: permission denied, open '/app-data/...'. App restartet im Loop oder wirft 500er.
Coolify-Sicht. Status grün — der Container ist gestartet und der Health-Check antwortet, weil der Pfad zur Health-Endpoint nicht aufs Volume schreibt.
Was wirklich passiert. Coolify legt persistente Volumes typisch root-owned an. Wenn das Container-Image als non-root-UID läuft (häufig bei node:alpine-Stacks mit explizitem USER nextjs), schlägt jeder Schreibversuch aufs Volume fehl. Der Container hängt nicht ab — er wirft Fehler nur dann, wenn echter Write-Traffic kommt.
Wie früh sichtbar. Restart-Loop-Detection (mehr als drei Restarts in zehn Minuten) ist der zuverlässige Frühindikator. Deploir gruppiert das pro Container und schickt einen Push nach dem dritten Restart. Manuell: docker logs --tail 50 direkt nach Deploy als Smoke-Check.
Prävention. Entweder den Container als root laufen lassen (gängig bei Coolify-Stacks mit Volume-Sharing), oder beim Anlegen des Volumes per Init-Container einmalig chowen. Die Entscheidung hängt vom Sicherheitsmodell ab — beides ist legitim, eine implizite UID-Annahme ohne explizite Setup-Doku ist es nicht.
Was diese fünf gemeinsam haben
In allen fünf Fällen gilt: Coolify-UI-Status ist nicht gleich Application-Health. Der Web-Spinner kann grün sein, während der OOM-Killer den Build wegnimmt, das Volume voll ist, der Bundle veraltete env vars enthält oder der Container im Restart-Loop hängt. Das Coolify-Dashboard ist exzellent für aktives Tunen — als alleiniger Monitoring-Layer reicht es nicht.
Drei Hebel schließen die Lücke. Erstens: Host-Level-Monitoring (RAM, Disk, OOM-Events) — Coolify operiert auf Application-Ebene und ist für Host-Anomalien blind. Zweitens: Push-Notifications für Container-Restarts und Deploy-Fails, die nicht auf einen offenen Browser-Tab angewiesen sind. Drittens: explizite Build-Hygiene — Build-Pack pinnen, Cache-Bust bei env-Änderungen, Volume-Permissions dokumentieren — statt Coolify-Auto-Detect blind zu vertrauen.
Was wir intern dafür einsetzen, ist Deploir: ein nativer Coolify-Client mit Push-Notifications auf Lock-Screen und Mac-Menüleiste, bewusst kein Datadog-Konkurrent. Drei der fünf hier beschriebenen Patterns landen damit innerhalb von Sekunden bis Minuten als Push, statt erst beim nächsten manuellen Tab-Refresh aufzufallen.
Loslegen
Deploir ist seit April 2026 im App Store für Mac und iOS kostenlos. Wer den konkreten Setup-Pfad sucht: das Push-Notification-How-to zeigt die Konfiguration in drei Minuten, inklusive Critical-Alerts und Per-Server-Stille-Stunden.
Für die unsichtbaren Patterns wie Build-Cache-Drift oder Permission-Mismatch gibt es kein Allheilmittel — sie verlangen Build-Hygiene und Doku. Aber sie werden zu lauten Patterns, sobald eine Deploy-Failed-Notification auf dem Lock-Screen liegt, statt im 50. ungeöffneten Browser-Tab. Wir bauen das Tooling, das wir selbst täglich brauchen, und teilen die Lehren, damit andere nicht dieselben drei Wochen verlieren.
Weitere Beiträge
Pressematerial — Bild + Plain-Text
Text des Beitrags
Plain-Text zum Mitnehmen – nur zur privaten Nutzung
Bilder im Beitrag
Alle Grafiken als ZIP – nur zur privaten Nutzung
Kommentare (1)
Diskutiere mit. Mit Apple-ID oder per E-Mail-Anmeldung.
Zum Kommentieren bitte anmelden
Habe Deploir mit meiner lokalen Coolify-Instanz getestet und bin absolut begeistert! Vorher hatte ich Coolify einfach als Chrome-App gespeichert, funktional, aber umständlich. Mit Deploir geht alles deutlich smoother, besonders dank des Menüs in der Topbar.
Newsletter
Mehr Artikel wie diesen per Mail
Monatliche Insights zu Webentwicklung, Apps, Shopware und KI. Kein Spam, jederzeit abmeldbar.
Du bekommst gleich eine Bestätigungsmail. Bitte klicke den Link darin, um deine Anmeldung abzuschließen. Kein Spam, Abmeldung jederzeit. Datenschutzerklärung