#!/bin/bash # Gitea backup script — run on the VPS before any hardening changes. # Usage: sudo bash scripts/gitea_backup.sh [off-site-dest] # # off-site-dest: optional rsync/scp destination for off-site copy # e.g. user@backup-host:/backups/gitea/ # # Refs: #971, #990 set -euo pipefail BACKUP_DIR="/opt/gitea/backups" TIMESTAMP=$(date +"%Y%m%d_%H%M%S") GITEA_CONF="/etc/gitea/app.ini" GITEA_WORK_DIR="/var/lib/gitea" OFFSITE_DEST="${1:-}" echo "=== Gitea Backup — $TIMESTAMP ===" # Ensure backup directory exists mkdir -p "$BACKUP_DIR" cd "$BACKUP_DIR" # Run the dump echo "[1/4] Running gitea dump..." gitea dump -c "$GITEA_CONF" # Find the newest zip (gitea dump names it gitea-dump-*.zip) BACKUP_FILE=$(ls -t "$BACKUP_DIR"/gitea-dump-*.zip 2>/dev/null | head -1) if [ -z "$BACKUP_FILE" ]; then echo "ERROR: No backup zip found in $BACKUP_DIR" exit 1 fi BACKUP_SIZE=$(stat -c%s "$BACKUP_FILE" 2>/dev/null || stat -f%z "$BACKUP_FILE") echo "[2/4] Backup created: $BACKUP_FILE ($BACKUP_SIZE bytes)" if [ "$BACKUP_SIZE" -eq 0 ]; then echo "ERROR: Backup file is 0 bytes" exit 1 fi # Lock down permissions chmod 600 "$BACKUP_FILE" # Verify contents echo "[3/4] Verifying backup contents..." CONTENTS=$(unzip -l "$BACKUP_FILE" 2>/dev/null || true) check_component() { if echo "$CONTENTS" | grep -q "$1"; then echo " OK: $2" else echo " WARN: $2 not found in backup" fi } check_component "gitea-db.sql" "Database dump" check_component "gitea-repo" "Repositories" check_component "custom" "Custom config" check_component "app.ini" "app.ini" # Off-site copy if [ -n "$OFFSITE_DEST" ]; then echo "[4/4] Copying to off-site: $OFFSITE_DEST" rsync -avz "$BACKUP_FILE" "$OFFSITE_DEST" echo " Off-site copy complete." else echo "[4/4] No off-site destination provided. Skipping." echo " To copy later: scp $BACKUP_FILE user@backup-host:/backups/gitea/" fi echo "" echo "=== Backup complete ===" echo "File: $BACKUP_FILE" echo "Size: $BACKUP_SIZE bytes" echo "" echo "To verify restore on a clean instance:" echo " 1. Copy zip to test machine" echo " 2. unzip $BACKUP_FILE" echo " 3. gitea restore --from -c /etc/gitea/app.ini" echo " 4. Verify repos and DB are intact"