Перейти к основному содержимому
Версия: 2.0 (WIP)

Виртуальная машина, конфигурация и Docker volumes

В этом разделе описана базовая (рекомендованная) стратегия резервного копирования Памир — копирование на уровне виртуальной машины, а также резервное копирование конфигурационных файлов приложения и томов Docker (Docker volumes).

Рекомендованная стратегия

Наиболее простой и надёжный способ защитить инсталляцию Памир, развёрнутую в Docker, — резервное копирование всей виртуальной машины (ВМ), на которой работает приложение. Снимок (snapshot) ВМ средствами гипервизора захватывает за один шаг и контейнеры, и тома, и конфигурацию, и операционную систему.

Резервное копирование отдельных томов и конфигурации (см. ниже) применяется как дополнение — например, для более частого создания копий БД или для переноса конфигурации между инсталляциями.

Для специализированных стратегий резервного копирования баз данных см. соответствующие разделы:

Резервное копирование виртуальной машины

Создавайте резервную копию ВМ штатными средствами вашей платформы виртуализации (snapshot/backup гипервизора, например zVirt, ПК СВ «Брест», VMware, Proxmox VE, и т.п.) или средствами системы резервного копирования (СРК).

Распределённая инсталляция

Если сервисы метрик (VictoriaMetrics) или OpenSearch вынесены в кластер на несколько узлов Docker Engine, резервная копия одной ВМ не является полной.

В этом случае необходимо создавать согласованные по времени резервные копии всех ВМ, входящих в инсталляцию:

  • узла (узлов) сервера Памир;
  • всех узлов кластера БД метрик (metrics-storage-*);
  • всех узлов кластера БД журналов (opensearch-*).

Для согласованности рекомендуется создавать снимки всех узлов в одном окне обслуживания.

Консистентность данных

Снимок работающей ВМ обеспечивает только crash-consistent состояние БД (эквивалентно внезапному отключению питания). СУБД при старте выполнят восстановление из журналов (WAL/translog), и в подавляющем большинстве случаев данные останутся целостными.

Для гарантированной application-consistent копии используйте логические бэкапы БД из соответствующих разделов либо останавливайте сервисы на время снятия снимка (см. Остановка сервисов).

Резервное копирование конфигурации Памир

Вся конфигурация инсталляции хранится в каталоге приложения:

Запуск от пользователяКаталог приложения
обычный пользователь/home/<pamir_user_name>/.pamir ($HOME/.pamir)
root/opt/pamir

Каталог содержит всё, что необходимо для развёртывания и работы инсталляции:

$HOME/.pamir/
├── docker-compose.yml # базовое описание (сети)
├── docker-compose.deps.yml # сервисы-зависимости (БД, брокер, кэш, OS, VM, …)
├── docker-compose.server.yml # сервисы приложения (auth, monitoring, srm, …)
├── docker-compose.server.migrations.yml
├── docker-compose.additional.yml # пользовательские доопределения сервисов
├── docker-compose.managed.yml
├── .env # основной файл параметров
├── .<service>.autogen # автогенерируемые параметры сервисов
├── .<service>.env # параметры конкретного сервиса
├── .override.env / .<service>.override.env # пользовательские переопределения
├── data/ # постоянные данные конфигурации
│ ├── nginx/ # сертификаты, шаблоны, vhost-конфигурации API Gateway
│ ├── licenses/ # файл лицензии (installation.key)
│ ├── opensearch/ # opensearch.yml, сертификаты (при ручной настройке)
│ └── step/ # данные центра сертификации
└── init/ # скрипты инициализации (init-database.sh и др.)
к сведению

Подробнее об иерархии и приоритете dotenv-файлов — в разделе Переменные окружения.

Так как пользовательские настройки и автогенерируемые файлы (.*.autogen, .env, .*.override.env), сертификаты, лицензия и init-скрипты хранятся в этом каталоге, его резервное копирование критично для восстановления инсталляции.

Создание архива конфигурации

Все примеры выполняются от имени пользователя, владеющего инсталляцией, из каталога приложения ($HOME/.pamir или /opt/pamir).

cd "$HOME/.pamir"

# Каталог для хранения резервных копий
mkdir -p "$HOME/pamir-backups"

# Архив конфигурации с сохранением прав, владельцев и временных меток (-p)
tar -czpf "$HOME/pamir-backups/pamir-config-$(date +%F).tar.gz" \
--numeric-owner \
-C "$HOME" .pamir

Ключи -p --numeric-owner сохраняют атрибуты файлов и каталогов (права, владельца, время), что важно для корректной работы сертификатов и init-скриптов после восстановления.

Восстановление конфигурации

# Остановить приложение перед восстановлением
pamirctl stop

# Распаковать архив поверх домашнего каталога
tar -xzpf "$HOME/pamir-backups/pamir-config-2026-06-08.tar.gz" \
--numeric-owner \
-C "$HOME"

# Запустить приложение
pamirctl start

Резервное копирование Docker volumes

Постоянные данные сервисов (БД конфигурации, метрики, журналы, очереди, кэш) хранятся в именованных томах Docker. Имена томов формируются с префиксом проекта COMPOSE_PROJECT_NAME (по умолчанию pamir), то есть pamir_<имя-тома>.

Список томов инсталляции:

docker volume ls --filter name=pamir_

Основные тома и их назначение:

Том (pamir_…)Точка монтирования в контейнереНазначение
database-data/var/lib/postgresql/dataБД конфигурации PostgreSQL
metrics-data/metricsБД метрик VictoriaMetrics
opensearch-data/usr/share/opensearch/dataИндексы и журналы OpenSearch
opensearch-config/usr/share/opensearch/configКонфигурация OpenSearch
redis-data/dataКэш и сессии Redis
rabbitmq-data/var/lib/rabbitmqДанные брокера сообщений
prometheus-data/prometheusЛокальное хранилище Prometheus
alertmanager-data/alertmanagerСостояние Alertmanager
step-data/home/stepДанные центра сертификации (Step CA)
openldap-data/var/lib/ldapКаталог OpenLDAP (если используется)
logstash-data/usr/share/logstash/dataСостояние конвейеров Logstash
подсказка

Точный набор томов зависит от включённых профилей (COMPOSE_PROFILES). Всегда сверяйтесь с выводом docker volume ls --filter name=pamir_.

Вспомогательный (утилитный) образ

Для упаковки тома в архив нужен временный контейнер с утилитами tar/gzip. Чтобы не зависеть от внешнего реестра (в закрытом контуре образы вроде alpine недоступны), в качестве вспомогательного используйте образ, уже загруженный в инсталляции — например, образ СУБД PostgreSQL (присутствует в любой установке и содержит полный набор утилит).

Имя образа удобно один раз сохранить в переменную:

cd "$HOME/.pamir"
UTIL_IMAGE=$(docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q database)")
echo "$UTIL_IMAGE" # например: pamir.io/postgres:15.13
примечание

Подойдёт любой локально доступный образ дистрибутива с tar/gzip (docker images — список загруженных образов). В примерах ниже используется переменная $UTIL_IMAGE.

Создание архива тома

Самый простой способ — упаковать содержимое тома в tar-архив с сохранением атрибутов и сжатием. Том монтируется в режиме «только чтение» во временный контейнер:

cd "$HOME/.pamir"

VOLUME=pamir_database-data
DATE=$(date +%F)
docker run --rm \
-v "${VOLUME}:/data:ro" \
-v "$HOME/pamir-backups:/backup" \
--entrypoint sh "$UTIL_IMAGE" \
-c "tar -czpf /backup/${VOLUME}-${DATE}.tar.gz --numeric-owner -C /data . && \
chown $(id -u):$(id -g) /backup/${VOLUME}-${DATE}.tar.gz"

Тот же приём применим к любому тому — достаточно изменить переменную VOLUME.

Владелец файла архива

Вспомогательный контейнер работает от root, поэтому без явного chown файл архива на хосте принадлежал бы root. Команда chown $(id -u):$(id -g) (выполняется внутри контейнера) передаёт файл пользователю инсталляции — это важно, чтобы автоматическая ротация из пользовательского таймера systemd могла удалять старые копии.

Согласованность БД

Для томов баз данных (database-data, metrics-data, opensearch-data) «горячий» архив тома работающего контейнера будет лишь crash-consistent. Для гарантированно согласованных копий используйте специализированные методы из разделов PostgreSQL, OpenSearch, VictoriaMetrics либо останавливайте сервис на время архивации (см. ниже).

Остановка сервисов перед «холодным» бэкапом

Для гарантированно согласованной копии тома остановите соответствующий сервис.

pamirctl start поднимает весь стек

Команда pamirctl start <сервис> запускает всю инсталляцию, а не только указанный сервис. Чтобы остановить и запустить отдельный сервис, используйте напрямую docker compose.

cd "$HOME/.pamir"

# Зафиксировать утилитный образ ДО остановки сервиса (см. «Вспомогательный образ»)
UTIL_IMAGE=$(docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q database)")

# Остановить отдельный сервис (пример для БД конфигурации)
docker compose stop database

# Заархивировать том
DATE=$(date +%F)
docker run --rm \
-v pamir_database-data:/data:ro \
-v "$HOME/pamir-backups:/backup" \
--entrypoint sh "$UTIL_IMAGE" \
-c "tar -czpf /backup/database-data-${DATE}.tar.gz --numeric-owner -C /data . && \
chown $(id -u):$(id -g) /backup/database-data-${DATE}.tar.gz"

# Запустить сервис обратно
docker compose start database

Восстановление тома из архива

cd "$HOME/.pamir"

# Зафиксировать утилитный образ ДО остановки приложения (см. «Вспомогательный образ»)
UTIL_IMAGE=$(docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q database)")

# Остановить приложение (или конкретный сервис)
pamirctl stop

# Очистить том и распаковать в него содержимое архива
docker run --rm \
-v pamir_database-data:/data \
-v "$HOME/pamir-backups:/backup" \
--entrypoint sh "$UTIL_IMAGE" \
-c "rm -rf /data/* /data/..?* /data/.[!.]* 2>/dev/null; \
tar -xzpf /backup/database-data-2026-06-08.tar.gz --numeric-owner -C /data"

# Запустить приложение
pamirctl start
примечание

Если том ещё не существует (восстановление на чистой инсталляции), Docker создаст его автоматически при первом монтировании.

Проверка резервных копий

Поверхностная проверка по размеру, дате и целостности архива:

# Размер и дата создания резервных копий
ls -lh "$HOME/pamir-backups/"

# Проверка целостности gzip-архива (без распаковки)
gzip -t "$HOME/pamir-backups/pamir-config-2026-06-08.tar.gz" && echo "OK"

# Просмотр содержимого архива без распаковки
tar -tzf "$HOME/pamir-backups/pamir-config-2026-06-08.tar.gz" | head

Признаки потенциальной проблемы:

  • размер архива заметно меньше ожидаемого (например, единицы килобайт у тома БД);
  • дата создания не соответствует ожидаемому расписанию;
  • ошибка при gzip -t.

Автоматизация (systemd timer)

Предпочтительный способ планирования — таймеры systemd (от имени пользователя инсталляции).

Создайте скрипт ~/.local/bin/pamir-backup-config.sh:

~/.local/bin/pamir-backup-config.sh
#!/usr/bin/env bash
set -euo pipefail

APP_DIR="$HOME/.pamir"
DEST="$HOME/pamir-backups"
RETENTION_DAYS=14

cd "$APP_DIR"
mkdir -p "$DEST"
STAMP="$(date +%F_%H-%M)"

# Утилитный образ (уже загруженный образ дистрибутива, без обращения к реестру)
UTIL_IMAGE=$(docker inspect --format '{{.Config.Image}}' "$(docker compose ps -q database)")

# Конфигурация
tar -czpf "$DEST/pamir-config-$STAMP.tar.gz" --numeric-owner -C "$HOME" .pamir

# Том БД конфигурации (с передачей файла архива пользователю инсталляции)
docker run --rm -v pamir_database-data:/data:ro -v "$DEST:/backup" \
--entrypoint sh "$UTIL_IMAGE" \
-c "tar -czpf /backup/database-data-$STAMP.tar.gz --numeric-owner -C /data . && \
chown $(id -u):$(id -g) /backup/database-data-$STAMP.tar.gz"

# Удаление копий старше RETENTION_DAYS
find "$DEST" -name '*.tar.gz' -mtime +"$RETENTION_DAYS" -delete
chmod +x ~/.local/bin/pamir-backup-config.sh

Юнит-файлы службы и таймера:

~/.config/systemd/user/pamir-backup.service
[Unit]
Description=Pamir configuration & volumes backup

[Service]
Type=oneshot
ExecStart=%h/.local/bin/pamir-backup-config.sh
~/.config/systemd/user/pamir-backup.timer
[Unit]
Description=Daily Pamir backup at 02:00

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

Активация таймера:

systemctl --user daemon-reload
systemctl --user enable --now pamir-backup.timer

# Чтобы пользовательские таймеры работали без активной сессии:
loginctl enable-linger "$USER"

# Проверка расписания и ручной запуск
systemctl --user list-timers pamir-backup.timer
systemctl --user start pamir-backup.service

Связанные разделы