2026-07-31 12:41:28 +03:00
2026-07-31 12:41:28 +03:00
2026-07-31 12:40:04 +03:00

Safe Monthly Maintenance

Безопасное ежемесячное обслуживание Ubuntu/Debian одной командой.

Скрипт устанавливает systemd timer, обновляет пакеты без dist-upgrade, чистит безопасные кэши и журналы, проверяет состояние dpkg, свободное место и необходимость перезагрузки. Автоматическая перезагрузка, autoremove и очистка Docker выключены по умолчанию.

Проверено на Debian 12. Скрипт рассчитан на Ubuntu и Debian с systemd и APT. Перед массовым развертыванием проверьте его на одной тестовой VM.

Установка одной командой

Закрепленная версия:

curl -fsSL https://raw.githubusercontent.com/andrey271192/safe-monthly-maintenance/v1.0.2/install.sh | sudo bash -s -- --run-now

Команда:

  1. скачивает install.sh;
  2. устанавливает maintenance-скрипт и systemd units;
  3. включает ежемесячный timer;
  4. сразу выполняет первое обслуживание.

Установка без немедленного запуска:

curl -fsSL https://raw.githubusercontent.com/andrey271192/safe-monthly-maintenance/v1.0.2/install.sh | sudo bash

Если curl отсутствует:

wget -qO- https://raw.githubusercontent.com/andrey271192/safe-monthly-maintenance/v1.0.2/install.sh | sudo bash -s -- --run-now

Более безопасная установка с проверкой

Не запускайте неизвестный код от root вслепую. Скачайте, проверьте, затем выполните:

curl -fsSL https://raw.githubusercontent.com/andrey271192/safe-monthly-maintenance/v1.0.2/install.sh -o /tmp/install-safe-maintenance.sh
sha256sum /tmp/install-safe-maintenance.sh
less /tmp/install-safe-maintenance.sh
sudo bash /tmp/install-safe-maintenance.sh --run-now

SHA-256 версии v1.0.2:

247312aaca5eb5b40c8893edb065203b2e4f0121c47421d85b46f9ae46770367

Что устанавливается

Путь Назначение
/usr/local/sbin/safe-monthly-maintenance Основной maintenance-скрипт
/etc/default/safe-monthly-maintenance Настройки конкретной VM
/etc/systemd/system/safe-monthly-maintenance.service Одноразовый systemd service
/etc/systemd/system/safe-monthly-maintenance.timer Ежемесячный запуск
/var/backups/safe-monthly-maintenance/ Снимки списка пакетов

Повторный запуск installer обновляет скрипт и units, но сохраняет существующий файл настроек.

Расписание

Timer запускается первого числа каждого месяца в 03:00 с случайной задержкой до шести часов:

OnCalendar=*-*-01 03:00:00
RandomizedDelaySec=6h
Persistent=true

Случайная задержка уменьшает одновременную нагрузку на репозитории, если один installer установлен на много VM. Persistent=true выполняет пропущенный запуск после включения сервера.

Что делает обслуживание

1. Проверяет окружение

  • требует права root;
  • разрешает только Ubuntu/Debian и Debian-подобные системы;
  • использует flock, поэтому два запуска не идут одновременно;
  • использует ожидание APT-lock до 600 секунд;
  • повторяет сетевые обращения APT до трех раз.

2. Сохраняет список пакетов

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

dpkg --get-selections

Снимок записывается в /var/backups/safe-monthly-maintenance/. Снимки старше 120 дней удаляются. Это не полный rollback системы, но помогает восстановить состав пакетов.

3. Чистит только безопасные данные

  • systemd-tmpfiles --clean — применяет штатные политики очистки временных файлов;
  • logrotate — запускает штатную ротацию логов;
  • journalctl --vacuum-time=30d — удаляет старый journal;
  • journalctl --vacuum-size=500M — ограничивает размер journal;
  • apt-get autoclean — удаляет устаревшие package-файлы;
  • apt-get clean — очищает скачанный APT-кэш после обновления.

Скрипт не выполняет ручной rm -rf для /tmp, /var/log, Docker volumes или пользовательских каталогов.

4. Проверяет пакетную систему

dpkg --audit запускается до обновления. Если пакетная операция была прервана, обновление пропускается. Скрипт не пытается автоматически ремонтировать неоднозначное состояние.

После обновления выполняется:

apt-get check

5. Проверяет свободное место

Обновление пропускается, если:

  • на / осталось меньше 1 ГиБ;
  • на отдельном /boot осталось меньше 200 МиБ.

Порог можно изменить в конфигурации.

6. Обновляет пакеты

Используется:

apt-get -y \
  -o Dpkg::Options::=--force-confold \
  --with-new-pkgs \
  --no-remove \
  upgrade

Почему:

  • upgrade, не dist-upgrade/full-upgrade: пакеты не удаляются;
  • --with-new-pkgs: разрешает новые зависимости, включая новое ядро;
  • --no-remove: аварийно останавливает операцию, если APT захочет удалить пакет;
  • --force-confold: сохраняет локальные конфиги вместо тихой замены;
  • NEEDRESTART_MODE=l: показывает сервисы со старыми библиотеками, но не перезапускает все сервисы автоматически.

Пакетные maintainer scripts все равно могут перезапустить собственный сервис. Абсолютно гарантировать отсутствие краткого service interruption при системном обновлении невозможно.

7. Не удаляет зависимости автоматически

По умолчанию выполняется только dry-run:

apt-get --dry-run autoremove

Кандидаты попадают в журнал. Реальный autoremove включается только вручную через конфигурацию.

8. Не перезагружает сервер

Скрипт проверяет /var/run/reboot-required и сравнивает текущее ядро с /vmlinuz. При необходимости пишет:

REBOOT REQUIRED. Automatic reboot disabled.

Решение о reboot остается у администратора.

9. Показывает итог

В конце журнал содержит:

  • failed systemd units;
  • использование диска;
  • необходимость reboot;
  • успешные и неуспешные этапы.

Настройка

Файл:

sudo nano /etc/default/safe-monthly-maintenance

Параметры:

Параметр По умолчанию Значение
ENABLE_AUTOREMOVE 0 1 разрешает apt-get autoremove --purge
ENABLE_DOCKER_PRUNE 0 1 удаляет только dangling Docker images
JOURNAL_MAX_AGE 30d Максимальный возраст systemd journal
JOURNAL_MAX_SIZE 500M Максимальный размер journal
MIN_ROOT_FREE_KB 1048576 Минимум свободного места на /
MIN_BOOT_FREE_KB 204800 Минимум на отдельном /boot

Для серверов с важными stopped-контейнерами и локальными Docker-образами оставляйте ENABLE_DOCKER_PRUNE=0.

Управление

Следующий запуск:

systemctl list-timers safe-monthly-maintenance.timer --all

Запустить вручную:

sudo systemctl start safe-monthly-maintenance.service

Последний статус:

systemctl status safe-monthly-maintenance.service

Логи:

journalctl -u safe-monthly-maintenance.service

Логи текущего запуска:

journalctl -u safe-monthly-maintenance.service --since today

Отключить автоматический запуск:

sudo systemctl disable --now safe-monthly-maintenance.timer

Удалить:

sudo systemctl disable --now safe-monthly-maintenance.timer
sudo rm -f /etc/systemd/system/safe-monthly-maintenance.timer
sudo rm -f /etc/systemd/system/safe-monthly-maintenance.service
sudo rm -f /usr/local/sbin/safe-monthly-maintenance
sudo systemctl daemon-reload

Конфигурация и package snapshots при удалении сохраняются намеренно.

Массовое развертывание

Пример с локальным списком серверов:

for host in vm1.example.com vm2.example.com vm3.example.com; do
  ssh "$host" \
    'curl -fsSL https://raw.githubusercontent.com/andrey271192/safe-monthly-maintenance/v1.0.2/install.sh | sudo bash -s -- --run-now'
done

Сначала используйте одну тестовую VM. Для большой инфраструктуры лучше Ansible, Salt или другой configuration-management инструмент.

Ограничения

  • Скрипт не делает filesystem/provider snapshot.
  • Скрипт не исправляет сломанный dpkg автоматически.
  • Скрипт не обновляет Ubuntu/Debian между major releases.
  • Скрипт не управляет сторонними package managers.
  • Скрипт не гарантирует отсутствие service restart от maintainer scripts.
  • Скрипт не заменяет мониторинг, резервные копии и тестирование обновлений.

Подробная модель безопасности: docs/SAFETY.md.

Лицензия

MIT

Description
Safe monthly maintenance for Ubuntu and Debian: conservative APT upgrades, cleanup, logging, and systemd timer.
Readme MIT 38 KiB
Languages
Shell 100%