Quando um disco Linux está cheio, trabalhe por esta ordem. Execute df -h para ver que sistema de ficheiros está a 100%. Depois execute du -sh * | sort -h para descer um diretório de cada vez até encontrar o culpado, e use o ncdu para o explorar de forma interativa. Por fim, recupere espaço com journalctl --vacuum-size e docker system prune.

df -h: que sistema de ficheiros está cheio e se os inodes se esgotaram

O df -h mostra o tamanho, o espaço usado, o disponível e a percentagem de utilização de cada sistema de ficheiros montado, em unidades legíveis (K, M, G). Vem em primeiro lugar porque responde à pergunta que importa antes de tudo: que partição está cheia? Limpar /home não serve de nada se é /var que está a 100%.

df -h
df -h /var
df -i

Se o df -h mostra espaço livre mas as escritas continuam a falhar com «No space left on device», verifique o df -i. Pode ter esgotado os inodes por causa de milhões de ficheiros minúsculos: caches, sessões ou filas de correio. Nesse caso, o tamanho é irrelevante. O problema é o número de ficheiros, por isso procure o diretório com mais entradas, não o mais pesado.

du -sh * | sort -h: encontrar o diretório que enche o disco

O du -sh * | sort -h calcula o total de cada entrada do diretório atual e ordena os resultados do menor para o maior. O maior culpado fica na última linha, mesmo acima do prompt, que é tudo o que precisa de ler num ecrã pequeno.

cd /var
sudo du -sh * | sort -h

# from root, without crossing into other filesystems
sudo du -xh --max-depth=1 / 2>/dev/null | sort -h

# include hidden files and directories
du -sh .[!.]* * | sort -h

Tenha em conta três pormenores. O glob * ignora os ficheiros ocultos (dotfiles), e é por isso que existe a última linha. O -x mantém-se no sistema de ficheiros de partida e ignora /proc e as montagens de rede. O 2>/dev/null esconde o ruído das permissões negadas. Repita o comando um nível mais abaixo de cada vez até chegar ao ficheiro. Todas as outras flags estão documentadas na página de manual do du.

Em discos grandes, o du pode demorar vários minutos. Inicie-o dentro do tmux: se a ligação cair, a análise continua e o resultado está à sua espera quando voltar a ligar-se.

ncdu: explorar um disco cheio de forma interativa

O ncdu -x / analisa o sistema de ficheiros uma única vez e depois mostra uma árvore navegável ordenada por tamanho, para que deixe de ter de executar o du em cada nível. Instale-o com o gestor de pacotes da sua distribuição (apt install ncdu, dnf install ncdu).

sudo ncdu -x /
sudo ncdu -x /var/lib

Dentro do ncdu, use estas teclas:

  • as setas, para se deslocar;
  • Enter, para abrir um diretório;
  • a seta para a esquerda, para voltar ao nível acima;
  • d, para eliminar (pede confirmação);
  • q, para sair.

Num telemóvel, tudo depende de ter as setas e o Esc à mão. O teclado próprio do termi1 inclui-os, juntamente com Ctrl, Tab e PgUp/PgDn para percorrer listagens longas.

Ficheiros eliminados que continuam a encher o disco: lsof +L1

Se o total do du está claramente abaixo do espaço usado que o df indica, há algum processo a manter aberto um ficheiro eliminado. O caso clássico é um log removido com rm enquanto o serviço ainda escrevia nele. O espaço só é libertado quando esse descritor de ficheiro é fechado.

sudo lsof +L1
# restart the service holding it, or empty the descriptor:
sudo truncate -s 0 /proc/PID/fd/N

A regra é simples: para esvaziar um log em uso, execute truncate -s 0 file, e não rm.

journalctl --vacuum: reduzir os logs do systemd que enchem /var

O journalctl --disk-usage indica quanto espaço ocupa o journal do systemd. As opções --vacuum-size e --vacuum-time eliminam os ficheiros de journal arquivados mais antigos até que o limite definido seja cumprido.

journalctl --disk-usage
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=2weeks

Um vacuum é uma operação pontual. Para evitar que o problema volte, defina SystemMaxUse= em /etc/systemd/journald.conf e reinicie o systemd-journald.

docker system prune: recuperar o espaço que o Docker ocupa

O docker system df discrimina o espaço ocupado por imagens, contentores, volumes e cache de build. Execute-o antes de eliminar o que quer que seja, para saber onde está realmente o grosso.

docker system df
docker system prune
docker system prune -a --volumes

Sem flags, o docker system prune remove os contentores parados, as redes não usadas, as imagens órfãs (dangling) e a cache de build. O -a remove também todas as imagens que não estejam a ser usadas por um contentor. O --volumes elimina os volumes não usados, e os respetivos dados vão com eles. Em servidores de produção, leia o resultado de docker system df -v antes de acrescentar essa flag.

df vs du vs ncdu para diagnosticar um disco cheio

FerramentaO que medeQuando usarLimitação
df -hUtilização por sistema de ficheiros montadoPrimeiro passo: descobrir que partição está cheiaNão mostra que diretório ocupa o espaço
du -sh * | sort -hTamanho de cada entrada do diretório atualServidores sem pacotes adicionais; resultado fácil de lerTem de ser repetido por nível; ignora os ficheiros ocultos
ncdu -x /Árvore completa ordenada por tamanhoExploração interativa e eliminação com confirmaçãoRequer instalação; requer teclas de setas
lsof +L1Ficheiros eliminados ainda abertosQuando o df e o du não coincidemSó os encontra; não liberta espaço

Limpar um disco cheio a partir do telemóvel com o termi1

Os alertas de disco cheio costumam disparar a más horas, por isso compensa poder resolvê-los com segurança a partir do telemóvel. Antes de truncar um log de que possa vir a precisar, descarregue-o por SFTP: o termi1 tem-no integrado, sem sair da sessão. O Mosh mantém a ligação ativa quando passa do Wi-Fi para os dados móveis, e o tmux mantém um du longo em execução mesmo que feche a app.

A IA do termi1 transforma uma frase como «que diretórios em /var ocupam mais espaço» no comando correspondente e escreve-o no prompt sem carregar em Enter. Nas ligações marcadas como produção, o Production Guard retém tudo o que elimina, como docker system prune ou journalctl --vacuum-size, antes de chegar ao prompt. O terminal é gratuito no terminal SSH no Google Play. Encontra mais guias no blog técnico do termi1.

Perguntas frequentes

Porque é que o df e o du indicam tamanhos diferentes?

O df e o du discordam porque o df lê a utilização do sistema de ficheiros e o du soma os ficheiros que encontra. Se um processo mantém aberto um ficheiro eliminado, o df continua a contá-lo e o du não. Execute sudo lsof +L1 para o localizar e reinicie o serviço responsável.

É seguro executar docker system prune num servidor?

O docker system prune sem flags só remove contentores parados, redes não usadas, imagens órfãs (dangling) e a cache de build. O risco surge com -a, que apaga imagens sem contentor, e sobretudo com --volumes, que elimina os dados dos volumes não usados. Verifique primeiro docker system df.

Como incluo os ficheiros ocultos com du -sh?

Para que o du -sh inclua ficheiros ocultos, acrescente o padrão .[!.]* ao glob: du -sh .[!.]* * | sort -h. O asterisco da shell não expande nomes começados por ponto, por isso diretórios como .cache ou .local podem ficar fora dos totais e passar despercebidos.

Como evito que o journald volte a encher o disco?

Para limitar o journald de forma permanente, defina SystemMaxUse= em /etc/systemd/journald.conf com o tamanho máximo pretendido e reinicie o systemd-journald. O journalctl --vacuum-size só limpa uma vez; o limite no ficheiro de configuração impede que o journal volte a crescer sem controlo.