241 lines
7.3 KiB
Bash
Executable File
241 lines
7.3 KiB
Bash
Executable File
#!/bin/bash
|
||
#
|
||
# Скрипт бэкапа Gitea в LXC контейнере
|
||
# Запускать ВНУТРИ LXC контейнера
|
||
#
|
||
# Создаёт:
|
||
# - pg_dump базы данных
|
||
# - gitea dump (репозитории, конфиг, данные)
|
||
# - Единый архив
|
||
#
|
||
|
||
set -e
|
||
|
||
# ============================================
|
||
# НАСТРОЙКИ
|
||
# ============================================
|
||
|
||
# Директория для бэкапов
|
||
BACKUP_BASE="${BACKUP_BASE:-/var/backups/gitea}"
|
||
|
||
# PostgreSQL
|
||
DB_USER="${DB_USER:-gitea}"
|
||
DB_NAME="${DB_NAME:-gitea}"
|
||
|
||
# Gitea пути
|
||
GITEA_BIN="${GITEA_BIN:-/usr/local/bin/gitea}"
|
||
GITEA_CONFIG="${GITEA_CONFIG:-/etc/gitea/app.ini}"
|
||
GITEA_DATA="${GITEA_DATA:-/var/lib/gitea}"
|
||
|
||
# Сколько бэкапов хранить (0 = не удалять старые)
|
||
KEEP_BACKUPS="${KEEP_BACKUPS:-7}"
|
||
|
||
# Отправка на удалённый сервер (опционально)
|
||
REMOTE_BACKUP="${REMOTE_BACKUP:-}" # user@host:/path/to/backups
|
||
|
||
# ============================================
|
||
# ФУНКЦИИ
|
||
# ============================================
|
||
|
||
log() {
|
||
echo -e "\033[1;32m[$(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
|
||
}
|
||
|
||
cleanup() {
|
||
if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then
|
||
rm -rf "$BACKUP_DIR"
|
||
fi
|
||
}
|
||
|
||
trap cleanup EXIT
|
||
|
||
# ============================================
|
||
# ПРОВЕРКИ
|
||
# ============================================
|
||
|
||
if [ "$EUID" -ne 0 ]; then
|
||
error "Запустите от root: sudo $0"
|
||
fi
|
||
|
||
if ! command -v "$GITEA_BIN" &>/dev/null; then
|
||
error "Gitea не найдена: $GITEA_BIN"
|
||
fi
|
||
|
||
if ! systemctl is-active --quiet postgresql; then
|
||
error "PostgreSQL не запущен"
|
||
fi
|
||
|
||
# ============================================
|
||
# ПОДГОТОВКА
|
||
# ============================================
|
||
|
||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||
BACKUP_DIR="$BACKUP_BASE/gitea-backup-$TIMESTAMP"
|
||
ARCHIVE_NAME="gitea-backup-$TIMESTAMP.tar.gz"
|
||
|
||
mkdir -p "$BACKUP_DIR"
|
||
mkdir -p "$BACKUP_BASE"
|
||
|
||
log "=========================================="
|
||
log " Бэкап Gitea (LXC)"
|
||
log "=========================================="
|
||
log ""
|
||
log "Директория: $BACKUP_DIR"
|
||
log "Архив: $BACKUP_BASE/$ARCHIVE_NAME"
|
||
log ""
|
||
|
||
# Сохраняем версию
|
||
GITEA_VERSION=$("$GITEA_BIN" --version 2>&1 | head -1)
|
||
echo "$GITEA_VERSION" > "$BACKUP_DIR/gitea-version.txt"
|
||
log "Версия Gitea: $GITEA_VERSION"
|
||
|
||
# ============================================
|
||
# ШАГ 1: ДАМП POSTGRESQL
|
||
# ============================================
|
||
|
||
log "Создание дампа PostgreSQL..."
|
||
sudo -u postgres pg_dump -d "$DB_NAME" --no-owner --no-acl > "$BACKUP_DIR/database.sql"
|
||
log " ✓ database.sql ($(du -h "$BACKUP_DIR/database.sql" | cut -f1))"
|
||
|
||
# ============================================
|
||
# ШАГ 2: ОСТАНОВКА GITEA (для консистентности)
|
||
# ============================================
|
||
|
||
GITEA_WAS_RUNNING=false
|
||
if systemctl is-active --quiet gitea; then
|
||
GITEA_WAS_RUNNING=true
|
||
log "Остановка Gitea..."
|
||
systemctl stop gitea
|
||
sleep 2
|
||
fi
|
||
|
||
# ============================================
|
||
# ШАГ 3: GITEA DUMP
|
||
# ============================================
|
||
|
||
log "Создание gitea dump..."
|
||
|
||
# gitea dump запускается от пользователя git, поэтому используем его директорию
|
||
DUMP_TEMP="$GITEA_DATA/tmp-dump"
|
||
mkdir -p "$DUMP_TEMP"
|
||
chown git:git "$DUMP_TEMP"
|
||
|
||
# gitea dump создаёт архив с репозиториями и данными
|
||
sudo -u git "$GITEA_BIN" dump \
|
||
--config "$GITEA_CONFIG" \
|
||
--work-path "$GITEA_DATA" \
|
||
--file "$DUMP_TEMP/gitea-dump.zip" \
|
||
--tempdir "$DUMP_TEMP" \
|
||
--skip-db \
|
||
--type zip 2>&1 | tee "$BACKUP_DIR/dump.log" || {
|
||
warn "gitea dump завершился с предупреждениями (см. dump.log)"
|
||
}
|
||
|
||
# Проверяем на фатальные ошибки
|
||
if grep -q "\[F\]" "$BACKUP_DIR/dump.log" 2>/dev/null; then
|
||
warn "Обнаружена фатальная ошибка в gitea dump:"
|
||
grep "\[F\]" "$BACKUP_DIR/dump.log"
|
||
fi
|
||
|
||
# Перемещаем результат в директорию бэкапа
|
||
if [ -f "$DUMP_TEMP/gitea-dump.zip" ]; then
|
||
mv "$DUMP_TEMP/gitea-dump.zip" "$BACKUP_DIR/"
|
||
log " ✓ gitea-dump.zip ($(du -h "$BACKUP_DIR/gitea-dump.zip" | cut -f1))"
|
||
else
|
||
warn "gitea-dump.zip не создан, копируем данные вручную..."
|
||
cp -a "$GITEA_DATA" "$BACKUP_DIR/data"
|
||
log " ✓ data/ (ручное копирование)"
|
||
fi
|
||
|
||
# Очищаем временную директорию
|
||
rm -rf "$DUMP_TEMP"
|
||
|
||
# ============================================
|
||
# ШАГ 4: КОПИРОВАНИЕ КОНФИГУРАЦИИ
|
||
# ============================================
|
||
|
||
log "Копирование конфигурации..."
|
||
cp "$GITEA_CONFIG" "$BACKUP_DIR/app.ini"
|
||
log " ✓ app.ini"
|
||
|
||
# ============================================
|
||
# ШАГ 5: ПЕРЕЗАПУСК GITEA
|
||
# ============================================
|
||
|
||
if [ "$GITEA_WAS_RUNNING" = true ]; then
|
||
log "Запуск Gitea..."
|
||
systemctl start gitea
|
||
log " ✓ Gitea запущена"
|
||
fi
|
||
|
||
# ============================================
|
||
# ШАГ 6: СОЗДАНИЕ АРХИВА
|
||
# ============================================
|
||
|
||
log "Создание архива..."
|
||
cd "$BACKUP_BASE"
|
||
tar -czf "$ARCHIVE_NAME" -C "$BACKUP_BASE" "$(basename $BACKUP_DIR)"
|
||
|
||
ARCHIVE_SIZE=$(du -h "$BACKUP_BASE/$ARCHIVE_NAME" | cut -f1)
|
||
log " ✓ $ARCHIVE_NAME ($ARCHIVE_SIZE)"
|
||
|
||
# Удаляем временную директорию
|
||
rm -rf "$BACKUP_DIR"
|
||
trap - EXIT
|
||
|
||
# ============================================
|
||
# ШАГ 7: РОТАЦИЯ СТАРЫХ БЭКАПОВ
|
||
# ============================================
|
||
|
||
if [ "$KEEP_BACKUPS" -gt 0 ]; then
|
||
log "Ротация бэкапов (храним $KEEP_BACKUPS)..."
|
||
cd "$BACKUP_BASE"
|
||
ls -t gitea-backup-*.tar.gz 2>/dev/null | tail -n +$((KEEP_BACKUPS + 1)) | xargs -r rm -f
|
||
CURRENT_COUNT=$(ls -1 gitea-backup-*.tar.gz 2>/dev/null | wc -l)
|
||
log " ✓ Текущих бэкапов: $CURRENT_COUNT"
|
||
fi
|
||
|
||
# ============================================
|
||
# ШАГ 8: ОТПРАВКА НА УДАЛЁННЫЙ СЕРВЕР
|
||
# ============================================
|
||
|
||
if [ -n "$REMOTE_BACKUP" ]; then
|
||
log "Отправка на удалённый сервер: $REMOTE_BACKUP"
|
||
if scp "$BACKUP_BASE/$ARCHIVE_NAME" "$REMOTE_BACKUP/"; then
|
||
log " ✓ Отправлено"
|
||
else
|
||
warn "Не удалось отправить бэкап"
|
||
fi
|
||
fi
|
||
|
||
# ============================================
|
||
# ИТОГИ
|
||
# ============================================
|
||
|
||
log ""
|
||
log "=========================================="
|
||
log " ✅ Бэкап завершён!"
|
||
log "=========================================="
|
||
log ""
|
||
log "Файл: $BACKUP_BASE/$ARCHIVE_NAME"
|
||
log "Размер: $ARCHIVE_SIZE"
|
||
log ""
|
||
log "Содержимое архива:"
|
||
log " - database.sql (PostgreSQL дамп)"
|
||
log " - gitea-dump.zip (репозитории, LFS, данные)"
|
||
log " - app.ini (конфигурация)"
|
||
log " - gitea-version.txt"
|
||
log ""
|
||
|
||
# Возвращаем путь к архиву (для скриптов)
|
||
echo "$BACKUP_BASE/$ARCHIVE_NAME"
|