Бэкап и восстановление Homepage
Homepage (gethomepage.dev) хранит весь дашборд в паре YAML-файлов и иконках — казалось бы, что там бэкапить. Но именно из-за этой простоты про бэкап забывают: сервер переезжает, диск сыпется, кто-то случайно перезаписывает services.yaml — и вы час восстанавливаете список из 40 виджетов по памяти. Ниже — как настроить бэкап конфигурации Homepage так, чтобы восстановление занимало пять минут, а не вечер.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что нужно бэкапить в Homepage
Homepage — это не база данных и не приложение с состоянием пользователей. Всё, что определяет дашборд, лежит в каталоге конфигурации, который вы монтируете в контейнер как volume. Типовая структура:
config/
├── settings.yaml # тема, layout, язык, заголовок
├── services.yaml # карточки сервисов, группы, ссылки
├── widgets.yaml # виджеты в шапке (погода, ресурсы, поиск)
├── bookmarks.yaml # закладки
├── docker.yaml # подключения к Docker-сокетам/API
├── kubernetes.yaml # если используете k8s-интеграцию
├── proxmox.yaml # если подключён Proxmox
├── custom.css # кастомные стили
├── custom.js # кастомный JS
├── logs/ # служебные логи, бэкапить не нужно
└── icons/ # если используете свои иконки, а не dashboard-icons
Важный нюанс: docker.yaml и другие файлы интеграций часто содержат креды — токены API, пароли basic-auth, ключи Proxmox. Это конфиденциальные данные не меньше, чем база пользователей, поэтому бэкап должен быть либо зашифрован, либо лежать в приватном хранилище с ограниченным доступом. Каталог logs/ в бэкап включать не нужно — это просто раздувает архив.
Если вы используете переменные окружения вместо хардкода секретов в YAML (Homepage поддерживает {{HOMEPAGE_VAR_...}} в конфигах), не забудьте бэкапить и файл .env рядом с docker-compose.yml — без него восстановленный конфиг просто не подставит нужные значения.
Ручной бэкап конфигурации
Самый быстрый вариант — обычный tar с меткой времени. Работает, если Homepage развёрнут через Docker и конфиг лежит в примонтированной директории на хосте:
mkdir -p /opt/backups/homepage
tar -czf /opt/backups/homepage/homepage-config-$(date +%Y%m%d-%H%M%S).tar.gz \
-C /opt/homepage config
Проверить, что архив читается и не пустой:
tar -tzf /opt/backups/homepage/homepage-config-*.tar.gz | head -20
Для регулярности добавьте задачу в cron — например, ежедневный бэкап в 3:00 ночи с ротацией последних 14 копий:
crontab -e
0 3 * * * /usr/bin/tar -czf /opt/backups/homepage/homepage-config-$(date +\%Y\%m\%d).tar.gz -C /opt/homepage config && find /opt/backups/homepage -name '*.tar.gz' -mtime +14 -delete
Это решает проблему «забыл сделать бэкап перед правкой», но не защищает от полного отказа диска — архивы лежат на том же сервере. Для этого нужна доставка копии наружу: через rclone в объектное хранилище, rsync на второй сервер, или встроенный в Homepage экспорт настроек (в UI есть кнопка Settings → Export, но она выгружает не всё — только часть runtime-настроек, а не файлы конфигурации целиком, поэтому полагаться только на неё не стоит).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверАвтоматический бэкап с помощью restic
Для конфигурации в несколько мегабайт полноценный дедуплицирующий бэкап — избыточно, но если Homepage у вас стоит рядом с другими сервисами и вы уже используете restic, логично добавить его конфиг в общий репозиторий. Плюс — шифрование «из коробки», что закрывает вопрос с секретами в docker.yaml.
Инициализация репозитория (один раз):
restic init --repo /mnt/backup-storage/restic-repo
Бэкап каталога конфигурации с тегом для удобного поиска:
export RESTIC_PASSWORD='ваш-пароль-репозитория'
restic backup /opt/homepage/config \
--repo /mnt/backup-storage/restic-repo \
--tag homepage \
--exclude 'config/logs/*'
Политика хранения снапшотов — например, 7 дневных, 4 недельных, 6 месячных:
restic forget --repo /mnt/backup-storage/restic-repo \
--tag homepage \
--keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
--prune
Обе команды — в один cron-джоб, запускаемый после ежедневного бэкапа основных сервисов. Если restic ещё не установлен и не настроен, у нас есть отдельный разбор — как установить и настроить restic на VPS с пошаговой инициализацией репозитория и первым бэкапом.
Если репозиторий restic находится на удалённом сервере (второй VPS, S3-совместимое хранилище), это закрывает и сценарий «сгорел весь сервер целиком» — конфиг физически лежит в другом месте.
Бэкап при развёртывании через Docker Compose
Если Homepage у вас поднят через Compose, volume с конфигом обычно объявлен явно — это и есть точка входа для бэкапа. Пример типового docker-compose.yml:
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
ports:
- 3000:3000
volumes:
- ./config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- HOMEPAGE_VAR_TITLE=Мой дашборд
restart: unless-stopped
Здесь ./config — обычная директория на хосте, и её можно бэкапить теми же средствами, что и любой другой конфиг: tar, restic, rsync. Специальных «Docker-хитростей» для Homepage не требуется — в отличие от приложений с базой данных внутри контейнера, здесь нет смысла делать docker exec и снимать дамп: файлы и так лежат на хосте в открытом виде.
Единственное, за чем стоит следить — не бэкапить контейнер целиком через docker commit. Это создаёт образ с зашитыми в него данными на момент снимка, раздувает дисковое пространство и не даёт нормально версионировать изменения. Бэкапьте директорию с конфигом, а образ приложения при необходимости просто перекачивайте заново — docker compose pull && docker compose up -d.
Если вы ещё не разворачивали Homepage и ищете готовый файл для старта, у нас есть отдельная статья с рабочим docker-compose — как установить и настроить Homepage на VPS.
Восстановление из бэкапа
Порядок действий зависит от того, восстанавливаете вы на том же сервере после сбоя или переезжаете на новый.
Восстановление из tar-архива:
cd /opt/homepage
docker compose down
mv config config.broken-$(date +%Y%m%d)
tar -xzf /opt/backups/homepage/homepage-config-20260830.tar.gz
docker compose up -d
Важно не забыть остановить контейнер перед заменой файлов — Homepage кеширует часть данных в рантайме, и подмена конфига «на живую» иногда приводит к рассинхрону UI до перезапуска.
Восстановление из restic:
export RESTIC_PASSWORD='ваш-пароль-репозитория'
restic restore latest --repo /mnt/backup-storage/restic-repo \
--tag homepage \
--target /opt/homepage-restored
Восстановленные файлы появятся в /opt/homepage-restored/opt/homepage/config (restic сохраняет полный путь) — остаётся скопировать нужную папку config на место и перезапустить контейнер:
cp -r /opt/homepage-restored/opt/homepage/config/* /opt/homepage/config/
docker compose restart homepage
Перенос на новый сервер: после восстановления конфига на новой машине проверьте три вещи отдельно от файлов — DNS-запись домена, если дашборд смотрит наружу через reverse proxy (см. Traefik как reverse proxy для Docker), доступность Docker-сокета для docker.yaml-интеграции (на новом сервере он может быть по другому пути в нестандартных установках) и переменные окружения из .env, если секреты вынесены туда, а не в YAML.
После любого восстановления откройте UI и проверьте вкладку с виджетами ресурсов — если сервер новый, ID контейнеров в docker.yaml могли не совпасть по именам, и часть карточек первое время будет показывать «unavailable», пока Homepage не переопросит Docker API.
Частые ошибки при бэкапе и восстановлении Homepage
| Ошибка | Последствие | Как избежать |
|---|---|---|
Бэкапят весь /opt/homepage, включая logs/ | Архив растёт линейно, восстановление дольше | Явно исключать config/logs/* |
Секреты в docker.yaml лежат в открытом бэкапе на общем диске | Утечка токенов при компрометации хранилища | Шифровать через restic или хранить .env отдельно |
| Правка конфига «на живую» без бэкапа перед изменением | Нет отката при синтаксической ошибке в YAML | Бэкап перед каждой правкой — cp -r config config.bak |
| YAML с неправильными отступами после восстановления вручную | Контейнер стартует, но UI пустой или падает в ошибку парсинга | Валидировать YAML перед копированием (python3 -c "import yaml,sys; yaml.safe_load(open(sys.argv[1]))" services.yaml) |
| Бэкап без ротации | Диск с бэкапами заполняется за несколько месяцев | find ... -mtime +N -delete или restic forget --prune |
| Восстановление без остановки контейнера | Временная рассинхронизация UI и файлов на диске | docker compose down перед заменой конфига |
Отдельно стоит сказать про синтаксис YAML — это самая частая практическая причина «всё было в бэкапе, а после восстановления не работает». Homepage довольно строг к отступам и типам данных в services.yaml и widgets.yaml; если бэкап и восстановление делаются вручную через копипаст (например, кто-то открыл файл в редакторе и пересохранил с другими отступами), лишний пробел ломает парсинг молча — контейнер стартует, но карточки не рендерятся. Автоматический бэкап архивом или через restic от этой проблемы избавляет полностью, потому что копирует файлы побайтово.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Нужно ли бэкапить сам образ Homepage, а не только конфиг?
Нет, образ берётся с ghcr.io при каждом docker compose pull — бэкапить нужно только директорию с вашими YAML-файлами и, если используете свои иконки, каталог icons/.
Как часто делать бэкап конфигурации Homepage?
Раз в сутки достаточно для большинства случаев — конфиг меняется нечасто. Если правите виджеты и сервисы каждый день, добавьте бэкап перед каждой ручной правкой отдельным скриптом или git-хуком.
Можно ли хранить конфиг Homepage в git вместо архивного бэкапа?
Да, и это хороший вариант для версионирования изменений — но секреты (токены, пароли) из docker.yaml в таком случае обязательно выносите в .env и добавляйте его в .gitignore, иначе они попадут в историю репозитория.
Что делать, если после восстановления виджеты ресурсов (CPU, RAM) не работают?
Проверьте, что Docker-сокет примонтирован в контейнер (/var/run/docker.sock:/var/run/docker.sock:ro в compose-файле) и что путь к нему на новом сервере совпадает — на некоторых дистрибутивах и в rootless-Docker он отличается.
Восстановленный дашборд открывается, но пустой — почему?
Чаще всего это повреждённый или пустой services.yaml — либо бэкап снимался в момент записи файла, либо восстановился не тот снапшот. Проверьте валидность YAML отдельной командой перед тем, как перезапускать контейнер.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →