Если в логах всплывает systemd-tmpfiles рядом с /tmp или /var/tmp и фразой No space left on device, обычно «сломался не systemd», а закончилось место, inode или лимит временной файловой системы. Дальше запускается цепочка неприятностей: не создаются сокеты, падают сборки, не ставятся пакеты, отваливаются деплои, а часть сервисов вообще не стартует.
Ниже — практичный разбор: как определить, что именно закончилось (гигабайты, inode, tmpfs), как безопасно освободить ресурс «прямо сейчас» и как настроить tmpfiles.d, чтобы проблема не возвращалась.
Что делает systemd-tmpfiles и почему он трогает /tmp и /var/tmp
systemd-tmpfiles — механизм systemd для создания и очистки файлов и каталогов по правилам из tmpfiles.d. Он работает как при ручном запуске (например, systemd-tmpfiles --clean), так и по расписанию через systemd unit’ы.
Каталоги /tmp и /var/tmp обычно чистятся по возрасту: /tmp — агрессивнее, /var/tmp — мягче (по смыслу это «временное, которое может пережить ребут»).
А вот No space left on device в контексте tmpfiles означает: в момент операции (сканирование, создание служебного файла, запись состояния, попытка атомарной замены) файловая система отказала из‑за нехватки ресурса.
Чек-лист: «место закончилось» — это не всегда про гигабайты
Прежде чем удалять «всё подряд», определите тип нехватки: место, inode, tmpfs-лимит или что-то локальное (квоты/контейнеры).
1) Закончились блоки (обычное место на диске)
df -h /tmp /var/tmp
df -h
Смотрите конкретные точки монтирования: /tmp нередко отдельный tmpfs или отдельный раздел.
2) Закончились inode (место есть, но файлы создавать нельзя)
df -ih /tmp /var/tmp
df -ih
Если IUse% около 100% — проблема в «миллионе мелких файлов» (сборки, распаковки, временные кеши, очереди задач).
3) /tmp — это tmpfs (RAM) и он переполнен
findmnt /tmp
mount | grep -E ' on /tmp '
Если это tmpfs, «место на диске» тут не при чём: упёрлись в лимит tmpfs (часто доля RAM).
4) Reserved blocks (чаще ext4) и запись не-root
На ext4 часть блоков зарезервирована для root. Обычно это не про отдельный /tmp, но если /tmp на общем разделе, а пишут не-root процессы, эффекты могут выглядеть «как будто место есть, но писать нельзя».
df -h /
sudo tune2fs -l /dev/vda1 | grep -E 'Reserved block count|Block count|Block size'
Не «обнуляйте резервы» на проде ради красивого df. Резерв часто нужен, чтобы система могла дышать и логироваться при заполнении диска.
5) Квоты, контейнеры, локальные лимиты
В контейнере или при включённых квотах место может закончиться «локально», даже если на хосте всё выглядит нормально. Для быстрой проверки состояния очистки:
systemctl status systemd-tmpfiles-clean.service
systemctl status systemd-tmpfiles-clean.timer
journalctl -u systemd-tmpfiles-clean.service -b --no-pager

Быстрая диагностика: что именно раздувает /tmp и /var/tmp
Когда место уже «на нуле», задача — быстро найти виновника, освободить хотя бы немного ресурса и только потом аккуратно нормализовать политику очистки.
Топ по занимаемому месту (простая и понятная база)
sudo du -xhd1 /tmp 2>/dev/null | sort -h
sudo du -xhd1 /var/tmp 2>/dev/null | sort -h
Ключ -x спасает от «проваливания» в примонтированные точки внутри дерева.
Топ по количеству файлов (когда упёрлись в inode)
sudo find /tmp -xdev -type f 2>/dev/null | wc -l
sudo find /var/tmp -xdev -type f 2>/dev/null | wc -l
Если нужно понять, какой каталог плодит больше всего файлов на верхнем уровне:
sudo find /tmp -xdev -mindepth 1 -maxdepth 1 -type d -print 2>/dev/null | while read -r d; do echo "$(sudo find "$d" -xdev -type f 2>/dev/null | wc -l) $d"; done | sort -n
Да, на миллионах файлов это может быть небыстро, но часто хватает, чтобы увидеть «один подозрительный каталог» и копать уже туда.
Проверьте «удалён, но место не освободилось» (open deleted)
Классика: файл удалили, но процесс держит дескриптор. Место не освобождается, пока процесс не закроет файл (часто помогает restart/reload конкретного сервиса).
sudo lsof +L1 | grep -E '(/tmp|/var/tmp)' | head
sudo lsof +L1 | wc -l
Как безопасно очистить /tmp и /var/tmp прямо сейчас
Главное правило: не удаляйте «всё» в живой системе, если не понимаете, что там происходит. В /tmp могут лежать сокеты, lock-файлы и временные результаты активных операций.
Вариант 1: запустить штатную очистку tmpfiles
Самый правильный путь — применить системную политику, а не придумывать свою на ходу:
sudo systemd-tmpfiles --clean
И сразу посмотреть, не падает ли очистка и что именно она делала:
journalctl -u systemd-tmpfiles-clean.service -b --no-pager
Вариант 2: адресная очистка по возрасту (когда надо «вот прямо сейчас»)
Когда сервисы падают из-за нехватки места, иногда нужно быстро освободить ресурс, удалив очевидно старое. Например, удалить файлы старше 2 дней из /tmp:
sudo find /tmp -xdev -type f -mtime +2 -print -delete
Для /var/tmp обычно выбирают больший срок (например, 10–30 дней):
sudo find /var/tmp -xdev -type f -mtime +10 -print -delete
Если проблема именно в inode, удаление «многих мелких» файлов обычно даст эффект быстрее, чем попытка найти один большой.
Вариант 3: починить первопричину (куда приложение пишет временное)
Частые генераторы мусора: CI/CD раннеры и сборки (npm/composer/pip/cargo), распаковки архивов, конвертация медиа, массовые экспорты/импорты.
Если это ваш сервис или ваш деплой-пайплайн, безопаснее вынести тяжёлое временное в управляемый каталог (например, в /var/tmp/appname или /srv/tmp) и задать ему понятные правила очистки. Для проектов на VDS это особенно актуально: у временных операций должен быть предсказуемый потолок, иначе один «жирный» билд выдавит всё остальное.
Почему systemd-tmpfiles «не спасает»: типовые причины
Таймер отключён или не запускается
systemctl status systemd-tmpfiles-clean.timer
systemctl list-timers --all | grep tmpfiles
Если таймер выключен, регулярной очистки не будет. Причины обычно банальные: ручные изменения, минимальные образы, неудачные hardening-настройки.
Правила очистки не подходят под вашу нагрузку
Сроки по умолчанию могут быть слишком длинными для небольшого диска или слишком короткими для «долгих» задач. Если у вас специфичная нагрузка (например, сборки в /var/tmp), придётся уточнить политику через tmpfiles.d.
Если параллельно занимаетесь усилением изоляции сервисов, полезно свериться с практиками sandboxing: hardening systemd-сервисов на VDS.
Неправильный mount для /tmp
Если /tmp на tmpfs, тяжёлые операции (распаковка больших архивов, сборка, конвертация) могут забить RAM быстрее, чем вы успеете среагировать. Тогда решение одно из:
- увеличить лимит tmpfs (осторожно, это память);
- перенести временные файлы тяжёлых задач на диск (в
/var/tmpили отдельный путь приложения); - выделить отдельный раздел/том под временное.

Где лежат правила tmpfiles и как понять, что применяется к /tmp и /var/tmp
Правила tmpfiles обычно лежат в нескольких местах (зависит от дистрибутива):
/usr/lib/tmpfiles.d/или/lib/tmpfiles.d/— правила пакетов (лучше не править вручную);/etc/tmpfiles.d/— ваши локальные правила и оверрайды;/run/tmpfiles.d/— временные правила на время загрузки (редко нужно руками).
Посмотреть, что есть в системе:
ls -la /etc/tmpfiles.d
ls -la /usr/lib/tmpfiles.d 2>/dev/null
ls -la /lib/tmpfiles.d 2>/dev/null
Найти правила именно для /tmp и /var/tmp
grep -R " /tmp" -n /etc/tmpfiles.d /usr/lib/tmpfiles.d /lib/tmpfiles.d 2>/dev/null
grep -R " /var/tmp" -n /etc/tmpfiles.d /usr/lib/tmpfiles.d /lib/tmpfiles.d 2>/dev/null
Дальше читаем найденные строки: там будет тип правила и возраст/условия очистки.
Настройка: свои правила в /etc/tmpfiles.d для /tmp и /var/tmp
Корректный подход: не редактировать файлы пакетов, а создать свой файл в /etc/tmpfiles.d и переопределить политику под вашу нагрузку.
Пример: файл /etc/tmpfiles.d/fastfox-tmp.conf с более агрессивной очисткой /tmp и более мягкой для /var/tmp:
sudo tee /etc/tmpfiles.d/fastfox-tmp.conf > /dev/null <<'EOF'
# Type Path Mode UID GID Age Argument
q /tmp 1777 root root 2d -
q /var/tmp 1777 root root 14d -
EOF
Тип записи q означает очистку содержимого каталога по возрасту. Набор типов и нюансы зависят от версии systemd, поэтому на конкретной системе всегда перепроверьте:
man tmpfiles.d
Применить и протестировать:
sudo systemd-tmpfiles --clean
sudo systemd-tmpfiles --create
Как не удалить нужное: стратегия исключений
Лучшее «исключение» — не хранить важное в /tmp и /var/tmp. Если приложению нужно долгоживущее хранилище, дайте ему нормальный путь в /var/lib или /srv, а временное направьте в управляемый каталог через переменную TMPDIR или настройку приложения.
Профилактика: чтобы No space left on device не возвращалась
1) Следите за tmpfs и реальной нагрузкой
df -h /tmp
findmnt -no OPTIONS /tmp
Если задачи регулярно требуют много места, переносите временные файлы на диск или увеличивайте tmpfs осознанно (иначе можно получить OOM вместо «просто переполненного /tmp»).
2) Мониторинг: /tmp отдельно и inode отдельно
Частая ошибка — мониторить только / по гигабайтам. А /tmp может быть отдельным mount, а inode заканчиваются независимо от свободных блоков.
- Алерты по заполнению
/tmpи/var/tmp, если это отдельные точки монтирования. - Алерты по inode (
df -i) на соответствующих разделах. - Периодическая проверка
lsof +L1на большие(deleted)(хотя бы вручную при инцидентах).
3) Разведите «временное» по назначению
Для сборок, конвертаций и импортов полезно выделить отдельный каталог (например, /var/tmp/build или /srv/tmp), задать ему отдельные правила очистки и ограничить рост организационно (лимитами в приложении, квотами, расписанием задач).
Если вы активно используете Nginx и у вас «временное» разрастается не только в /tmp, но и в temp-каталогах Nginx, загляните в разбор: куда Nginx пишет временные файлы и как выбрать tmpfs или диск.
Практический сценарий: если ошибка уже ломает сервисы
Проверьте, что именно закончилось:
df -hиdf -ihдля/tmpи/var/tmp.Найдите источник:
du -xhd1, при необходимости — подсчёт файлов черезfind ... | wc -l.Освободите место адресно: удалите старые файлы по возрасту или конкретный мусорный каталог.
Проверьте
lsof +L1на «удалённые, но занятые» файлы и перезапустите процесс, который удерживает их.Запустите
systemd-tmpfiles --cleanи убедитесь, что таймер включён.Настройте свои правила в
/etc/tmpfiles.d, чтобы политика соответствовала вашей нагрузке.
Частые вопросы и подводные камни
Можно ли просто сделать cron на очистку /tmp?
Можно, но на systemd-системах логичнее использовать tmpfiles.d и штатные таймеры: политика будет прозрачной, воспроизводимой и совместимой с дистрибутивом. Cron оставляйте для нестандартных кейсов (например, чистка специфичных директорий приложения).
Почему tmpfiles не удалил файлы, хотя они старые?
Чаще всего: правило не подходит под путь, файл попал под исключение, файл лежит в примонтированном подкаталоге, или сама очистка не запускалась/падала. Начните с journalctl по сервису очистки и поиска правил через grep в tmpfiles.d.
Насколько безопасно чистить /var/tmp?
/var/tmp часто используют для «временного, переживающего ребут». Агрессивная очистка может сломать редкие или долгие фоновые операции. Подбирайте срок по реальной динамике: если раз в неделю там появляется 30 ГБ мусора, политика «14 дней» может быть слишком мягкой.
Итог
Ошибка systemd-tmpfiles с /tmp, /var/tmp и No space left on device — сигнал, что временные каталоги стали «боевыми» и требуют дисциплины как логи или бэкапы. Быстро определите тип нехватки (место, inode, tmpfs), освободите ресурс безопасно, проверьте таймер и настройте tmpfiles.d под вашу нагрузку — тогда очистка станет профилактикой, а не ночным инцидентом.


