СУБД PostgreSQL
В Памир конфигурация и накопленные данные приложения хранятся в СУБД PostgreSQL,
запущенной в контейнере Docker (сервис database). База данных приложения называется srm
и принадлежит пользователю приложения; кроме неё в кластере PostgreSQL присутствуют
служебная БД postgres и роли (пользователи).
Для PostgreSQL рекомендуется логическое резервное копирование утилитами pg_dump /
pg_dumpall с восстановлением через pg_restore / psql. Этот способ даёт
application-consistent копию, переносимую между версиями и инсталляциями, и не требует
остановки сервиса.
Параметры подключения
| Параметр | Значение | Источник |
|---|---|---|
| Сервис / контейнер | database | docker-compose.deps.yml |
| Суперпользователь | $POSTGRES_USER (по умолчанию postgres) | .postgres.env |
| Пароль суперпользователя | $POSTGRES_PASSWORD | .postgres.env |
| Пользователь приложения | $POSTGRES_APP_USER | .postgres.env |
| БД приложения | $POSTGRES_APP_DB (по умолчанию srm) | .postgres.env |
| Каталог данных (PGDATA) | /var/lib/postgresql/data | том pamir_database-data |
Переменные окружения (POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_APP_DB и др.) уже
заданы внутри контейнера database из файла .postgres.env. Поэтому в примерах ниже
на них можно ссылаться напрямую внутри sh -c '…', не подставляя значения вручную.
Все команды выполняются из каталога приложения ($HOME/.pamir или /opt/pamir).
-T при перенаправлении выводаДля команд, вывод которых перенаправляется в файл на хосте (> backup.dump), используйте
docker compose exec -T (без выделения псевдотерминала). Псевдотерминал (-it) искажает
двоичный поток и делает дамп непригодным для восстановления. Флаг -it уместен только для
интерактивных сессий (psql).
Резервное копирование
Дамп базы данных приложения
Дамп БД srm в пользовательском (custom) формате — наиболее гибкий вариант: позволяет
выборочное восстановление и сжимается «на лету».
cd "$HOME/.pamir"
mkdir -p "$HOME/pamir-backups"
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \
-U "$POSTGRES_USER" -d "$POSTGRES_APP_DB" -Fc' \
> "$HOME/pamir-backups/srm-$(date +%F).dump"
где:
-Fc— custom-формат (сжатый, дляpg_restore);-d "$POSTGRES_APP_DB"— БД приложения (srm).
Контейнер СУБД собран на базе Astra Linux, и в дамп попадают команды мандатных меток. Внутри
Памир это не мешает, но при восстановлении на сервер, который меток не поддерживает
(например, PostgreSQL из репозитория РЕД ОС), загрузка прерывается на MAC LABEL. Для такого
переноса дамп снимается с дополнительным флагом --disable-macs:
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \
-U "$POSTGRES_USER" -d "$POSTGRES_APP_DB" -Fc --disable-macs' \
> "$HOME/pamir-backups/srm-$(date +%F).dump"
Флаг нужен при переводе системы на внешний сервер PostgreSQL; для обычного резервного копирования внутри той же инсталляции он не требуется.
Дамп ролей (глобальных объектов)
Роли и права не входят в дамп отдельной БД, поэтому их выгружают отдельно:
cd "$HOME/.pamir"
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dumpall \
-U "$POSTGRES_USER" --globals-only' \
> "$HOME/pamir-backups/globals-$(date +%F).sql"
Полный дамп кластера (альтернатива)
Если нужно сохранить весь кластер PostgreSQL единым файлом (все БД + роли) в текстовом формате:
cd "$HOME/.pamir"
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dumpall -U "$POSTGRES_USER"' \
| gzip > "$HOME/pamir-backups/cluster-$(date +%F).sql.gz"
Восстановление
Восстановление выполняется при работающем сервисе database, но остановленных сервисах
приложения Памир, чтобы исключить запись в БД во время восстановления.
Команда pamirctl start <сервис> поднимает весь стек, поэтому для запуска только СУБД
используйте напрямую docker compose:
docker compose stop # остановить все сервисы
docker compose start database # поднять только СУБД (и её зависимости)
Восстановление из custom-дампа
Сначала восстановите роли (если восстанавливаете на чистый кластер), затем — БД приложения:
cd "$HOME/.pamir"
# 1. Роли (при необходимости)
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER" -d postgres' \
< "$HOME/pamir-backups/globals-2026-06-08.sql"
# 2. БД приложения: пересоздать схему и загрузить данные
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_restore \
-U "$POSTGRES_USER" -d "$POSTGRES_APP_DB" \
--clean --if-exists' \
< "$HOME/pamir-backups/srm-2026-06-08.dump"
где:
--clean --if-exists— удалить существующие объекты перед загрузкой.
--no-ownerВосстановление выполняется от суперпользователя postgres, а объекты БД srm принадлежат
пользователю приложения app_postgres. Флаг --no-owner назначил бы всем объектам владельца
postgres, и приложение потеряло бы доступ (permission denied).
Поэтому роли восстанавливают первым шагом (чтобы роль app_postgres существовала), а
pg_restore запускают без --no-owner — тогда исходное владение (app_postgres)
сохраняется.
Если БД srm нужно создать заново, выполните перед загрузкой:
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER" -d postgres \
-c "DROP DATABASE IF EXISTS \"$POSTGRES_APP_DB\";" \
-c "CREATE DATABASE \"$POSTGRES_APP_DB\" OWNER \"$POSTGRES_APP_USER\";"'
После восстановления запустите приложение:
pamirctl start
Восстановление из полного дампа кластера
cd "$HOME/.pamir"
gunzip -c "$HOME/pamir-backups/cluster-2026-06-08.sql.gz" | \
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" psql -U "$POSTGRES_USER" -d postgres'
Проверка резервных копий
Поверхностная проверка по размеру и дате, а также целостности дампа:
# Размер и дата
ls -lh "$HOME/pamir-backups/"*.dump "$HOME/pamir-backups/"*.sql* 2>/dev/null
# Просмотр оглавления custom-дампа (TOC) — подтверждает читаемость файла
docker compose exec -T database pg_restore -l \
< "$HOME/pamir-backups/srm-2026-06-08.dump" | head
# Проверка целостности сжатого SQL-дампа
gzip -t "$HOME/pamir-backups/cluster-2026-06-08.sql.gz" && echo "OK"
Если pg_restore -l возвращает оглавление без ошибок, а размер файла соответствует
ожидаемому — дамп корректен.
Автоматизация (systemd timer)
Скрипт резервного копирования ~/.local/bin/pamir-backup-postgres.sh:
#!/usr/bin/env bash
set -euo pipefail
cd "$HOME/.pamir"
DEST="$HOME/pamir-backups"
RETENTION_DAYS=14
mkdir -p "$DEST"
STAMP="$(date +%F_%H-%M)"
# Роли
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dumpall -U "$POSTGRES_USER" --globals-only' \
> "$DEST/globals-$STAMP.sql"
# БД приложения
docker compose exec -T database \
sh -c 'PGPASSWORD="$POSTGRES_PASSWORD" pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_APP_DB" -Fc' \
> "$DEST/srm-$STAMP.dump"
# Ротация
find "$DEST" -name 'srm-*.dump' -mtime +"$RETENTION_DAYS" -delete
find "$DEST" -name 'globals-*.sql' -mtime +"$RETENTION_DAYS" -delete
chmod +x ~/.local/bin/pamir-backup-postgres.sh
Служба и таймер:
[Unit]
Description=Pamir PostgreSQL logical backup
[Service]
Type=oneshot
ExecStart=%h/.local/bin/pamir-backup-postgres.sh
[Unit]
Description=Pamir PostgreSQL backup every 6 hours
[Timer]
OnCalendar=*-*-* 00/6:00:00
Persistent=true
[Install]
WantedBy=timers.target
Активация:
systemctl --user daemon-reload
systemctl --user enable --now pamir-backup-postgres.timer
loginctl enable-linger "$USER" # работа таймера без активной сессии
systemctl --user list-timers pamir-backup-postgres.timer