VPSSPark Blog
← Zurück zum Tagebuch

Server-Festplatte voll? Ein-Klick-Skript für gängige Cache-Verzeichnisse

Server-Notizen · 2026.07.23 · ~11 Min. Lesezeit

Häufig gesucht: Server Festplatte voll · Linux Speicher bereinigen · VPS Festplatte · Cache-Cleanup (Docker · journal · apt)

Server-Rack-Wartung—Linux-VPS-Speicherplatz und Ops-Cleanup
Disk-Alarme bedeuten meist angesammelte Logs, Container-Layer und Paket-Caches—erst diagnostizieren, dann per Skript statt panischem rm.

Um 3 Uhr morgens vibrierte das Diensttelefon: Monitoring meldete die /-Partition bei 98 % Belegung, MySQL konnte keine Binlogs schreiben, und CI-Deployments brachen mitten im docker pull mit no space left on device ab. Per SSH und df -h fanden wir auf Root gerade einmal 412 MB frei – kein Malware-Befall, sondern drei Monate unbeachtete Logs, Docker-Layer, apt-Cache und Journal, die langsam eine 40-GB-VPS-Platte auffraßen.

Dieses Szenario ist auf kleinen VPS-Instanzen allgegenwärtig: wenig Speicher, Container rund um die Uhr, ständige Image-Pulls und unerbittliches Logging. Manuelles rm -rf ist langsam und fehleranfällig; das zuverlässige Vorgehen heißt zuerst die größten Verbraucher finden, dann regenerierbare Verzeichnisse per Skript in einem Rutsch bereinigen. Dieser Artikel bündelt das One-Click-Cleanup-Skript, das wir in Produktion wiederholt eingesetzt haben – mit klaren Hinweisen, was sicher automatisiert werden kann und was eine zweite Prüfung braucht.

Voraussetzung: SSH-Zugang und sudo. Wenn gar keine Verbindung klappt (z. B. weil SSH-Keys nicht geschrieben werden können), zuerst unseren Leitfaden zu abgelehnten SSH-Verbindungen auf Linux-Servern nutzen, um volle Platte vs. Netzwerk/Firewall zu unterscheiden. Bevor Sie UFW-Regeln anfassen, zuerst Speicher freimachen – Dienste brauchen Platz für Logs, bevor wieder alles normal läuft.

5 Min.
Finden + sicheres Cleanup
8+
Typische Cache-Verzeichnisse
1 Skript
Copy-Paste-Cleanup

Volle Platte: Was bricht zuerst?

Ist das Root-Dateisystem voll, wirken Linux-Symptome oft zufällig: SSH geht noch, aber vim speichert nicht, apt install scheitert, Docker-Container starten nicht, Nginx liefert 500, während error.log nicht mehr wächst. MySQL und PostgreSQL gehen schreibgeschützt oder stürzen ab; systemd-Dienste starten in Schleifen neu, weil pid-Dateien oder Sockets nicht angelegt werden können. Cron-Jobs scheitern leise, wenn Logs nicht mehr beschrieben werden können.

Schritt eins ist immer der Blick auf Mountpoints – nicht das Raten, welcher Ordner „groß aussieht“. Ein separates /data-Volume kann noch Luft haben, während Root blockiert. „Platte voll“ ohne df -hT als eine Zahl zu behandeln, hat schon manchen in die falsche Spur geschickt:

Schnelldiagnose
# Freier Speicher pro Partition
                df -hT

                # Größte Verzeichnisse direkt unter / (kann dauern)
                sudo du -xh --max-depth=1 / 2>/dev/null | sort -hr | head -20

                # Inode-Erschöpfung wirkt wie volle Platte
                df -ih

du braucht auf Hosts mit Millionen Dateien lange. Ist die Maschine schon träge, gezielt prüfen: sudo du -sh /var/lib/docker /var/log /var/cache. Das offizielle du(1)-Handbuch erklärt -x (ein Dateisystem) und --apparent-size – bei Bind-Mounts oder separaten Volumes nicht von Summen über Mount-Grenzen hinweg täuschen lassen.

Vier Schritte Server-Disk-Cleanup: df-Diagnose, du für große Verzeichnisse, Skript für regenerierbaren Cache, df-Verifikation und logrotate
Empfohlene Reihenfolge: erst diagnostizieren, dann bereinigen; direkt danach df erneut ausführen und logrotate/Cron ergänzen, damit Sie in drei Monaten nicht wieder hier stehen.

Typische Speicherfresser: Referenztabelle

Jeder Stack ist anders, aber die folgenden Pfade tauchen auf Ubuntu- und Debian-VPS ständig auf. Web + Docker + CI auf einer 40-GB-Platte ist ein vertrautes Rezept: Journal und Container-Layer wachsen im Hintergrund, Anwendungslogs explodieren bei Traffic-Spitzen. Die Spalte Auto-sicher? markiert, ob ein Skript sie auf einen Schlag leeren darf – Zeilen mit „Vorsicht“ brauchen eine Abhängigkeitsprüfung. Im Zweifel du dry-run und mit lsof +D /path prüfen, welcher Prozess Dateien offen hält, bevor gelöscht wird.

Pfad / Quelle Typische Größe Auto-sicher? Hinweise
/var/lib/docker Mehrere GB bis zig GB Teilweise Dangling Images, gestoppte Container, ungenutzte Volumes; Daten-Volumes laufender Container nicht löschen
/var/log/journal 1–10+ GB Ja systemd-Journal wächst schnell ohne Größenlimit
/var/log/*.log Hunderte MB bis GB Vorsicht Truncate oder logrotate; direktes rm kann offene fds und stale Inodes hinterlassen
/var/cache/apt Hunderte MB bis mehrere GB Ja apt-get clean ist sicher – entfernt nur heruntergeladene .deb-Pakete
/tmp, /var/tmp Variabel Teilweise Dateien ohne Zugriff seit 7 Tagen löschen; prüfen, ob Apps Uploads hier ablegen
Nginx proxy_cache Mehrere GB Ja Cache baut sich neu auf; nach unserem Nginx-Reverse-Proxy-Tuning kurzzeitig mehr MISS erwarten
Alte Kernel unter /boot Hunderte MB Ja apt autoremove --purge entfernt alte Kernel; aktuellen und vorherigen behalten
Core Dumps, Absturzberichte Variabel Ja /var/crash, Anwendungs-core.*-Dateien
Zuerst echte Daten ausschließen
Stehen /home, /var/lib/mysql, Object-Storage-Mounts oder Backup-Verzeichnisse oben, hilft Cache-Cleanup nicht – Sie brauchen Archivierung, Resize oder Cold-Data-Migration. Skripte holen regenerierbaren Speicher zurück; sie ersetzen keine Kapazitätsplanung.

One-Click-Cleanup-Skript (Copy-Paste)

Das Skript unten läuft standardmäßig im Dry-Run: Es zeigt freizugebenden Speicher und geplante Befehle. Mit --apply wird tatsächlich gelöscht. Immer zuerst dry-run und Ausgabe prüfen – Teams, die das einmal übersprungen und ein wochenaltes Basis-Image als einzige Kopie eines stillgelegten Dienstes geprunt haben, kennen wir. Module sind getrennt; ohne Docker den Docker-Block auskommentieren, ohne proxy_cache den Nginx-Teil.

disk-cleanup.sh — speichern als /usr/local/sbin/disk-cleanup.sh
#!/usr/bin/env bash
                # Server-Disk-Cleanup — nur regenerierbarer Cache
                # Nutzung: sudo ./disk-cleanup.sh          # Vorschau
                #          sudo ./disk-cleanup.sh --apply  # ausführen
                set -euo pipefail

                APPLY=false
                [[ "${1:-}" == "--apply" ]] && APPLY=true

                log() { echo "[$(date '+%F %T')] $*"; }
                run() {
                  if $APPLY; then
                    log "EXEC: $*"
                    eval "$@"
                  else
                    log "DRY-RUN: $*"
                  fi
                }

                before=$(df -h / | awk 'NR==2 {print $3 " used, avail " $4}')
                log "Before: $before"

                # 1. apt-Cache
                if command -v apt-get >/dev/null; then
                  run "apt-get clean -y"
                  run "apt-get autoremove -y --purge"
                fi

                # 2. systemd journal — letzte 7 Tage oder 500MB behalten
                if command -v journalctl >/dev/null; then
                  run "journalctl --vacuum-time=7d"
                  run "journalctl --vacuum-size=500M"
                fi

                # 3. Ungenutzte Docker-Ressourcen (ohne benannte Volume-Geschäftsdaten)
                if command -v docker >/dev/null && docker info >/dev/null 2>&1; then
                  run "docker system prune -af --filter 'until=168h'"
                  run "docker builder prune -af --filter 'until=168h'"
                fi

                # 4. Temp-Verzeichnisse — 7 Tage ohne Zugriff
                run "find /tmp /var/tmp -type f -atime +7 -print 2>/dev/null | head -20"
                if $APPLY; then
                  find /tmp /var/tmp -type f -atime +7 -delete 2>/dev/null || true
                fi

                # 5. Nginx proxy_cache (cache_path anpassen)
                NGINX_CACHE="/var/cache/nginx"
                if [[ -d "$NGINX_CACHE" ]]; then
                  run "du -sh '$NGINX_CACHE'"
                  run "find '$NGINX_CACHE' -type f -delete 2>/dev/null || true"
                fi

                # 6. Absturz-Dumps
                [[ -d /var/crash ]] && run "rm -rf /var/crash/*"

                # 7. pip / npm Cache (falls vorhanden)
                [[ -d /root/.cache/pip ]] && run "rm -rf /root/.cache/pip/*"
                for u in /home/*; do
                  [[ -d "$u/.npm" ]] && run "npm cache clean --force --cache '$u/.npm' 2>/dev/null || rm -rf '$u/.npm/_cacache'"
                done

                after=$(df -h / | awk 'NR==2 {print $3 " used, avail " $4}')
                log "After:  $after"
                $APPLY || log "Dry-Run fertig. Wenn ok: sudo $0 --apply"

Rechte setzen: sudo chmod 750 /usr/local/sbin/disk-cleanup.sh. Beim ersten Lauf ohne --apply die DRY-RUN-Ausgabe speichern. Zeigt der Docker-Teil große Image-Löschungen, prüfen, ob nicht die einzige lokale Kopie eines bereits gelöschten Registry-Tags verschwindet.

Docker prune ist kein Allheilmittel
docker system prune -a entfernt alle ungenutzten Images und erzwingt beim nächsten Deploy einen vollen Re-Pull – schmerzhaft bei knappem VPS-Bandbreite. Sicherer: --filter until=168h, damit nur wochenalte ungenutzte Layer gehen, oder regelmäßig docker image prune -f nur für Dangling Images. Siehe die offizielle Docker-Pruning-Dokumentation.

Modul für Modul: was weg darf, was nicht

journalctl: --vacuum-time und --vacuum-size lassen sich kombinieren; systemd kürzt Binärlogs gemäß der journalctl-Dokumentation. Für ein dauerhaftes Limit SystemMaxUse=500M in /etc/systemd/journald.conf, dann systemctl restart systemd-journald.

Logdateien: Bei großen, noch geöffneten Logs ist truncate -s 0 /var/log/nginx/access.log sicherer als rm – der Prozess behält sein fd; Löschen der Datei entfernt nur den Verzeichniseintrag, ohne Speicher sofort freizugeben. Langfristig logrotate mit täglicher Rotation und N Generationen für Nginx und Anwendungslogs.

apt: apt-get clean leert nur /var/cache/apt/archives; autoremove --purge entfernt alte Kernel und verwaiste Abhängigkeiten. Nach Kernel-Upgrade aktuellen und vorherigen Kernel behalten. In Produktion vor autoremove uname -r gegen dpkg -l 'linux-image-*' prüfen.

Geschäftsdaten nicht anfassen: /var/lib/mysql, /var/lib/postgresql, Redis-RDB, Upload-Verzeichnisse und Backup-Mounts liegen außerhalb des Skripts. Stehen sie bei du oben, brauchen Sie Archivierung, Resize oder Cold Storage – kein Cache-Cleanup.

Nach dem Cleanup: verhindern, dass die Platte wieder leise voll läuft

Root von 98 % auf 60 % zu bringen, ist nur der Anfang. Ohne Leitplanken wächst das Journal in sechs Wochen wieder auf 8 GB, Docker-Layer häufen sich nach jedem Deploy, und ein Traffic-Peak wiederholt den Vorfall. Unser Mindest-Präventions-Stack für kleine VPS:

  • Alert-Schwellen: Cloud-Konsole oder Prometheus bei 80 %, SMS/Pager bei 85 % – nicht bis 95 % warten.
  • Wöchentlicher Cron: 0 4 * * 0 root /usr/local/sbin/disk-cleanup.sh --apply >> /var/log/disk-cleanup.log 2>&1
  • journald + logrotate Limits: unbegrenztes Wachstum in ein erträgliches Deck verwandeln.

Bei Docker Compose max-size und max-file für json-file-Logging setzen – sonst füllt stdout eines Containers die Platte genauso sicher wie verwaiste Image-Layer, und diese Falle wird oft übersehen.

Kapazitätsdenken auf kleinen Platten
Ein 40-GB-Tarif mit Web + DB + Docker ist knapp. Statische Assets in Object Storage oder CDN, DB-Binlogs planmäßig archivieren, CI auf dediziertem Runner – günstiger als monatliche 3-Uhr-Notfälle. Speicher ist billig; Operator-Zeit nicht.

Checkliste vor dem Eingriff

In Ihr Runbook übernehmen und bei der nächsten Meldung der Reihe nach abarbeiten:

  • df -hT und df -ih — Speicher vs. Inode-Erschöpfung
  • du -sh für docker, journal, log, cache
  • Skript dry-run → menschliche Prüfung → --apply
  • Nach Cleanup df -h, dann DB, Nginx, Docker spot-checken
  • journald-Limits, logrotate, Cron und 80-%-Alerts ergänzen

Volle Platte ist nie nur „ein paar Dateien löschen“ – es ist ein Gesundheitscheck für Kapazität und Logging-Policy. Das Skript ersetzt panisches rm um 3 Uhr durch einen wiederholbaren Standard. Dokumentieren, was gelöscht wurde und wie weit df sprang – oft fehlt dann eine logrotate-Stanza oder Container-Logging ohne Rotation. Der Rest ist Prävention, damit der Pager ruhig bleibt.

Build-Artefakte fressen die Platte? Rollen trennen

Läuft auf Ihrer VPS Produktion und lokales xcodebuild, mehrstufige Docker-Builds oder Ollama-Model-Caches, kann eine kleine Platte in einer Compile-Woche verschwinden – DerivedData und Image-Layer konkurrieren mit Produktionslogs auf derselben SSD.

Sauberer getrennt: Produktions-VPS schlank halten, schwere Builds woanders – Cloud-Mac für iOS-Pakete, dedizierter CI-Runner, Produktion zieht nur finale Artefakte.

Mac mini M4 mit Unified Memory und niedrigem Leerlaufverbrauch eignet sich als „nur Build, kein 24/7-Traffic“-Knoten. Mit Linux-VPS für Runtime kämpfen Compile-Caches nicht mehr mit Produktionslogs um dieselbe Platte. Planen Sie diese Trennung, lagern Sie schwere Arbeit zuerst in die Cloud-Mac ausVPSSpark-Tarife ansehen und weniger 3-Uhr-Sessions mit df -h.

Zeitlich begrenzt

Builds fressen die Platte? Produktion und Build trennen

Cloud-Mac für Builds · schlanker Linux-VPS für Runtime · weniger 3-Uhr-Notfälle

Zur Startseite
Zeitlich begrenzt Tarife ansehen