Files
gitea-backup/backup-scripts/backup-proxmox.sh
2026-01-06 22:12:07 +05:00

208 lines
6.9 KiB
Bash
Executable File
Raw 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
#
# Скрипт бэкапа 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 ""