#!/bin/bash set -euo pipefail # ==================================== # Forgejo restore script # ==================================== # Where this script lives (Forgejo project root) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" BACKUP_DIR="$SCRIPT_DIR/backup" TIMESTAMP="$(date +%Y-%m-%d_%H-%M-%S)" usage() { echo "Usage: $0 " echo echo " can be:" echo " - Full path to a backup tar.gz" echo " - Filename in the backup/ directory" echo " - If omitted, the latest backup in backup/ is used (if available)" exit 1 } # ------------------------------------ # 1) Pick backup file # ------------------------------------ if [[ $# -ge 1 ]]; then INPUT_FILE="$1" # If it's not an absolute path and not already in backup/, assume it's in backup/ if [[ "$INPUT_FILE" != /* && "$INPUT_FILE" != "$BACKUP_DIR/"* ]]; then BACKUP_FILE="$BACKUP_DIR/$INPUT_FILE" else BACKUP_FILE="$INPUT_FILE" fi else # No argument → pick the latest backup in backup/ echo "No backup file specified, selecting latest from $BACKUP_DIR..." BACKUP_FILE="$(ls -1t "$BACKUP_DIR"/forgejo-backup-*.tar.gz 2>/dev/null | head -n 1 || true)" if [[ -z "${BACKUP_FILE:-}" ]]; then echo "ERROR: No backups found in $BACKUP_DIR" usage fi fi if [[ ! -f "$BACKUP_FILE" ]]; then echo "ERROR: Backup file not found: $BACKUP_FILE" exit 1 fi echo "=== Forgejo restore ===" echo "Project dir : $SCRIPT_DIR" echo "Backup dir : $BACKUP_DIR" echo "Backup file : $BACKUP_FILE" echo read -rp "!!! This will overwrite current Forgejo data. Continue? [y/N] " ANSWER case "$ANSWER" in y|Y|yes|YES) ;; *) echo "Aborted."; exit 1 ;; esac # ------------------------------------ # 2) Stop Forgejo # ------------------------------------ echo "[1/4] Stopping Forgejo containers (if running)..." docker compose down || true # ------------------------------------ # 3) Safety snapshot of current state # ------------------------------------ SAFETY_BACKUP="$BACKUP_DIR/forgejo-pre-restore-${TIMESTAMP}.tar.gz" echo "[2/4] Creating safety backup of CURRENT state -> $SAFETY_BACKUP" tar -czf "$SAFETY_BACKUP" \ forgejo \ docker-compose.yml \ .gitignore \ README.md \ .git 2>/dev/null || true echo "[OK] Safety backup created." # ------------------------------------ # 4) Restore from selected backup # ------------------------------------ echo "[3/4] Removing current Forgejo data (moving to forgejo.old-$TIMESTAMP)..." if [[ -d forgejo ]]; then mv forgejo "forgejo.old-$TIMESTAMP" fi # If config files exist, move them too (just in case) for f in docker-compose.yml .gitignore README.md; do if [[ -f "$f" ]]; then mv "$f" "${f}.old-$TIMESTAMP" fi done echo "[4/4] Extracting backup archive..." tar -xzf "$BACKUP_FILE" -C "$SCRIPT_DIR" echo "=== Restore complete ===" echo "Starting Forgejo containers..." docker compose up -d echo "Forgejo should now be running with data from:" echo " $BACKUP_FILE" echo echo "Previous state saved as:" echo " $SAFETY_BACKUP" echo " forgejo.old-$TIMESTAMP (and *.old-$TIMESTAMP for configs, if any)"