Tutoriais de VPS
VPS mostra espaço livre em disco mas não consegue gravar arquivos (2026): como diagnosticar e limpar o esgotamento de inodes
O VPS reporta No space left on device, mas o df -h claramente mostra espaço livre? Provavelmente não é a capacidade que está cheia, mas os inodes que se esgotaram. Este artigo explica a diferença entre df -h e df -i, como localizar a origem dos arquivos pequenos e como limpar com segurança arquivos de Docker, journal, cache e sessão.

Existe um tipo de falha de VPS que confunde facilmente:
No space left on device
Sua primeira reação é que o disco está cheio, então você executa:
df -h
E descobre que a partição / está apenas 60% usada, ou seja, claramente ainda há espaço suficiente. Mas os uploads do site falham, o banco de dados não consegue gravar, o cache do Nginx dá erro, a criação de sessão PHP falha e até touch test.txt falha.
Nesse momento, o que você deve suspeitar não é da capacidade do disco, mas dos inodes.
Em resumo, o espaço em disco controla "quanto conteúdo de arquivo pode ser armazenado", enquanto os inodes controlam "quantos arquivos podem ser criados". Se milhões de arquivos pequenos se acumularem no servidor, o espaço pode ainda não ter acabado, mas os inodes já podem estar esgotados. O Linux continuará reportando No space left on device, porque, para o sistema de arquivos, ele não tem mais onde registrar novos arquivos.
Primeiro veja o espaço:
df -h
Depois veja os inodes:
df -i
df -h mostra a capacidade, df -i mostra os inodes. A documentação do GNU Coreutils para df também lista -i / --inodes separadamente como informações de uso de inode.
Você pode ver algo assim:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 1310720 1310500 220 100% /
Essa situação é um caso típico de inodes quase esgotados ou já esgotados. Nesse ponto, mesmo que df -h ainda tenha dezenas de GB de espaço, pode não ser possível criar novos arquivos.
Você também pode fazer um teste seguro:
touch /tmp/inode-test
Se isso também reportar No space left on device enquanto df -i mostra 100%, basicamente está confirmado.
Os inodes normalmente não são consumidos por arquivos grandes, mas por uma grande quantidade de arquivos pequenos.
As fontes comuns em um VPS incluem:
- Arquivos de sessão PHP
- Cache do Nginx / CDN / proxy reverso
- Arquivos pequenos do Docker overlay2
- Caches de npm, pip, composer
- Filas de e-mail
- Diretórios temporários de upload
- Arquivos pequenos gerados por rastreadores, scraping, rotação de logs
- Aplicações que gravam cada requisição, cada tarefa, cada mensagem como um arquivo separado
Um arquivo pequeno de 2 KB também ocupa um inode. Um vídeo grande de dezenas de GB pode ocupar apenas alguns inodes, mas milhões de arquivos de sessão podem encher os inodes rapidamente.
A operação mais perigosa em uma falha de inode é apagar diretórios diretamente sem saber quem está ocupando os inodes.
Principalmente, não apague às cegas estes caminhos:
/var/lib
/etc
/usr
/home
/var/lib/docker
Alguns diretórios parecem grandes ou contêm muitos arquivos, mas dentro podem haver bancos de dados, camadas do Docker, estado do gerenciador de pacotes ou dados de serviços em execução. Se apagar errado, o problema de inode não é resolvido e o sistema quebra primeiro.
A ordem correta é: primeiro localizar, depois limpar; primeiro limpar caches e arquivos temporários, depois considerar os dados de negócio.
Comece a contar a partir da partição raiz, olhando a quantidade de arquivos em cada nível:
sudo find / -xdev -type f | cut -d/ -f2 | sort | uniq -c | sort -nr | head
Se /var for o que tem mais, olhe mais abaixo:
sudo find /var -xdev -type f | cut -d/ -f2-3 | sort | uniq -c | sort -nr | head
Continue detalhando:
sudo find /var -xdev -type f | cut -d/ -f2-4 | sort | uniq -c | sort -nr | head
A ideia desse tipo de comando não é olhar o tamanho dos arquivos, mas a "quantidade de arquivos". Porque quando os inodes são esgotados por arquivos pequenos, du -sh não necessariamente expõe o problema rapidamente.
Se você suspeitar de um diretório específico, como PHP session:
sudo find /var/lib/php/sessions -type f | wc -l
Se suspeitar do Docker:
sudo find /var/lib/docker -xdev -type f | wc -l
Se suspeitar do cache do Nginx:
sudo find /var/cache/nginx -type f | wc -l
Às vezes você já excluiu arquivos, mas o espaço não foi liberado. O motivo é que os processos ainda mantêm esses arquivos abertos.
Você pode verificar:
sudo lsof +L1
Esse comando lista arquivos com link count menor que 1, ou seja, arquivos já removidos do diretório mas ainda mantidos por processos. Ele é mais usado para problemas de liberação de capacidade, mas também vale a pena dar uma olhada ao diagnosticar anomalias relacionadas ao disco.
Se encontrar um arquivo de log mantido por um processo, normalmente não mate o processo diretamente; primeiro determine o tipo de serviço. Para Nginx, PHP-FPM e serviços de aplicação, prefira reload ou restart:
sudo systemctl reload nginx
sudo systemctl restart php8.2-fpm
sudo systemctl restart app
Antes de reiniciar, confirme se é um serviço de produção, para evitar interromper o negócio sem querer.
Se o journal do systemd ocupa muitos arquivos, primeiro veja o uso de disco dele:
journalctl --disk-usage
Para limpar logs antigos, você pode usar os parâmetros vacuum oficialmente suportados pelo systemd, por exemplo manter apenas 7 dias:
sudo journalctl --vacuum-time=7d
Ou limitar o tamanho total:
sudo journalctl --vacuum-size=500M
Não entre diretamente em /var/log/journal para apagar coisas à mão. journalctl --vacuum-* é uma forma mais segura e controlável.
Se você notar que o journal costuma crescer muito rápido, continue investigando: algum serviço está reportando erros sem parar? Você pode usar:
journalctl -p warning --since "24 hours ago" --no-pager
systemctl --failed
Limpar logs é apenas estancar o sangramento; o que realmente precisa ser corrigido é o serviço que continua inundando os logs.
O Docker é um grande consumidor de inodes, especialmente com builds frequentes, pulls frequentes de imagens, logs de contêiner sem limite e camadas overlay2 acumuladas.
Primeiro veja o uso do Docker:
docker system df
Liste os contêineres:
docker ps -a
Antes de limpar, confirme quais imagens, contêineres e volumes ainda são necessários. Um primeiro passo relativamente seguro é limpar contêineres parados, redes não usadas, imagens pendentes (dangling) e build cache:
docker system prune
Se você tiver certeza de que imagens não usadas também podem ser apagadas, então use:
docker system prune -a
Atenção: -a vai apagar todas as imagens que não estão sendo usadas atualmente por contêineres. Para ambientes de produção, é melhor confirmar primeiro se o rollback da implantação depende de imagens antigas.
Não apague diretamente /var/lib/docker/overlay2. Isso vai quebrar o estado interno do Docker e pode impedir que os contêineres iniciem.
Uma forma melhor de prevenção é colocar limites nos logs dos contêineres. Por exemplo, configuração do daemon do Docker:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
Depois de alterar, é preciso reiniciar o Docker:
sudo systemctl restart docker
Reiniciar o Docker afeta os contêineres, então em produção é preciso agendar uma janela.
Se os inodes forem consumidos pelas sessões PHP, primeiro confirme o diretório de sessões:
php -i | grep session.save_path
Locais comuns:
/var/lib/php/sessions
Veja a quantidade:
sudo find /var/lib/php/sessions -type f | wc -l
Ao limpar sessões antigas, não apague tudo diretamente. Você pode apagar primeiro as com mais de 7 dias:
sudo find /var/lib/php/sessions -type f -mtime +7 -delete
Se for um diretório de cache, também tente limpar por tempo:
sudo find /path/to/cache -type f -mtime +7 -delete
Se o diretório tiver uma quantidade enorme de arquivos, o próprio find também pode demorar muito. Recomenda-se executar em horário de baixo movimento e primeiro pré-visualizar com um comando sem -delete:
sudo find /path/to/cache -type f -mtime +7 | head
Apague somente depois de confirmar que não há problema.
O cache do APT normalmente não é a maior fonte de inodes, mas pode servir como limpeza auxiliar.
Veja o diretório de cache:
sudo du -sh /var/cache/apt
Limpe o cache de pacotes baixados:
sudo apt clean
Limpar dependências que não são mais necessárias exige mais cuidado:
sudo apt autoremove
autoremove pode remover pacotes dos quais você não depende mais explicitamente, mas que ainda são importantes nos seus cenários de uso. Antes de executar em uma máquina de produção, veja com atenção a lista do que será removido.
Se o site já não consegue gravar sessões, não consegue fazer upload e o banco de dados não consegue gravar, você pode estancar o sangramento nesta ordem:
df -iconfirmar se os inodes estão em 100%- Encontrar o diretório com mais inodes
- Priorizar a limpeza de arquivos temporários claros, caches e sessões antigas
- Se for Docker, primeiro usar
docker system df, depois decidir o escopo do prune - Se forem logs, priorizar
journalctl --vacuum-*e logrotate - Depois de limpar, executar
df -ipara verificar - Reiniciar ou fazer reload dos serviços afetados
Verificar:
df -i
touch /tmp/inode-test
rm /tmp/inode-test
systemctl --failed
Se os inodes caírem de 100% e touch funcionar, significa que o sistema de arquivos recuperou a capacidade de criar arquivos.
Prevenir é mais importante do que limpar depois.
Recomenda-se fazer o seguinte:
- Monitorar
df -i, não apenasdf -h - Definir
max-sizeemax-filepara os logs do Docker - Definir tempo ou tamanho de retenção para o journal do systemd
- Configurar bem o logrotate para evitar rotação infinita de logs
- Configurar limpeza periódica para session, cache, upload tmp
- Para negócios com especialmente muitos arquivos pequenos, não colocá-los todos no disco do sistema
- Limitar a quantidade de arquivos gravados em disco para programas de scraping, rastreadores e filas de tarefas
- Ao fazer backup, não faça backup apenas de arquivos grandes; também preste atenção à quantidade de arquivos pequenos
Se o negócio naturalmente produz uma grande quantidade de arquivos pequenos, como miniaturas de imagens, caches de rastreadores, filas de e-mail, fatias de objetos, você deve considerar:
- Montar um disco de dados separado
- Usar um sistema de arquivos mais adequado para certos cenários, como XFS
- Colocar objetos estáticos em armazenamento de objetos
- Colocar dados temporários em Redis / banco de dados / sistemas de fila
- Arquivar ou compactar periodicamente arquivos pequenos antigos
Quando você encontrar No space left on device mas df -h parecer que ainda tem espaço, verifique nesta ordem:
-
df -hver a capacidade -
df -iver os inodes -
touch /tmp/inode-testverificar se é possível criar arquivos -
findcontar qual diretório tem mais arquivos pequenos - Verificar PHP session, cache, Docker, journal, fila de e-mail
- Pré-visualizar antes de limpar, não fazer diretamente
rm -rf - Depois de limpar, executar novamente
df -i - reload/restart dos serviços afetados
- Adicionar monitoramento e políticas de retenção para inodes, logs, caches, logs do Docker
O cerne do problema de inode não é "o disco não é grande o suficiente", mas "a quantidade de arquivos está fora de controle". Quando você vir que ainda há espaço mas os arquivos não podem ser gravados, não fique apenas olhando para df -h; adicione imediatamente um df -i. Muitas falhas de gravação de VPS que parecem misteriosas têm a resposta aqui.