Резервное копирование и восстановление
Эта инструкция для администратора, который хочет регулярно сохранять Portal и уметь вернуть его после сбоя.
Читайте сверху вниз. На каждом шаге — куда нажать в админке (или какую команду ввести) и что должно получиться.
Кратко про службу в каталоге: portal-backup.
0. Что вы получите в итоге
Заголовок раздела «0. Что вы получите в итоге»После настройки:
- На диске (или NAS) появляются файлы
portal-backup-*.tar.gz. - В админке виден журнал: проверка пути, копии, восстановления.
- Бейдж Runner online — зелёный, когда процесс бэкапа на связи.
- Можно включить ночное расписание или создать копию кнопкой.
1. Что обязательно сохранять
Заголовок раздела «1. Что обязательно сохранять»| Данные | Где лежат | Нужно ли |
|---|---|---|
| База PostgreSQL | БД portal | Обязательно |
| Файлы библиотек | S3 bucket portal-files | Обязательно |
Лицензия (license.key, install.id) | каталог PORTAL_DATA_DIR | Рекомендуется |
| Конфигурация | .env / portal.env / Helm values | Рекомендуется |
| Valkey (кэш) | кэш | Не обязательно — пересоздаётся |
2. Как это устроено (простыми словами)
Заголовок раздела «2. Как это устроено (простыми словами)»| Часть | Роль |
|---|---|
| Служба Резервное копирование в админке | Разрешает очередь и расписание. Сама архив не пишет |
| Процесс backup-runner | Раз в ~30 с спрашивает API, делает pg_dump, копирует S3, упаковывает .tar.gz |
| Runner online | Heartbeat за последние ~2 минуты (это не то же самое, что «служба включена») |
| Журнал на странице | Записи validate, backup, restore |
В Docker runner обычно поднимается вместе со стеком:
docker compose up -ddocker compose ps backup-runnerdocker compose logs -f backup-runnerОжидание: контейнер в статусе Up / running. Runner ходит к API через host.docker.internal (Linux Docker Engine 20.10+ и Docker Desktop).
3. Каталог для бэкапов — самый важный момент
Заголовок раздела «3. Каталог для бэкапов — самый важный момент»Файлы появляются на хосте только если каталог смонтирован в контейнер backup-runner.
В .env задают пару:
| Переменная | Значение |
|---|---|
PORTAL_BACKUP_HOST_DIR | Каталог на хосте (левая часть тома) |
PORTAL_BACKUP_MOUNT_PATH | Путь внутри контейнера (правая часть тома) |
В админке указывают ровно PORTAL_BACKUP_MOUNT_PATH (без / в конце). Другой путь backend и runner отклонят.
Примеры
Заголовок раздела «Примеры»Прод на Linux:
PORTAL_BACKUP_HOST_DIR=/var/backups/portalPORTAL_BACKUP_MOUNT_PATH=/var/backups/portalВ админке: /var/backups/portal.
Dev рядом с compose:
# по умолчанию можно не задавать# PORTAL_BACKUP_HOST_DIR=./backups# PORTAL_BACKUP_MOUNT_PATH=/backupsВ админке: /backups. На хосте файлы появятся в ./backups.
Dev на Mac (отдельная папка):
PORTAL_BACKUP_HOST_DIR=/path/on/mac/BackupPortalPORTAL_BACKUP_MOUNT_PATH=/path/on/mac/BackupPortalОба значения — один и тот же абсолютный путь. После правки .env:
docker compose up -d backup-runner backendЧастая ошибка: в админке указали путь Mac/Linux хоста, а в compose смонтирован другой каталог (например
./backups→/backups). Журнал покажет «Завершён», но в нужной папке на хосте файла не будет — он останется внутри контейнера.
4. Бэкап из админки — по шагам
Заголовок раздела «4. Бэкап из админки — по шагам»Страница: Админка → Службы → Резервное копирование → ⚙ Настройки
Адрес: /services/portal-backup.
Два аккордеона:
| Аккордеон | Что внутри |
|---|---|
| Резервное копирование | Путь, сколько копий хранить, проверка записи, создание копии, журнал, Runner online |
| Восстановление | Список успешных копий и постановка restore в очередь |
Бейдж Runner online — на этой странице и в Обзор → Обслуживание, не в таблице «Службы».
Шаг 4.1. Откройте страницу
Заголовок раздела «Шаг 4.1. Откройте страницу»- Войдите как администратор.
- Перейдите на
/services/portal-backup. - Должны увидеть два аккордеона и журнал.
Шаг 4.2. Укажите путь и сохраните
Заголовок раздела «Шаг 4.2. Укажите путь и сохраните»- В блоке Резервное копирование введите каталог.
- В Docker — точно значение
PORTAL_BACKUP_MOUNT_PATH. - Сохраните.
Шаг 4.3. Проверьте запись
Заголовок раздела «Шаг 4.3. Проверьте запись»- Нажмите Проверить запись (задание
validate). - Файл
.tar.gzпри этом не создаётся — только проверка, что путь доступен для записи. - В журнале статус должен стать Завершён.
Шаг 4.4. Дождитесь Runner online
Заголовок раздела «Шаг 4.4. Дождитесь Runner online»- Посмотрите бейдж Backup runner: Online.
- Если Offline — см. §8. Обычно помогает
docker compose up -d backup-runner.
Шаг 4.5. Создайте копию
Заголовок раздела «Шаг 4.5. Создайте копию»- Нажмите Создать резервную копию.
- Появится тост об постановке в очередь.
- В журнале — запись
backup: В очереди → Выполняется → Завершён. - На диске (в
HOST_DIR) появитсяportal-backup-*.tar.gz.
Обновляйте журнал (пагинация), пока статус не финальный.
Шаг 4.6. Включите расписание (по желанию)
Заголовок раздела «Шаг 4.6. Включите расписание (по желанию)»- Админка → Службы.
- Строка Резервное копирование → ⋮ → Расписание.
- Включите автозапуск и задайте время (после успешного validate и online runner).
Статусы журнала
Заголовок раздела «Статусы журнала»| Статус | Значение |
|---|---|
| В очереди | Ждёт runner |
| Выполняется | Runner взял задание |
| Завершён | Успех |
| Ошибка | Runner сообщил сбой или задание зависло > 30 мин |
5. Быстрый бэкап с хоста (portal-cli)
Заголовок раздела «5. Быстрый бэкап с хоста (portal-cli)»Архивы пишутся сразу на диск, без очереди админки:
# Docker-бандл./portal-cli/portal-cli backup --mode docker --output /mnt/nas/portal-backups
# Native./portal-cli/portal-cli backup --mode native --output /var/backups/portal
# Kubernetes./portal-cli/portal-cli backup --mode k8s --output /mnt/nas/portal-backupsПроверка каталога:
./portal-cli/portal-cli backup validate --path /mnt/nas/portal-backups6. Восстановление из админки — по шагам
Заголовок раздела «6. Восстановление из админки — по шагам»Аккордеон Восстановление на /services/portal-backup.
Внимание: восстановление — деструктивная операция. На время работы портал недоступен. Нужны Runner online и отсутствие активного backup/restore.
- Откройте аккордеон Восстановление.
- В списке — успешные копии с файлом на диске (до 50 шт.).
- Выберите копию → подтвердите в модальном окне.
- Задание
restoreпопадёт в очередь; runner выполнит восстановление. - Дождитесь статуса Завершён в журнале и проверьте вход на портал.
Восстановление вручную на хосте:
./portal-cli/portal-cli restore --mode docker \ --file /mnt/nas/portal-backups/portal-backup-20260710-120000.tar.gz --yesAPI: Резервное копирование (API).
7. Сетевое хранилище (SMB/NFS)
Заголовок раздела «7. Сетевое хранилище (SMB/NFS)»Portal сам шары не монтирует. Сначала смонтируйте NAS на сервере, затем укажите этот путь в .env и в админке.
Пример Linux:
sudo mkdir -p /mnt/nas/portal-backupssudo mount -t cifs //nas.corp/backups/portal /mnt/nas/portal-backups \ -o credentials=/etc/portal/nas.creds,uid=0,gid=0Затем PORTAL_BACKUP_HOST_DIR / PORTAL_BACKUP_MOUNT_PATH и путь в админке — на этот каталог.
8. Диагностика
Заголовок раздела «8. Диагностика»Журнал долго «Выполняется»
Заголовок раздела «Журнал долго «Выполняется»»- Смотрите логи runner — главный источник:
docker compose logs -f backup-runner- Запись в БД:
docker compose exec postgres psql -U portal -d portal -c \ "SELECT id, kind, status, started_at, error_message FROM portal_backups ORDER BY created_at DESC LIMIT 5;"-
Задания в
runningдольше 30 минут backend переводит в Ошибка. -
Ручной сброс зависшей записи (только если понимаете, что делаете):
UPDATE portal_backups SET status = 'failed', error_message = 'Сброс вручную', completed_at = NOW()WHERE id = '<uuid>' AND status = 'running';«Завершён», но файла нет на диске
Заголовок раздела ««Завершён», но файла нет на диске»- Сверьте путь в админке с
PORTAL_BACKUP_MOUNT_PATH. - Проверьте том:
docker inspect portal-backup-runner-1 --format '{{json .Mounts}}'. - Смотрите файлы в HOST_DIR на хосте, а не только путь «внутри» контейнера.
Runner offline
Заголовок раздела «Runner offline»docker compose ps backup-runnerdocker compose up -d backup-runnerdocker compose logs --tail 20 backup-runnerПосле старта бейдж Online обычно появляется в течение ~30 секунд.
9. Формат архива
Заголовок раздела «9. Формат архива»portal-backup-YYYYMMDD-HHMMSS.tar.gz├── manifest.json├── checksums.sha256├── postgres.dump├── s3/portal-files/...├── portal-data/...└── config/...10. Переменные окружения
Заголовок раздела «10. Переменные окружения»| Переменная | Назначение |
|---|---|
PORTAL_BACKUP_DIR | Каталог по умолчанию для portal-cli backup |
PORTAL_BACKUP_HOST_DIR | Каталог на хосте для тома runner |
PORTAL_BACKUP_MOUNT_PATH | Путь внутри контейнера (= путь в админке) |
PORTAL_BACKUP_RETENTION_COUNT | Сколько последних .tar.gz хранить (по умолчанию 7) |
PORTAL_BACKUP_RUNNER_TOKEN | Токен X-Portal-Backup-Token для internal API |
PORTAL_BACKUP_API_URL | URL API для runner (в compose часто через host.docker.internal) |
Ручной запуск runner:
./portal-cli/portal-cli backup-runnersudo systemctl enable --now portal-backup-runner # native Linuxdocker compose up -d backup-runner # dockerВ Docker Compose runner ходит к Docker через сервис docker-socket-proxy-backup, а не монтирует /var/run/docker.sock напрямую.
11. Ручные команды (низкий уровень)
Заголовок раздела «11. Ручные команды (низкий уровень)»Только если нужен частичный снимок без полного архива Portal.
PostgreSQL:
# Dockerdocker compose exec postgres pg_dump -U portal -Fc portal > portal-backup.dump
# Nativepg_dump -h localhost -U portal -Fc portal > portal-backup.dumpS3 (пример с клиентом MinIO):
mc mirror portal/portal-files ./backup/portal-files/12. Бэкап перед обновлением
Заголовок раздела «12. Бэкап перед обновлением»- Сделайте копию: кнопка в админке или
portal-cli backup --output <каталог>. - Обновите:
portal-cli upgrade --mode <канал>(см. Обновление). - Проверьте
/healthи/api/v1/system/version. - При проблемах:
portal-cli restore --file <архив> --yes.
13. Ориентиры RPO / RTO
Заголовок раздела «13. Ориентиры RPO / RTO»- RPO — сколько данных допустимо потерять при сбое.
- RTO — сколько времени допустимо на восстановление.
| Профиль | RPO | RTO |
|---|---|---|
| Пилот | 24 ч | 4 ч |
| Production | 1 ч | 1 ч |
| Enterprise | 15 мин | 30 мин |
Настройте Расписание службы в админке или таймер ОС для portal-cli backup под свой профиль.