208 lines
6.9 KiB
Bash
Executable File
208 lines
6.9 KiB
Bash
Executable File
#!/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 ""
|