Tutoriales de VPS
El VPS muestra espacio libre en disco pero no puede escribir archivos (2026): cómo diagnosticar y limpiar el agotamiento de inodos
¿El VPS informa No space left on device, pero df -h claramente muestra espacio libre? Es probable que no sea la capacidad la que está llena, sino los inodos los que se agotaron. Este artículo explica la diferencia entre df -h y df -i, cómo localizar el origen de los archivos pequeños y cómo limpiar de forma segura archivos de Docker, journal, caché y sesión.

Hay un tipo de fallo de VPS que confunde con facilidad:
No space left on device
Tu primera reacción es que el disco está lleno, así que ejecutas:
df -h
Y descubres que la partición / solo está usada al 60%, así que claramente todavía hay espacio suficiente. Pero las subidas del sitio web fallan, la base de datos no puede escribir, la caché de Nginx da errores, la creación de sesiones PHP falla e incluso touch test.txt falla.
En este momento, lo que debes sospechar no es la capacidad del disco, sino los inodos.
En pocas palabras, el espacio en disco gobierna "cuánto contenido de archivos se puede almacenar", mientras que los inodos gobiernan "cuántos archivos se pueden crear". Si en el servidor se acumulan millones de archivos pequeños, puede que el espacio aún no se haya agotado, pero los inodos ya se hayan agotado. Linux seguirá informando No space left on device, porque para el sistema de archivos ya no tiene dónde registrar nuevos archivos.
Primero mira el espacio:
df -h
Luego mira los inodos:
df -i
df -h mira la capacidad, df -i mira los inodos. La documentación de GNU Coreutils para df también enumera -i / --inodes por separado como información de uso de inodos.
Puede que veas algo como esto:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/vda1 1310720 1310500 220 100% /
Esta situación es un caso típico de inodos casi agotados o ya agotados. En este punto, aunque df -h todavía tenga decenas de GB de espacio, puede que no se puedan crear nuevos archivos.
También puedes hacer una prueba segura:
touch /tmp/inode-test
Si esto también informa No space left on device mientras df -i muestra 100%, básicamente queda confirmado.
Los inodos normalmente no los consumen los archivos grandes, sino una gran cantidad de archivos pequeños.
Las fuentes comunes en un VPS incluyen:
- Archivos de sesión PHP
- Caché de Nginx / CDN / proxy inverso
- Archivos pequeños de Docker overlay2
- Cachés de npm, pip, composer
- Colas de correo
- Directorios temporales de subida
- Archivos pequeños generados por rastreadores, scraping, rotación de logs
- Aplicaciones que escriben cada petición, cada tarea, cada mensaje como un archivo independiente
Un archivo pequeño de 2 KB también ocupa un inodo. Un video grande de decenas de GB puede ocupar solo unos pocos inodos, pero millones de archivos de sesión pueden llenar los inodos rápidamente.
La operación más peligrosa ante un fallo de inodos es borrar directorios directamente sin saber quién está ocupando los inodos.
En particular, no borres a ciegas estas rutas:
/var/lib
/etc
/usr
/home
/var/lib/docker
Algunos directorios parecen grandes o contienen muchos archivos, pero dentro puede haber bases de datos, capas de Docker, estado del gestor de paquetes o datos de servicios en ejecución. Si borras lo incorrecto, el problema de inodos no se resuelve y el sistema se rompe primero.
El orden correcto es: primero localizar, luego limpiar; primero limpiar cachés y archivos temporales, luego considerar los datos de negocio.
Empieza a contar desde la partición raíz, mirando el número de archivos en cada nivel:
sudo find / -xdev -type f | cut -d/ -f2 | sort | uniq -c | sort -nr | head
Si /var es el que más tiene, mira más abajo:
sudo find /var -xdev -type f | cut -d/ -f2-3 | sort | uniq -c | sort -nr | head
Sigue desglosando:
sudo find /var -xdev -type f | cut -d/ -f2-4 | sort | uniq -c | sort -nr | head
La idea de este tipo de comandos no es mirar el tamaño de los archivos, sino el "número de archivos". Porque cuando los inodos se agotan por archivos pequeños, du -sh no necesariamente expone el problema rápidamente.
Si sospechas de un directorio concreto, como PHP session:
sudo find /var/lib/php/sessions -type f | wc -l
Si sospechas de Docker:
sudo find /var/lib/docker -xdev -type f | wc -l
Si sospechas de la caché de Nginx:
sudo find /var/cache/nginx -type f | wc -l
A veces ya has eliminado archivos, pero el espacio no se libera. La razón es que los procesos todavía tienen esos archivos abiertos.
Puedes revisar:
sudo lsof +L1
Este comando lista archivos con link count menor que 1, es decir, archivos ya eliminados del directorio pero aún retenidos por procesos. Se usa más a menudo para problemas de liberación de capacidad, pero también vale la pena echarle un vistazo al diagnosticar anomalías relacionadas con el disco.
Si encuentras un archivo de log retenido por un proceso, normalmente no mates el proceso directamente; primero determina el tipo de servicio. Para Nginx, PHP-FPM y servicios de aplicación, prioriza reload o restart:
sudo systemctl reload nginx
sudo systemctl restart php8.2-fpm
sudo systemctl restart app
Antes de reiniciar, confirma si es un servicio de producción, para evitar interrumpir el negocio sin querer.
Si el journal de systemd ocupa muchos archivos, primero mira su uso de disco:
journalctl --disk-usage
Para limpiar logs antiguos puedes usar los parámetros vacuum oficialmente soportados por systemd, por ejemplo conservar solo 7 días:
sudo journalctl --vacuum-time=7d
O limitar el tamaño total:
sudo journalctl --vacuum-size=500M
No entres directamente en /var/log/journal a borrar cosas a mano. journalctl --vacuum-* es una forma más segura y controlable.
Si notas que el journal suele crecer muy rápido, sigue preguntando: ¿hay algún servicio reportando errores sin parar? Puedes usar:
journalctl -p warning --since "24 hours ago" --no-pager
systemctl --failed
Limpiar logs solo detiene la hemorragia; lo que realmente hay que arreglar es el servicio que sigue inundando los logs.
Docker es un gran consumidor de inodos, especialmente con builds frecuentes, pulls frecuentes de imágenes, logs de contenedores sin límite y capas overlay2 acumuladas.
Primero mira el uso de Docker:
docker system df
Lista los contenedores:
docker ps -a
Antes de limpiar, confirma qué imágenes, contenedores y volúmenes todavía se necesitan. Un primer paso relativamente seguro es limpiar contenedores detenidos, redes no usadas, imágenes colgantes y build cache:
docker system prune
Si estás seguro de que las imágenes no usadas también se pueden borrar, entonces usa:
docker system prune -a
Nota: -a eliminará todas las imágenes que no estén siendo usadas actualmente por contenedores. Para entornos de producción, es mejor confirmar primero si el rollback del despliegue depende de imágenes antiguas.
No borres directamente /var/lib/docker/overlay2. Esto romperá el estado interno de Docker y puede impedir que los contenedores arranquen.
Una mejor forma de prevención es poner límites a los logs de los contenedores. Por ejemplo, configuración del daemon de Docker:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "3"
}
}
Después de cambiarlo, hay que reiniciar Docker:
sudo systemctl restart docker
Reiniciar Docker afecta a los contenedores, así que en producción hay que programar una ventana.
Si los inodos los consumen las sesiones PHP, primero confirma el directorio de sesiones:
php -i | grep session.save_path
Ubicaciones comunes:
/var/lib/php/sessions
Mira la cantidad:
sudo find /var/lib/php/sessions -type f | wc -l
Al limpiar sesiones antiguas, no borres todo directamente. Puedes borrar primero las de hace más de 7 días:
sudo find /var/lib/php/sessions -type f -mtime +7 -delete
Si es un directorio de caché, también intenta limpiar por tiempo:
sudo find /path/to/cache -type f -mtime +7 -delete
Si el directorio tiene una cantidad enorme de archivos, find en sí mismo también puede tardar mucho. Se recomienda ejecutarlo en horas de baja carga y primero previsualizar con un comando sin -delete:
sudo find /path/to/cache -type f -mtime +7 | head
Borra solo después de confirmar que no hay problema.
La caché de APT normalmente no es la mayor fuente de inodos, pero puede servir como limpieza auxiliar.
Ver el directorio de caché:
sudo du -sh /var/cache/apt
Limpiar la caché de paquetes descargados:
sudo apt clean
Limpiar dependencias que ya no se necesitan requiere más cuidado:
sudo apt autoremove
autoremove puede eliminar paquetes de los que ya no dependes explícitamente pero que siguen siendo importantes en tus escenarios de uso. Antes de ejecutarlo en una máquina de producción, revisa bien la lista de lo que se eliminará.
Si el sitio web ya no puede escribir sesiones, no puede subir archivos y la base de datos no puede escribir, puedes detener la hemorragia en este orden:
df -iconfirmar si los inodos están al 100%- Encontrar el directorio con más inodos
- Priorizar la limpieza de archivos temporales claros, cachés y sesiones antiguas
- Si es Docker, primero usar
docker system df, luego decidir el alcance del prune - Si son logs, priorizar
journalctl --vacuum-*y logrotate - Después de limpiar, ejecutar
df -ipara verificar - Reiniciar o hacer reload de los servicios afectados
Verificar:
df -i
touch /tmp/inode-test
rm /tmp/inode-test
systemctl --failed
Si los inodos bajan del 100% y touch tiene éxito, significa que el sistema de archivos ha recuperado la capacidad de crear archivos.
Prevenir es más importante que limpiar después.
Se recomienda hacer esto:
- Monitorizar
df -i, no solodf -h - Configurar
max-sizeymax-filepara los logs de Docker - Configurar tiempo o tamaño de retención para el journal de systemd
- Configurar bien logrotate para evitar rotación infinita de logs
- Configurar limpieza periódica para session, cache, upload tmp
- Para negocios con especialmente muchos archivos pequeños, no ponerlos todos en el disco del sistema
- Limitar la cantidad de archivos escritos a disco para programas de scraping, rastreadores y colas de tareas
- Al hacer copias de seguridad, no solo respaldes archivos grandes; también presta atención a la cantidad de archivos pequeños
Si el negocio produce de forma natural una gran cantidad de archivos pequeños, como miniaturas de imágenes, cachés de rastreadores, colas de correo, fragmentos de objetos, deberías considerar:
- Montar un disco de datos separado
- Usar un sistema de archivos más adecuado para ciertos escenarios, como XFS
- Poner objetos estáticos en almacenamiento de objetos
- Poner datos temporales en Redis / base de datos / sistemas de colas
- Archivar o comprimir periódicamente archivos pequeños antiguos
Cuando encuentres No space left on device pero df -h parezca que todavía tiene espacio, revisa en este orden:
-
df -hver la capacidad -
df -iver los inodos -
touch /tmp/inode-testverificar si se pueden crear archivos -
findcontar qué directorio tiene más archivos pequeños - Revisar PHP session, caché, Docker, journal, cola de correo
- Previsualizar antes de limpiar, no hacer directamente
rm -rf - Después de limpiar, ejecutar de nuevo
df -i - reload/restart de los servicios afectados
- Añadir monitorización y políticas de retención para inodos, logs, cachés, logs de Docker
El núcleo del problema de inodos no es "el disco no es lo bastante grande", sino "el número de archivos está fuera de control". Cuando veas que queda espacio pero no se pueden escribir archivos, no te quedes solo mirando df -h; añade de inmediato un df -i. Muchos fallos de escritura de VPS que parecen misteriosos tienen aquí su respuesta.