Files
homelab-docs/scripts/backup-ct101-pgdump.sh
Andrey 16c254510a Update documentation to centralize Vaultwarden integration details and enhance backup scripts
Refactor README, architecture, and backup documentation to emphasize the use of Vaultwarden for credential management across various services. Update scripts for Nextcloud, Gitea, Paperless, and others to reference Vaultwarden for sensitive information. Remove outdated references to previous backup strategies and ensure clarity on credential retrieval processes. This improves security practices and streamlines backup operations.
2026-02-28 00:52:56 +03:00

74 lines
3.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Логический бэкап PostgreSQL (Nextcloud) из контейнера 101.
# Запускать на хосте Proxmox под root. Использует pct exec (SSH не нужен).
# Результат: /mnt/backup/databases/ct101-nextcloud/nextcloud-db-YYYYMMDD-HHMM.sql.gz
set -e
# Чтобы из cron находились bw и jq (часто в /usr/local/bin)
export PATH="/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH:-}"
CT_ID=101
BACKUP_DIR="/mnt/backup/databases/ct101-nextcloud"
RETENTION_DAYS=14
# Имя контейнера БД в compose-проекте nextcloud (при смене имени в compose — поправить)
PG_CONTAINER="nextcloud-db-1"
if [ "$(id -u)" -ne 0 ]; then
echo "Запускайте под root."
exit 1
fi
# Минимальный размер дампа (байт). Пустой gzip ≈ 20 байт — значит pg_dump не отдал данные.
MIN_BACKUP_BYTES=512
mkdir -p "$BACKUP_DIR"
DATE=$(date +%Y%m%d-%H%M)
OUTPUT="$BACKUP_DIR/nextcloud-db-$DATE.sql.gz"
ERR=$(mktemp)
trap "rm -f '$ERR'" EXIT
# PGPASSWORD из Vaultwarden (объект NEXTCLOUD: поле dbpassword или пароль). См. docs/vaultwarden-secrets.md
PG_ENV_ARGS=""
BW_MASTER_PASSWORD_FILE="${BW_MASTER_PASSWORD_FILE:-/root/.bw-master}"
if [ -f "$BW_MASTER_PASSWORD_FILE" ] && command -v bw >/dev/null 2>&1 && command -v jq >/dev/null 2>&1; then
export BW_SESSION=$(bw unlock --passwordfile "$BW_MASTER_PASSWORD_FILE" --raw 2>/dev/null) || true
if [ -n "${BW_SESSION:-}" ]; then
PGPASS=$(bw get item "NEXTCLOUD" 2>/dev/null | jq -r '.fields[] | select(.name=="dbpassword") | .value')
[ -z "$PGPASS" ] && PGPASS=$(bw get password "NEXTCLOUD" 2>/dev/null)
[ -n "$PGPASS" ] && PG_ENV_ARGS="-e PGPASSWORD=$PGPASS"
fi
fi
pct exec $CT_ID -- docker exec $PG_ENV_ARGS "$PG_CONTAINER" pg_dump -U nextcloud nextcloud 2>"$ERR" | gzip > "$OUTPUT"
SIZE_BYTES=$(stat -c%s "$OUTPUT" 2>/dev/null || echo 0)
if [ -s "$OUTPUT" ] && [ "$SIZE_BYTES" -ge "$MIN_BACKUP_BYTES" ]; then
echo "Создан: $OUTPUT ($(du --apparent-size -h "$OUTPUT" | cut -f1))"
# Проверка: несжатый размер дампа (2GB БД на диске → 200600MB SQL нормально: индексы не в дампе, потом gzip)
if [ "${VERIFY_BACKUP:-0}" = "1" ]; then
UNCOMPRESSED=$(gunzip -c "$OUTPUT" 2>/dev/null | wc -c)
UNCOMPRESSED_MB=$(( UNCOMPRESSED / 1024 / 1024 ))
echo "Несжатый размер дампа: ${UNCOMPRESSED_MB} MB (${UNCOMPRESSED} B)"
TABLES_IN_DUMP=$(gunzip -c "$OUTPUT" 2>/dev/null | grep -c '^CREATE TABLE ' || true)
echo "Таблиц в дампе: $TABLES_IN_DUMP"
fi
else
echo "Ошибка: дамп пустой или слишком мал (${SIZE_BYTES} байт). Проверьте контейнер $PG_CONTAINER и пароль БД в Vaultwarden (NEXTCLOUD)."
[ -s "$ERR" ] && cat "$ERR" >&2
rm -f "$OUTPUT"
exit 1
fi
find "$BACKUP_DIR" -name 'nextcloud-db-*.sql.gz' -mtime +$RETENTION_DAYS -delete
NOTIFY_SCRIPT="${NOTIFY_SCRIPT:-/root/scripts/notify-telegram.sh}"
if [ -x "$NOTIFY_SCRIPT" ]; then
SIZE=$(du --apparent-size -h "$OUTPUT" | cut -f1)
SIZE_BYTES=$(stat -c%s "$OUTPUT" 2>/dev/null || echo 0)
BODY="Резервное копирование завершено.
Объекты: дамп БД Nextcloud (PostgreSQL).
Размер копии: ${SIZE}."
[ "$SIZE_BYTES" -lt 10240 ] 2>/dev/null && BODY="${BODY}
⚠️ Подозрительно малый размер — проверьте контейнер nextcloud-db-1 и наличие данных в БД."
"$NOTIFY_SCRIPT" "🗄️ Nextcloud (БД)" "$BODY" || true
fi