Disk voll: Speicherplatz unter Linux freigeben – Schritt für Schritt
No space left on device – diese Meldung kommt immer im ungünstigsten Moment. Datenbank schreibt nicht mehr, Webserver liefert 500-Fehler, Logs brechen ab. Wer weiß wo er suchen muss, behebt das Problem in Minuten.
Dieser Guide zeigt den systematischen Weg: Erst analysieren, dann gezielt aufräumen.
Schnelldiagnose: Was ist voll?
df – Dateisystem-Übersicht
# Übersicht aller Dateisysteme
df -h
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 50G 48G 1.2G 98% /
# /dev/sdb1 200G 45G 155G 23% /data
# tmpfs 7.8G 234M 7.6G 3% /dev/shm
# Nur echte Dateisysteme (keine tmpfs, devtmpfs etc.)
df -h --type=ext4 --type=xfs --type=btrfs
# Inode-Nutzung (wichtig bei vielen kleinen Dateien!)
df -i
Wenn der Prozentwert 100% (oder 99%) zeigt: Manche Dateisysteme reservieren 5% für root.
Use% 100bei regulären Benutzern bedeutet, dass root noch etwas Platz hat.df -hzeigt das.
lsof – Gelöschte aber noch offene Dateien
# Ein häufiger Grund für "voll ohne sichtbaren Grund":
# Dateien sind gelöscht, werden aber noch von Prozessen gehalten
# (verschwinden erst wenn der Prozess sie freigibt)
sudo lsof | grep deleted | awk '{print $1, $7, $9}' | sort -k2 -rn | head -20
# Ausgabe: Prozessname, Größe, Dateiname (deleted)
# Platz zurückgewinnen: betroffene Prozesse neu starten
sudo systemctl restart nginx # Beispiel
Speicherfresser finden
du – Verzeichnisgrößen
# Größte Verzeichnisse in / (erste Ebene)
du -sh /* 2>/dev/null | sort -rh | head -15
# Rekursiv: Unterverzeichnisse mit einbeziehen
du -sh /var/* 2>/dev/null | sort -rh | head -10
# Alle Unterverzeichnisse bis Tiefe 2
du -h --max-depth=2 /var/ 2>/dev/null | sort -rh | head -20
# Top 20 größte Dateien im gesamten System
find / -type f -printf '%s %p\n' 2>/dev/null | \
sort -rn | head -20 | \
numfmt --field=1 --to=iec
ncdu – Interaktiver Disk-Usage-Analyzer
ncdu ist das beste Werkzeug für interaktive Analyse – zeigt eine navigierbare Baumansicht.
# Installieren
sudo apt install ncdu # Ubuntu/Debian
sudo dnf install ncdu # Fedora
# Aktuelles Verzeichnis analysieren
ncdu
# Spezifisches Verzeichnis
ncdu /var
# Remote (über SSH)
ssh server "ncdu -o- /" | ncdu -f-
# Navigation in ncdu:
# ↑/↓ oder j/k: navigieren
# Enter: in Verzeichnis wechseln
# d: Verzeichnis löschen (mit Bestätigung)
# q: beenden
gdu – Schnelle Alternative zu ncdu
# Installieren (auch als Single Binary verfügbar)
sudo apt install gdu # Ubuntu 22.04+
# Starten
gdu /
Systemdateien aufräumen
/tmp – Temporäre Dateien
# Größe prüfen
du -sh /tmp/
# Alles löschen (Vorsicht: laufende Prozesse könnten Dateien nutzen!)
# Sicherer: Reboot (Linux leert /tmp beim Neustart)
sudo rm -rf /tmp/*
# Alte Dateien (>7 Tage) löschen
sudo find /tmp -mtime +7 -delete
# tmpwatch / systemd-tmpfiles für automatisches Cleanup
sudo systemd-tmpfiles --clean
/var/tmp – Halbpermanente temporäre Dateien
du -sh /var/tmp/
sudo find /var/tmp -mtime +30 -delete # älter als 30 Tage
Downloads und persönliche Dateien
# Heimverzeichnis analysieren
du -sh ~/* 2>/dev/null | sort -rh | head -15
# Große Dateien im Home finden (>100MB)
find ~ -type f -size +100M -printf '%s %p\n' 2>/dev/null | \
sort -rn | numfmt --field=1 --to=iec
Docker aufräumen
Docker kann schnell viele Gigabyte belegen – Images, Container, Volumes und Build-Cache summieren sich.
# Gesamten Docker-Speicherverbrauch anzeigen
docker system df
# TYPE TOTAL ACTIVE SIZE RECLAIMABLE
# Images 15 8 12.3GB 6.2GB (50%)
# Containers 5 3 234MB 12MB (5%)
# Local Volumes 8 5 4.5GB 1.2GB (26%)
# Build Cache - - 2.1GB 2.1GB
# Alles reclaimable auf einmal löschen
docker system prune
# Auch Volumes löschen (VORSICHT: Datenverlust!)
docker system prune --volumes
# Aggressiv: auch ungenutzte Images löschen
docker system prune -a
# Einzeln aufräumen:
# Gestoppte Container
docker container prune
# Ungenutzte Images (dangling = ohne Tag)
docker image prune
# Alle ungenutzten Images (nicht nur dangling)
docker image prune -a
# Ungenutzte Volumes
docker volume prune
# Build-Cache löschen
docker builder prune
# Build-Cache älter als 24h löschen
docker builder prune --keep-storage 2GB
Docker-Datenverzeichnis verschieben (wenn / voll)
# Standardpfad: /var/lib/docker
# Prüfen:
du -sh /var/lib/docker/
# In /etc/docker/daemon.json anderen Pfad setzen:
sudo nano /etc/docker/daemon.json
{
"data-root": "/data/docker"
}
sudo systemctl stop docker
sudo mv /var/lib/docker /data/docker
sudo systemctl start docker
docker system df # prüfen
Logs bereinigen
journald – systemd Journal
# Aktueller Speicherverbrauch
journalctl --disk-usage
# Alte Logs löschen (älter als X)
sudo journalctl --vacuum-time=7days # 7 Tage
sudo journalctl --vacuum-time=2weeks # 2 Wochen
sudo journalctl --vacuum-time=1month # 1 Monat
# Auf bestimmte Größe begrenzen
sudo journalctl --vacuum-size=500M
# Journal dauerhaft begrenzen (in /etc/systemd/journald.conf)
sudo nano /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M # Max. Gesamtgröße
SystemKeepFree=1G # Mindestens 1G frei halten
MaxRetentionSec=1month # Maximal 1 Monat aufbewahren
sudo systemctl restart systemd-journald
/var/log – Klassische Logdateien
# Größte Log-Dateien finden
du -sh /var/log/* 2>/dev/null | sort -rh | head -20
# Große Logdatei leeren ohne zu löschen (Prozesse halten sie offen!)
sudo truncate -s 0 /var/log/syslog
# Komprimierte alte Logs löschen
sudo find /var/log -name "*.gz" -delete
sudo find /var/log -name "*.1" -delete
# logrotate manuell ausführen
sudo logrotate -f /etc/logrotate.conf
Nginx/Apache-Logs
# Aktuelle Größe
du -sh /var/log/nginx/
# Access-Log rotieren
sudo logrotate -f /etc/logrotate.d/nginx
# Log-Rotation konfigurieren (/etc/logrotate.d/nginx):
sudo nano /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14 # 14 Tage aufbewahren
compress # gzip komprimieren
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
nginx -s reopen
endscript
}
APT/DNF-Cache und alte Pakete
Ubuntu/Debian (apt)
# Paket-Cache-Größe
du -sh /var/cache/apt/archives/
# Veraltete Pakete aus Cache löschen
sudo apt autoclean
# Gesamten Cache löschen
sudo apt clean
# Nicht mehr benötigte Pakete (verwaiste Abhängigkeiten) entfernen
sudo apt autoremove
# Alte Linux-Kernel entfernen (behält aktiven + einen)
# Vorsicht: erst prüfen!
uname -r # aktiver Kernel
dpkg -l "linux-image*" | grep "^ii" # installierte Kernel
sudo apt autoremove --purge # entfernt auch alte Kernel
# Oder gezielt:
sudo apt purge linux-image-5.15.0-91-generic
Fedora (dnf)
# Cache-Größe
du -sh /var/cache/dnf/
# Cache leeren
sudo dnf clean all
# Nicht mehr benötigte Pakete
sudo dnf autoremove
# Paket-Liste ohne Download neu aufbauen
sudo dnf makecache
Inode-Erschöpfung (seltener, aber tückisch)
df -h zeigt noch freien Speicher, aber du kannst trotzdem keine Dateien erstellen? Dann sind die Inodes voll. Jede Datei (auch leere) braucht einen Inode.
# Inode-Nutzung prüfen
df -i
# Filesystem Inodes IUsed IFree IUse% Mounted on
# /dev/sda1 3276800 3276800 0 100% / ← voll!
# Verzeichnisse mit vielen kleinen Dateien finden
# (der übliche Verdächtige: Mail-Spool, Session-Dateien, Cache)
find / -xdev -printf '%h\n' 2>/dev/null | sort | uniq -c | sort -rn | head -20
Typische Inode-Fresser
# PHP-Sessions
du -sh /var/lib/php/sessions/
ls /var/lib/php/sessions/ | wc -l # Anzahl Sessions
sudo find /var/lib/php/sessions/ -mtime +1 -delete
# Postfix/Exim Mail-Queue
ls /var/spool/postfix/deferred/ | wc -l
sudo postsuper -d ALL deferred # alle verzögerten Mails löschen
# Node.js node_modules (viele kleine Dateien!)
find /var/www -name "node_modules" -type d -prune | \
xargs du -sh 2>/dev/null | sort -rh | head -10
# Temporäre Upload-Dateien
find /tmp -maxdepth 1 -name "tmp.*" | wc -l
sudo find /tmp -maxdepth 1 -name "tmp.*" -mtime +1 -delete
Automatisches Monitoring
Bash-Skript: Disk-Alert per E-Mail
sudo nano /usr/local/bin/disk-alert.sh
#!/bin/bash
# Disk-Space-Alert: Sendet Warnung wenn Nutzung über Schwellwert
THRESHOLD=85 # Warnen ab 85%
EMAIL="admin@example.com"
df -h --output=pcent,target | tail -n +2 | while read -r line; do
USAGE=$(echo "$line" | awk '{print $1}' | tr -d '%')
MOUNT=$(echo "$line" | awk '{print $2}')
if [ "$USAGE" -ge "$THRESHOLD" ]; then
echo "WARNUNG: $MOUNT ist zu ${USAGE}% voll auf $(hostname)" | \
mail -s "Disk Alert: $MOUNT ${USAGE}% voll" "$EMAIL"
fi
done
sudo chmod +x /usr/local/bin/disk-alert.sh
# Als Cron-Job alle 30 Minuten
echo "*/30 * * * * root /usr/local/bin/disk-alert.sh" | \
sudo tee /etc/cron.d/disk-alert
Prometheus Node Exporter (für Monitoring-Stacks)
# Mit Docker
docker run -d \
--name node-exporter \
--pid="host" \
-v "/:/host:ro,rslave" \
prom/node-exporter \
--path.rootfs=/host
# Metriken ansehen (Port 9100)
curl localhost:9100/metrics | grep node_filesystem_avail
Schnell-Referenz
# 1. Was ist voll?
df -h
# 2. Wo ist der Speicher?
du -sh /* 2>/dev/null | sort -rh | head -10
ncdu / # interaktiv
# 3. Gelöschte aber offene Dateien?
sudo lsof | grep deleted
# 4. Docker aufräumen
docker system prune -a
# 5. Journal verkleinern
sudo journalctl --vacuum-time=2weeks
# 6. APT aufräumen
sudo apt clean && sudo apt autoremove
# 7. Alte Logs löschen
sudo find /var/log -name "*.gz" -delete
| Speicherfresser | Größenordnung | Befehl |
|---|---|---|
| Docker (images/volumes) | Mehrere GB | docker system prune -a |
| systemd Journal | 100MB–2GB | journalctl --vacuum-time=7d |
| APT-Cache | 100MB–1GB | apt clean |
| Alte Kernel | 200–500MB je Kernel | apt autoremove --purge |
| /tmp | variabel | find /tmp -mtime +7 -delete |
| Node.js node_modules | Mehrere GB | manuell entfernen |
| PHP-Sessions | 100MB–mehrere GB | find /var/lib/php/sessions -mtime +1 -delete |
Fazit
Wenn die Disk voll ist, geht es um schnelles, systematisches Vorgehen. Fast immer steckt einer dieser Übeltäter dahinter: Docker, System-Logs, APT-Cache oder gelöschte-aber-noch-offene Dateien. Mit ncdu findest du den Schuldigen in unter einer Minute.
Richte danach automatisches Monitoring ein, damit du nicht wieder unvorbereitet getroffen wirst.