tech:backup

Бэкапы

Ежедневное локальное резервное копирование. Внешнего (offsite) копирования нет — см. «Что не сделано».

Путь Назначение
/usr/local/bin/ve-backup.sh скрипт бэкапа (chmod 700)
/etc/cron.d/ve-playground-backup расписание: ежедневно 03:20 UTC
/root/backups/ архивы (каталог chmod 700, файлы chmod 600)
/var/log/ve-backup.log лог выполнения
/etc/logrotate.d/ve-backup ротация лога: monthly, rotate 6

Права ужесточены осознанно: внутрь архивов попадают .env ToolMesh с секретами и приватные ключи сертификатов.

За один запуск создаются три файла с общей меткой времени <TS> формата ГГГГММДД-ЧЧММСС.

Файл Содержимое
app-data-<TS>.tar.gz /opt/ve-playground целиком: DokuWiki (страницы, медиа, ACL, пользователи), ToolMesh (.env, config, dadl, data), данные KeyDB
system-conf-<TS>.tar.gz /etc/nginx, /etc/letsencrypt, /etc/iptables, /etc/fail2ban, /etc/ssh/sshd_config
manifest-<TS>.txt версии образов, запущенные контейнеры, commit ToolMesh, sha256 DADL-файлов

Исключения из app-data: ToolMesh/.git и ToolMesh/data/blobs.

Манифест нужен именно для восстановления: он фиксирует, какие версии крутились на момент снятия. Без него после распаковки неизвестно, какой образ и какой commit собирать — принцип фиксации версий (см. tech) без этого не работает.

Перед архивацией выполняется keydb-cli bgsave — сброс снапшота KeyDB на диск. Если команда не отработала, бэкап продолжается: AOF (appendonly yes) всё равно лежит на диске.

RETENTION_DAYS=7. Файлы старше семи дней удаляются в конце каждого запуска, число удалённых пишется в лог.

Семь дней выбраны по наличию места: полный набор занимает около 6.6 МБ при диске 59 ГБ, занятом на ~7%.

/usr/local/bin/ve-backup.sh          # запуск вручную
cat /var/log/ve-backup.log           # результат
ls -lah /root/backups/               # что лежит

Состав архива без распаковки:

tar tzf /root/backups/app-data-<TS>.tar.gz | grep -E 'acl.auth.php|users.auth.php|ToolMesh/.env'
tar tzf /root/backups/app-data-<TS>.tar.gz | grep -c 'pages/'

Предупреждение tar об удалении ведущего слэша из имён — нормальное: пути сохраняются относительными, чтобы распаковка не затирала системные файлы вслепую.

Архивы лежат на том же диске, что и данные, которые они защищают. Это закрывает сценарий «удалили страницу, сбросились ACL», но не закрывает потерю диска и компрометацию сервера.

Нужно: выгрузка во внешнее хранилище отдельным шагом в конце скрипта — rclone в S3-совместимое, rsync на другой сервер, Storage Box.

Проверен только состав архивов. Полное развёртывание из бэкапа на чистой машине не прогонялось — то есть неизвестно, всё ли нужное попало и в каком порядке разворачивается.

DokuWiki файловая, вероятность поймать страницу в момент записи мала, но не нулевая. При необходимости можно добавить короткий stop/start контейнера dokuwiki на время архивации, с trap на гарантированный подъём.


← Техническая документация

  • tech/backup.txt
  • Last modified: 2026/07/29 08:12
  • by claude