This commit is contained in:
2026-01-06 22:12:07 +05:00
commit 12f57baa26
13 changed files with 3110 additions and 0 deletions

207
backup-scripts/backup-proxmox.sh Executable file
View File

@@ -0,0 +1,207 @@
#!/bin/bash
#
# Скрипт бэкапа Gitea LXC контейнера с Proxmox хоста
# Запускать НА PROXMOX хосте
#
# Выполняет:
# 1. Бэкап на уровне приложения (gitea dump + pg_dump) внутри LXC
# 2. vzdump - полный бэкап контейнера (опционально)
#
set -e
# ============================================
# НАСТРОЙКИ
# ============================================
# ID LXC контейнера с Gitea
LXC_ID="${LXC_ID:-300}"
# Директория для хранения бэкапов на Proxmox
BACKUP_STORAGE="${BACKUP_STORAGE:-/var/lib/vz/dump}"
# Делать ли полный vzdump контейнера (занимает много места)
DO_VZDUMP="${DO_VZDUMP:-false}"
# Сжатие для vzdump: zstd, gzip, lzo, none
VZDUMP_COMPRESS="${VZDUMP_COMPRESS:-zstd}"
# Сколько бэкапов хранить
KEEP_BACKUPS="${KEEP_BACKUPS:-7}"
# Сколько vzdump хранить (они большие!)
KEEP_VZDUMP="${KEEP_VZDUMP:-3}"
# Удалённый сервер для копирования (опционально)
REMOTE_BACKUP="${REMOTE_BACKUP:-}" # user@host:/path
# ============================================
# ФУНКЦИИ
# ============================================
log() {
echo -e "\033[1;34m[$(date '+%Y-%m-%d %H:%M:%S')]\033[0m $1"
}
warn() {
echo -e "\033[1;33m[WARN]\033[0m $1"
}
error() {
echo -e "\033[1;31m[ERROR]\033[0m $1" >&2
exit 1
}
# ============================================
# ПРОВЕРКИ
# ============================================
if ! command -v pct &>/dev/null; then
error "Этот скрипт должен запускаться на Proxmox хосте"
fi
if ! pct status "$LXC_ID" &>/dev/null; then
error "LXC контейнер $LXC_ID не найден"
fi
LXC_STATUS=$(pct status "$LXC_ID" | awk '{print $2}')
if [ "$LXC_STATUS" != "running" ]; then
error "LXC контейнер $LXC_ID не запущен (статус: $LXC_STATUS)"
fi
mkdir -p "$BACKUP_STORAGE"
# ============================================
# ПЕРЕМЕННЫЕ
# ============================================
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
GITEA_BACKUP_DIR="/var/backups/gitea"
log "=========================================="
log " Бэкап Gitea LXC (ID: $LXC_ID)"
log "=========================================="
log ""
# ============================================
# ШАГ 1: БЭКАП НА УРОВНЕ ПРИЛОЖЕНИЯ
# ============================================
log "Запуск бэкапа Gitea внутри LXC..."
# Копируем скрипт бэкапа в контейнер
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [ -f "$SCRIPT_DIR/backup-gitea-lxc.sh" ]; then
pct push "$LXC_ID" "$SCRIPT_DIR/backup-gitea-lxc.sh" /root/backup-gitea-lxc.sh
pct exec "$LXC_ID" -- chmod +x /root/backup-gitea-lxc.sh
fi
# Запускаем бэкап внутри контейнера
BACKUP_OUTPUT=$(pct exec "$LXC_ID" -- bash -c "KEEP_BACKUPS=$KEEP_BACKUPS /root/backup-gitea-lxc.sh" 2>&1) || {
echo "$BACKUP_OUTPUT"
error "Бэкап внутри LXC завершился с ошибкой"
}
echo "$BACKUP_OUTPUT"
# Получаем путь к созданному архиву (последняя строка вывода)
LXC_BACKUP_FILE=$(echo "$BACKUP_OUTPUT" | tail -1)
if [ -z "$LXC_BACKUP_FILE" ] || ! pct exec "$LXC_ID" -- test -f "$LXC_BACKUP_FILE"; then
# Ищем последний бэкап
LXC_BACKUP_FILE=$(pct exec "$LXC_ID" -- ls -t "$GITEA_BACKUP_DIR"/gitea-backup-*.tar.gz 2>/dev/null | head -1)
fi
if [ -n "$LXC_BACKUP_FILE" ]; then
log "Копирование бэкапа из LXC..."
BACKUP_NAME=$(basename "$LXC_BACKUP_FILE")
pct pull "$LXC_ID" "$LXC_BACKUP_FILE" "$BACKUP_STORAGE/$BACKUP_NAME"
log "$BACKUP_STORAGE/$BACKUP_NAME"
# Удаляем архив из LXC (хранятся только на Proxmox)
pct exec "$LXC_ID" -- rm -f "$LXC_BACKUP_FILE"
log " ✓ Удалён из LXC (хранится только на Proxmox)"
else
warn "Не удалось найти архив бэкапа в LXC"
fi
# ============================================
# ШАГ 2: VZDUMP (полный бэкап контейнера)
# ============================================
if [ "$DO_VZDUMP" = "true" ]; then
log ""
log "Создание полного бэкапа контейнера (vzdump)..."
vzdump "$LXC_ID" \
--compress "$VZDUMP_COMPRESS" \
--storage local \
--mode snapshot \
--notes "Gitea backup $TIMESTAMP" \
2>&1 | while read line; do log " $line"; done
log " ✓ vzdump завершён"
fi
# ============================================
# ШАГ 3: ОТПРАВКА НА УДАЛЁННЫЙ СЕРВЕР
# ============================================
if [ -n "$REMOTE_BACKUP" ] && [ -n "$BACKUP_NAME" ]; then
log ""
log "Отправка на удалённый сервер: $REMOTE_BACKUP"
if scp "$BACKUP_STORAGE/$BACKUP_NAME" "$REMOTE_BACKUP/"; then
log " ✓ Отправлено"
else
warn "Не удалось отправить"
fi
fi
# ============================================
# ШАГ 4: РОТАЦИЯ БЭКАПОВ
# ============================================
if [ "$KEEP_BACKUPS" -gt 0 ]; then
log ""
log "Ротация gitea бэкапов (храним $KEEP_BACKUPS)..."
cd "$BACKUP_STORAGE"
ls -t gitea-backup-*.tar.gz 2>/dev/null | tail -n +$((KEEP_BACKUPS + 1)) | xargs -r rm -f
log " ✓ Готово"
fi
# Ротация vzdump (они большие!)
if [ "$KEEP_VZDUMP" -gt 0 ] && [ "$DO_VZDUMP" = "true" ]; then
log "Ротация vzdump бэкапов (храним $KEEP_VZDUMP)..."
cd "$BACKUP_STORAGE"
# Удаляем старые .tar.zst, .tar.gz, .tar.lzo и соответствующие .log файлы
for ext in tar.zst tar.gz tar.lzo vma.zst vma.gz vma.lzo; do
ls -t vzdump-lxc-${LXC_ID}-*.$ext 2>/dev/null | tail -n +$((KEEP_VZDUMP + 1)) | while read f; do
rm -f "$f" "${f%.${ext}}.log"
log " Удалён: $(basename $f)"
done
done
log " ✓ Готово"
fi
# ============================================
# ИТОГИ
# ============================================
log ""
log "=========================================="
log " ✅ Бэкап завершён!"
log "=========================================="
log ""
log "Бэкапы Gitea:"
ls -lh "$BACKUP_STORAGE"/gitea-backup-*.tar.gz 2>/dev/null | tail -5 || echo " (нет)"
log ""
if [ "$DO_VZDUMP" = "true" ]; then
log "Бэкапы vzdump:"
ls -lh "$BACKUP_STORAGE"/vzdump-lxc-${LXC_ID}-*.* 2>/dev/null | tail -3 || echo " (нет)"
log ""
fi
log "Следующий бэкап по расписанию или вручную:"
log " $0"
log ""