Хостинг и Серверы 9 мин чтения 2026-08-27

Закончилось место на диске VDS (No space left on device): поиск пожирателей памяти и безопасная очистка Ubuntu / Debian

Практическое руководство по экстренному и плановому освобождению места на Linux VDS: поиск скрытых гигабайтов через ncdu, проверка переполнения дескрипторов inodes (df -i), очистка логов journald и Docker, удаление кэша APT и настройка автоочистки по расписанию.

Инженерная редакция SysKit Проверено инженерами SysKit.ru

Сообщение No space left on device — один из самых коварных ночных кошмаров вебмастера и системного администратора. Когда на виртуальном сервере (VDS) свободное дисковое пространство заполняется до 100%, последствия наступают мгновенно:

  • СУБД (MySQL / PostgreSQL) аварийно останавливается или блокирует таблицы на запись с ошибкой Can't create/write to file.
  • Веб-сервер Nginx перестает отдавать динамические страницы и возвращает ошибку 500 Internal Server Error или 502 Bad Gateway.
  • SSH-сессия перестает сохранять историю команд, а автодополнение (Tab completion) выдает ошибки создания временных файлов в /tmp.
  • Почтовые службы (Postfix/Exim) блокируют доставку входящих и исходящих писем.

В этой статье мы подробно разберем пошаговый алгоритм реанимации сервера: от экстренного поиска истинных причин нехватки места до глубокой очистки скрытого мусора (логов, Docker, старых ядер, MySQL binlog) и настройки автоматической профилактики по расписанию.

💡
Совет инженера: Если сервер переполнен настолько, что вы не можете даже создать временный файл или поставить утилиту, освободите 100–200 МБ за пару секунд безопасной командой усечения системных журналов: sudo journalctl --vacuum-size=50M. Это сразу вернет сервер к жизни и позволит спокойно продолжить диагностику.

1. Экстренная диагностика: df -h, переполнение Inodes и открытые удаленные файлы (lsof)

Первый шаг при падении сервера — понять, чем именно вызвано переполнение: физическими мегабайтами, исчерпанием файловых дескрипторов (Inodes) или зависшими процессами.

1.1. Проверка физического объема диска (df -h)

# Проверяем занятое пространство на всех смонтированных разделах
df -h

Обратите внимание на корневой раздел / (или /dev/vda1, /dev/sda1). Если в столбце Use% указано 100% — диск физически переполнен большими файлами.

1.2. Проверка файловых дескрипторов Inodes (df -i)

Типичная загадочная ситуация: команда df -h показывает 10–15 ГБ свободного места, но при попытке создать любой файл система выдает No space left on device. Причина — 100% исчерпание Inodes (индексных дескрипторов файлов).

# Проверяем количество свободных Inodes
df -i

В Linux каждый файл, каталог или сокет занимает один Inode. Если на сервере скопились миллионы крошечных файлов (старые сессии PHP, кэш мелких картинок, спам-очередь почты в /var/spool/postfix), таблица дескрипторов переполняется, даже если сам диск свободен на 90%.

1.3. Поиск удаленных, но удерживаемых процессов файлов (lsof + deleted)

Очень частая ошибка новичков: вы удалили огромный лог-файл командой rm -f /var/log/nginx/access.log, но df -h по-прежнему показывает 100% занятости. Почему так происходит?

В операционных системах Linux файл физически удаляется с диска только тогда, когда закрыты все его файловые дескрипторы. Если веб-сервер Nginx продолжает держать файл открытым, место на диске не освобождается до перезагрузки процесса.

# Находим процессы, удерживающие удаленные файлы
sudo lsof -nP | grep '(deleted)'

# Пример вывода:
# nginx   1420   www-data    3w   REG  253,1  8589934592  /var/log/nginx/access.log (deleted)

Чтобы мгновенно освободить место без перезагрузки всей ОС, достаточно перезапустить сервис, удерживающий файл:

# Мягкий перезапуск службы
sudo systemctl reload nginx
# или для PHP-FPM:
sudo systemctl reload php8.3-fpm

2. Визуальный поиск тяжелых папок через ncdu и du

Чтобы не гадать вслепую, воспользуемся лучшей интерактивной консольной утилитой анализа диска — ncdu (NCurses Disk Usage).

# Устанавливаем ncdu в Ubuntu / Debian
sudo apt update && sudo apt install -y ncdu

# Запускаем сканирование корневой директории
# Флаг -x запрещает утилите сканировать сетевые диски и виртуальные каталоги (/proc, /sys)
sudo ncdu / -x
🔍
Как работать в ncdu: Используйте стрелки и для перемещения по папкам, Enter для входа в директорию, n для сортировки по имени или размеру, и клавишу q для выхода. Клавиша d удаляет выбранный файл (используйте с предельной осторожностью!).

Если по какой-то причине установить ncdu невозможно, используйте встроенную команду du для поиска топ-10 самых тяжелых директорий:

# Поиск 10 самых объемных папок в корне
sudo du -ahx / | sort -rh | head -n 10

# Поиск 10 самых объемных папок внутри /var
sudo du -hx --max-depth=2 /var | sort -rh | head -n 10

3. Очистка и ограничение системных журналов systemd-journald

В современных дистрибутивах (Ubuntu 22.04 / 24.04 LTS, Debian 11 / 12) служба systemd-journald логирует все системные события в двоичном формате. По умолчанию в базовых настройках journald может съедать до 10% от общего объема диска (от 2 до 10 ГБ), что катастрофично для недорогих VDS.

# 1. Проверяем, сколько места сейчас занимают журналы journald
journalctl --disk-usage
# Пример вывода: Archived and active journals take up 4.8G in the file system.

# 2. Экстренно удаляем логи старше 3 дней
sudo journalctl --vacuum-time=3d

# 3. Или ограничиваем максимальный размер журналов 100 мегабайтами
sudo journalctl --vacuum-size=100M

Как ограничить размер journald навсегда:

Отредактируйте конфигурационный файл /etc/systemd/journald.conf:

[Journal]
# Задаем жесткий лимит на максимальный объем логов
SystemMaxUse=100M
SystemMaxFileSize=20M
MaxRetentionSec=1month

Примените настройки перезапуском службы:

sudo systemctl restart systemd-journald

4. Тотальная чистка Docker: контейнеры, образы, билдер-кэш и волюмы

Docker — абсолютный рекордсмен по незаметному пожиранию дискового пространства. Сборка образов, промежуточные слои (BuildKit Cache), остановленные контейнеры и JSON-логи накапливают гигабайты мусора за считанные недели.

# Смотрим детализированную статистику занятого пространства в Docker
docker system df

Вы увидите разбивку по категориям: Images (образы), Containers (контейнеры), Local Volumes (тома) и Build Cache (кэш сборщика).

4.1. Безопасная очистка неиспользуемых ресурсов

# Удаляем все остановленные контейнеры, висячие образы (dangling) и кэш сборки
docker system prune -f

# Глубокая очистка: удаление ВСЕХ неиспользуемых образов (а не только без тега)
docker system prune -a --volumes -f
⚠️
Внимание с флагом --volumes: Флаг --volumes удалит безымянные тома, не привязанные к активным контейнерам. Если вы храните базы данных в именованных томах, они останутся нетронутыми, но анонимные тома будут стерты.

4.2. Ограничение бесконечных логов Docker-контейнеров

По умолчанию Docker сохраняет стандартный вывод (stdout/stderr) контейнеров в формате JSON без ротации. Чтобы логи не раздувались до сотен гигабайт, создайте или дополните файл /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "20m",
    "max-file": "3"
  }
}

Перезапустите демон Docker для применения глобального правила:

sudo systemctl restart docker

5. Очистка кэша APT и удаление старых неиспользуемых ядер Linux

Каждый раз при выполнении apt install или apt upgrade пакетный менеджер загружает .deb архивы в директорию /var/cache/apt/archives/. Они остаются на диске навсегда, если их не чистить вручную.

# 1. Проверяем размер кэша пакетов APT
du -sh /var/cache/apt/archives

# 2. Полностью очищаем кэш загруженных пакетов
sudo apt clean

# 3. Удаляем старые пакеты, которые больше не требуются установленным программам
sudo apt autoclean

# 4. Удаляем старые ядра Linux и неиспользуемые зависимости
sudo apt autoremove --purge -y

5.1. Очистка кэша пакетов Snap (для Ubuntu)

Пакетный менеджер Snap по умолчанию сохраняет по 2–3 старые версии каждого приложения. Если у вас используется Snap, отключите хранение старых ревизий и удалите дубликаты:

# Задаем лимит сохранения только 2 последних версий пакетов
sudo snap set system refresh.retain=2

# Однострочник для удаления отключенных (disabled) ревизий snap
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do sudo snap remove "$snapname" --revision="$revision"; done

6. Очистка логов Nginx, сессий PHP и бинарных логов MySQL/MariaDB

Для веб-серверов и CMS (WordPress, Bitrix, OpenCart) основными источниками скрытого разрастания файлов выступают:

6.1. Логи Nginx / Apache и правильное усечение

Никогда не удаляйте активные файлы логов через rm. Используйте команду truncate, которая обнуляет размер файла, не разрывая файловый дескриптор:

# Безопасное обнуление файла лога до 0 байт
sudo truncate -s 0 /var/log/nginx/access.log
sudo truncate -s 0 /var/log/nginx/error.log

# Удаление старых сжатых архивов логов (.gz)
sudo find /var/log -type f -name "*.gz" -delete
sudo find /var/log -type f -name "*.1" -delete

Для автоматической ежедневной ротации используйте нашу готовую конфигурацию Logrotate для Nginx и PHP-FPM.

6.2. Очистка миллионов мелких сессий PHP (борьба за Inodes)

В некоторых конфигурациях PHP сборщик мусора (Garbage Collector) не успевает удалять старые сессии из /var/lib/php/sessions, из-за чего исчерпываются Inodes:

# Удаляем файлы сессий старше 7 дней
sudo find /var/lib/php/sessions -type f -cmin +10080 -delete

6.3. Удаление бинарных логов MySQL / MariaDB (binlog)

Бинарные логи репликации MySQL (binlog.000001, mysql-bin.*) в каталоге /var/lib/mysql могут занимать десятки гигабайт. Категорически запрещено удалять их через rm (это сломает индекс СУБД!).

Очистка выполняется строго через SQL-консоль:

-- Подключаемся к MySQL: mysql -u root -p
-- Удаляем все бинарные логи старше 3 дней:
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;

Чтобы логи автоматически удалялись в будущем, добавьте в секцию [mysqld] файла /etc/mysql/my.cnf параметр автоматического срока жизни логов (подробнее в нашем руководстве по тюнингу MySQL my.cnf):

# Хранить бинарные логи максимум 3 дня (259200 секунд)
binlog_expire_logs_seconds = 259200
max_binlog_size = 100M

7. Рекомендуемые VDS-провайдеры с гибким расширением NVMe

Если проект перерос объем диска даже после полной оптимизации, оптимальное решение — выбор надежного провайдера с быстрыми накопителями NVMe и возможностью добавления дискового пространства в 1 клик:

Рекомендуемые VDS-провайдеры

Отказоустойчивые сервера с быстрыми NVMe и каналом до 1 Гбит/с

Быстрые NVMe от 200 ₽
🔷

Selectel VPS / VDS

Сверхбыстрые серверы KVM на NVMe с бесплатными 3 ТБ трафика. Легкое масштабирование диска и подключение облачных хранилищ S3 в панели управления.

Конфигурация
от 1 vCPU / 1 GB RAM / 10 GB NVMe
Гибкое масштабирование

Timeweb Cloud

Мощные процессоры до 5.0 GHz, расширение дискового пространства без переустановки ОС, автоматические резервные копии и поминутная тарификация.

Конфигурация
от 1 vCPU / 2 GB RAM / 30 GB NVMe
Простота и стабильность
🟠

Beget VPS

Удобная фирменная панель управления сервером, установка Docker и любого веб-стека в 1 клик, русскоязычная техническая поддержка 24/7.

Конфигурация
от 1 vCPU / 2 GB RAM / 35 GB NVMe

8. Автоматизация: готовый bash-скрипт регулярной самоочистки по Cron

Чтобы не доводить сервер до аварийных ситуаций, настроим регулярную еженедельную профилактику. Создадим системный скрипт автоматической очистки.

Создайте исполняемый файл /usr/local/bin/syskit-disk-cleanup.sh:

#!/usr/bin/env bash
# ====================================================================
# SysKit.ru - Автоматический скрипт еженедельной очистки диска Linux
# ====================================================================

set -e

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Запуск регламентной очистки диска..."

# 1. Очистка кэша пакетов APT
apt-get -y clean > /dev/null 2>&1 || true
apt-get -y autoclean > /dev/null 2>&1 || true
apt-get -y autoremove --purge > /dev/null 2>&1 || true

# 2. Ограничение и ротация journald (оставляем последние 7 дней / до 100MB)
journalctl --vacuum-time=7d > /dev/null 2>&1 || true
journalctl --vacuum-size=100M > /dev/null 2>&1 || true

# 3. Удаление старых ротированных логов старше 14 дней в /var/log
find /var/log -type f -name "*.gz" -mtime +14 -delete > /dev/null 2>&1 || true
find /var/log -type f -name "*.1" -mtime +14 -delete > /dev/null 2>&1 || true

# 4. Очистка устаревших сессий PHP (старше 7 дней)
if [ -d "/var/lib/php/sessions" ]; then
    find /var/lib/php/sessions -type f -mtime +7 -delete > /dev/null 2>&1 || true
fi

# 5. Очистка Docker (если установлен и запущен)
if command -v docker >/dev/null 2>&1 && systemctl is-active --quiet docker; then
    docker system prune -f > /dev/null 2>&1 || true
fi

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Очистка успешно завершена. Свободно на диске: $(df -h / | awk 'NR==2 {print $4}')"

Установите права на выполнение:

sudo chmod +x /usr/local/bin/syskit-disk-cleanup.sh

Добавьте задание в системный планировщик Cron для запуска каждое воскресенье в 04:00 утра. Для быстрого составления расписания используйте наш Генератор Cron задач.

# Открываем crontab суперпользователя root
sudo crontab -e

# Добавляем строку запуска:
0 4 * * 0 /usr/local/bin/syskit-disk-cleanup.sh >> /var/log/syskit-cleanup.log 2>&1

9. Чек-лист безопасности: что категорически нельзя удалять

✅ Что можно безопасно чистить:

  • Кэш загруженных deb-пакетов (apt clean).
  • Системные логи journald через journalctl --vacuum-*.
  • Удаленные сжатые архивы логов *.gz старше 14 дней.
  • Неиспользуемые контейнеры и build-кэш Docker (docker system prune).
  • Старые удаленные сессии PHP в /var/lib/php/sessions.
  • Старые ядра Linux через apt autoremove --purge.

⚠️ Что категорически НЕЛЬЗЯ делать:

  • Удалять папку /var/log целиком: Многие сервисы не умеют самостоятельно создавать эту директорию и упадут при старте.
  • Удалять файлы СУБД (ibdata1, ib_logfile*): Прямое удаление файлов из /var/lib/mysql безвозвратно уничтожит базу данных InnoDB.
  • Удалять /tmp через rm -rf /tmp: Временная папка содержит сокеты процессов (например, mysql.sock).
  • Удалять активные логи через rm: Используйте только truncate -s 0 file.log, иначе память не освободится.

10. Резюме и выводы

Переполнение диска — штатная ситуация в жизни любого сервера, с которой регулярно сталкиваются как новички, так и опытные инженеры. Своевременный контроль через ncdu, ограничение аппетитов systemd-journald, ротация логов Nginx и регулярный docker prune позволяют комфортно работать даже на компактных тарифах с 10–20 ГБ диска.

Для генерации надежных паролей баз данных воспользуйтесь нашим Генератором паролей, а проверить доступность сетевых сервисов после перезагрузки можно через Сканер портов SysKit.

Нужен надежный сервер с быстрыми NVMe и запасом места?

Арендуйте производительный VDS с чистой KVM-виртуализацией и каналом 1 Гбит/с на Selectel всего от 200 ₽ в месяц.

Выбрать тариф VDS на Selectel →

Вопросы и ответы (FAQ)

Популярные вопросы вебмастеров и сисадминов по данной теме

Что делать, если df -h показывает свободное место, но система пишет 'No space left on device'?
Это указывает на 100% переполнение файловых дескрипторов (Inodes). Проверьте их состояние командой 'df -i'. Чаще всего виновниками являются миллионы мелких файлов сессий PHP в /var/lib/php/sessions или зависшие очереди писем в /var/spool/postfix.
Почему после удаления большого файла access.log через rm место на диске не освободилось?
В Linux файл окончательно удаляется только после закрытия всех открывших его процессов. Если Nginx продолжает писать в этот файл, место удерживается дескриптором. Проверьте 'lsof -nP | grep deleted' и выполните 'systemctl reload nginx'.
Безопасно ли удалять файлы из каталогов /tmp и /var/tmp?
Удалять папку /tmp целиком нельзя, так как в ней находятся сокеты работающих служб (например, mysql.sock). Безопасно удалять только старые временные файлы командой: find /tmp -type f -atime +7 -delete.
Как настроить оповещение в Telegram при заполнении диска выше 90%?
Напишите простой bash-скрипт, проверяющий вывод 'df / | awk 'NR==2 {print $5}' | tr -d %', и при значении > 90 отправляющий сообщение через Telegram Bot API c помощью curl. Добавьте его вызов в crontab каждые 30 минут.

Читайте также в блоге SysKit

Смежные руководства и полезные технические статьи