„No space left on device“ a „Address already in use“: rychlé řešení
Dvě nejčastější chyby na VPS krok za krokem: jak najít, co zaplnilo disk, uvolnit místo bezpečně, a jak zjistit a ukončit proces blokující port.
Dvě chyby, se kterými se na serveru setká skoro každý: plný disk a obsazený port. Obě vypadají děsivě, ale mají jasný postup řešení. Tady je návod, který můžete projít i ve stresu, když web právě nefunguje.
Část 1: No space left on device
Příznaky: databáze přestane zapisovat, nginx vrací 500, apt selže, nelze uložit soubor, někdy nejde ani dokončit SSH přihlášení nebo doplňování tabulátorem v shellu.
Krok 1: Potvrďte, co došlo
df -h
df -i
df -h ukazuje místo, df -i inody. Inody můžou dojít i při volném místě – typicky miliony malých souborů (sessions, cache, fronta e-mailů).
Krok 2: Najděte, co zabírá místo
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -n 10
Přepínač -x zůstane na jednom souborovém systému. Pak se zanořujte do největšího adresáře:
sudo du -xh --max-depth=1 /var 2>/dev/null | sort -h | tail -n 10
Pohodlnější je interaktivní ncdu:
sudo apt install ncdu
sudo ncdu -x /
Pokud je disk úplně plný a apt nefunguje, nejdřív uvolněte trochu místa některým z kroků níže.
Velké soubory napříč systémem:
sudo find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null
Krok 3: Obvyklí viníci a bezpečný úklid
| Viník | Kontrola | Úklid |
|---|---|---|
| systemd journal | journalctl --disk-usage |
sudo journalctl --vacuum-size=200M |
| logy aplikací | du -sh /var/log/* |
truncate -s 0 + logrotate |
| cache apt | du -sh /var/cache/apt |
sudo apt clean |
| stará jádra a závislosti | dpkg -l 'linux-image*' |
sudo apt autoremove --purge |
| Docker | docker system df |
docker system prune (pozor, viz níže) |
| staré zálohy, dumpy | ls -lh /root /home/*/ |
přesunout mimo server |
| snap revize | snap list --all |
odstranit disabled revize |
K Dockeru: docker system prune maže zastavené kontejnery, nepoužívané sítě, dangling obrazy a build cache. S -a maže i všechny nepoužívané obrazy a s --volumes i nepoužívané volumes – tam můžou být data databáze. Vždy si nejdřív přečtěte, co příkaz vypíše.
Logy nemažte přes rm, ale zkraťte:
sudo truncate -s 0 /var/log/nginx/access.log
Krok 4: Smazal jsem, ale místo se neuvolnilo
Proces má smazaný soubor stále otevřený. Najděte ho:
sudo lsof +L1
Ve sloupci NLINK je 0 a na konci (deleted). Restartujte danou službu a místo se uvolní.
Krok 5: Zabraňte opakování
- logrotate a limit
SystemMaxUsepro journald, - zálohy ukládejte mimo server,
- jednoduchá kontrola v cronu, která vás upozorní při zaplnění nad 85 %:
#!/usr/bin/env bash
USAGE=$(df --output=pcent / | tail -1 | tr -dc '0-9')
if [ "$USAGE" -ge 85 ]; then
echo "Disk / je zaplněný na ${USAGE} %" | logger -t diskcheck -p user.warning
fi
Místo logger můžete poslat zprávu do Slacku, Discordu nebo e-mailem přes webhook.
Část 2: Address already in use
Příznaky: služba nenastartuje a v logu je:
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Error: listen EADDRINUSE: address already in use :::3000
OSError: [Errno 98] Address already in use
Krok 1: Kdo port drží
sudo ss -tlpn 'sport = :80'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("apache2",pid=1234,fd=4))
Alternativy: sudo lsof -i :80 nebo sudo fuser -v 80/tcp. Pro UDP použijte ss -ulpn.
sudo je důležité – bez něj neuvidíte procesy jiných uživatelů.
Krok 2: Typické příčiny a řešení
Jiná služba na stejném portu – nejčastěji Apache vs. nginx na portu 80:
sudo systemctl disable --now apache2
sudo systemctl start nginx
Stará instance vaší aplikace – spustili jste ji ručně v screen/tmux nebo přes nohup a teď spouštíte systemd službu:
ps -fp 1234
sudo kill 1234 # SIGTERM, slušné ukončení
sudo kill -9 1234 # jen pokud předchozí nepomůže
Docker kontejner publikuje port – ss ukáže proces docker-proxy:
docker ps --format '{{.Names}}\t{{.Ports}}'
docker stop nazev-kontejneru
Socket activation – port drží systemd, ne samotná služba (na Ubuntu 24.04 třeba ssh.socket). V ss uvidíte systemd jako proces:
systemctl list-sockets
Restart aplikace, port ještě „dobíhá“ – po ukončení serveru můžou spojení chvíli zůstat ve stavu TIME_WAIT. Serverové aplikace by měly nastavovat SO_REUSEADDR (Node.js a většina frameworků to dělá automaticky). V Pythonu u vlastního socketu:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Dva bloky listen v nginx – stejný port a IP v kombinaci, která koliduje (např. default_server dvakrát). nginx -t to odhalí.
Krok 3: Nechte port volný napořád
- každou aplikaci spouštějte jen jedním způsobem (ideálně systemd služba),
- porty aplikací držte na
127.0.0.1a ven pouštějte jen nginx, - port mějte v konfiguraci (proměnná
PORT), ne natvrdo v kódu.
Tahák
df -h; df -i # místo a inody
sudo ncdu -x / # co zabírá místo
sudo lsof +L1 # smazané, ale otevřené soubory
sudo ss -tlpn 'sport = :80' # kdo drží port 80
systemctl list-sockets # porty držené systemd
Pokud máte server připojený v ColdHost AI, stačí popsat chybu – AI navrhne diagnostické příkazy, vy je jednotlivě schválíte a podle výstupu pokračuje k řešení.