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.
74 lines
3.6 KiB
Bash
74 lines
3.6 KiB
Bash
#!/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 БД на диске → 200–600MB 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
|