mirror of
https://github.com/acedanger/shell.git
synced 2025-12-06 00:00:13 -08:00
267 lines
7.7 KiB
Bash
267 lines
7.7 KiB
Bash
#!/bin/bash
|
|
|
|
# backup-gitea.sh - Backup Gitea data and PostgreSQL database
|
|
# Author: Shell Repository
|
|
# Description: Comprehensive backup solution for Gitea with PostgreSQL database
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[0;33m'
|
|
RED='\033[0;31m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BACKUP_DIR="/home/acedanger/backups/gitea"
|
|
COMPOSE_DIR="/home/acedanger/docker/gitea"
|
|
COMPOSE_FILE="$COMPOSE_DIR/docker-compose.yml"
|
|
LOG_FILE="$SCRIPT_DIR/logs/gitea-backup.log"
|
|
|
|
# Ensure logs directory exists
|
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
|
|
# Logging function
|
|
log() {
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
# Display usage information
|
|
usage() {
|
|
echo "Usage: $0 [OPTIONS]"
|
|
echo ""
|
|
echo "Backup Gitea data and PostgreSQL database"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -h, --help Show this help message"
|
|
echo " -d, --dry-run Show what would be backed up without doing it"
|
|
echo " -f, --force Force backup even if one was recently created"
|
|
echo " -r, --restore FILE Restore from specified backup directory"
|
|
echo " -l, --list List available backups"
|
|
echo " -c, --cleanup Clean up old backups (keeps last 7 days)"
|
|
echo " --keep-days DAYS Number of days to keep backups (default: 7)"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Regular backup"
|
|
echo " $0 --dry-run # See what would be backed up"
|
|
echo " $0 --list # List available backups"
|
|
echo " $0 --restore /path/to/backup # Restore from backup"
|
|
}
|
|
|
|
# Check dependencies
|
|
check_dependencies() {
|
|
local missing_deps=()
|
|
|
|
command -v docker >/dev/null 2>&1 || missing_deps+=("docker")
|
|
command -v docker-compose >/dev/null 2>&1 || missing_deps+=("docker-compose")
|
|
|
|
if [ ${#missing_deps[@]} -ne 0 ]; then
|
|
echo -e "${RED}Error: Missing required dependencies: ${missing_deps[*]}${NC}"
|
|
echo "Please install the missing dependencies and try again."
|
|
exit 1
|
|
fi
|
|
|
|
# Check if docker-compose file exists
|
|
if [ ! -f "$COMPOSE_FILE" ]; then
|
|
echo -e "${RED}Error: Docker compose file not found at $COMPOSE_FILE${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if we can access Docker
|
|
if ! docker info >/dev/null 2>&1; then
|
|
echo -e "${RED}Error: Cannot access Docker. Check if Docker is running and you have permissions.${NC}"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Check if Gitea services are running
|
|
check_gitea_services() {
|
|
cd "$COMPOSE_DIR"
|
|
|
|
if ! docker-compose ps | grep -q "Up"; then
|
|
echo -e "${YELLOW}Warning: Gitea services don't appear to be running${NC}"
|
|
echo "Some backup operations may fail if services are not running."
|
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Backup cancelled"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# List available backups
|
|
list_backups() {
|
|
echo -e "${BLUE}=== Available Gitea Backups ===${NC}"
|
|
|
|
if [ ! -d "$BACKUP_DIR" ]; then
|
|
echo -e "${YELLOW}No backup directory found at $BACKUP_DIR${NC}"
|
|
return 0
|
|
fi
|
|
|
|
local count=0
|
|
|
|
# Find backup directories
|
|
for backup_path in "$BACKUP_DIR"/gitea_backup_*; do
|
|
if [ -d "$backup_path" ]; then
|
|
local backup_name
|
|
backup_name=$(basename "$backup_path")
|
|
local backup_date
|
|
backup_date=$(echo "$backup_name" | sed 's/gitea_backup_//' | sed 's/_/ /')
|
|
local size
|
|
size=$(du -sh "$backup_path" 2>/dev/null | cut -f1)
|
|
local info_file="$backup_path/backup_info.txt"
|
|
|
|
echo -e "${GREEN}📦 $backup_name${NC}"
|
|
echo " Date: $backup_date"
|
|
echo " Size: $size"
|
|
echo " Path: $backup_path"
|
|
|
|
if [ -f "$info_file" ]; then
|
|
local gitea_version
|
|
gitea_version=$(grep "Gitea Version:" "$info_file" 2>/dev/null | cut -d: -f2- | xargs)
|
|
if [ -n "$gitea_version" ]; then
|
|
echo " Version: $gitea_version"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
count=$((count + 1))
|
|
fi
|
|
done
|
|
|
|
if [ $count -eq 0 ]; then
|
|
echo -e "${YELLOW}No backups found in $BACKUP_DIR${NC}"
|
|
echo "Run a backup first to create one."
|
|
else
|
|
echo -e "${BLUE}Total backups found: $count${NC}"
|
|
fi
|
|
}
|
|
|
|
# Change to compose directory
|
|
cd "$COMPOSE_DIR"
|
|
|
|
# Create timestamped backup directory
|
|
BACKUP_PATH="$BACKUP_DIR/gitea_backup_$DATE"
|
|
mkdir -p "$BACKUP_PATH"
|
|
|
|
# Backup PostgreSQL database
|
|
echo "Backing up PostgreSQL database..."
|
|
docker-compose exec -T db pg_dump -U ${POSTGRES_USER:-gitea} ${POSTGRES_DB:-gitea} > "$BACKUP_PATH/database.sql"
|
|
|
|
# Backup Gitea data volume
|
|
echo "Backing up Gitea data volume..."
|
|
docker run --rm \
|
|
-v gitea_gitea:/data:ro \
|
|
-v "$BACKUP_PATH":/backup \
|
|
alpine:latest \
|
|
tar czf /backup/gitea_data.tar.gz -C /data .
|
|
|
|
# Backup PostgreSQL data volume (optional, as we have the SQL dump)
|
|
echo "Backing up PostgreSQL data volume..."
|
|
docker run --rm \
|
|
-v gitea_postgres:/data:ro \
|
|
-v "$BACKUP_PATH":/backup \
|
|
alpine:latest \
|
|
tar czf /backup/postgres_data.tar.gz -C /data .
|
|
|
|
# Copy docker-compose configuration
|
|
echo "Backing up configuration files..."
|
|
cp "$COMPOSE_FILE" "$BACKUP_PATH/"
|
|
if [ -f ".env" ]; then
|
|
cp ".env" "$BACKUP_PATH/"
|
|
fi
|
|
|
|
# Create a restore script
|
|
cat > "$BACKUP_PATH/restore.sh" << 'EOF'
|
|
#!/bin/bash
|
|
# Restore script for Gitea backup
|
|
|
|
set -e
|
|
|
|
RESTORE_DIR="$(dirname "$0")"
|
|
COMPOSE_DIR="/home/acedanger/docker/gitea"
|
|
|
|
echo "WARNING: This will stop Gitea and replace all data!"
|
|
read -p "Are you sure you want to continue? (yes/no): " confirm
|
|
|
|
if [ "$confirm" != "yes" ]; then
|
|
echo "Restore cancelled"
|
|
exit 1
|
|
fi
|
|
|
|
cd "$COMPOSE_DIR"
|
|
|
|
# Stop services
|
|
echo "Stopping Gitea services..."
|
|
docker-compose down
|
|
|
|
# Remove existing volumes
|
|
echo "Removing existing volumes..."
|
|
docker volume rm gitea_gitea gitea_postgres || true
|
|
|
|
# Recreate volumes
|
|
echo "Creating volumes..."
|
|
docker volume create gitea_gitea
|
|
docker volume create gitea_postgres
|
|
|
|
# Restore Gitea data
|
|
echo "Restoring Gitea data..."
|
|
docker run --rm \
|
|
-v gitea_gitea:/data \
|
|
-v "$RESTORE_DIR":/backup:ro \
|
|
alpine:latest \
|
|
tar xzf /backup/gitea_data.tar.gz -C /data
|
|
|
|
# Start database for restore
|
|
echo "Starting database for restore..."
|
|
docker-compose up -d db
|
|
|
|
# Wait for database to be ready
|
|
echo "Waiting for database to be ready..."
|
|
sleep 10
|
|
|
|
# Restore database
|
|
echo "Restoring database..."
|
|
docker-compose exec -T db psql -U ${POSTGRES_USER:-gitea} -d ${POSTGRES_DB:-gitea} < "$RESTORE_DIR/database.sql"
|
|
|
|
# Start all services
|
|
echo "Starting all services..."
|
|
docker-compose up -d
|
|
|
|
echo "Restore completed!"
|
|
EOF
|
|
|
|
chmod +x "$BACKUP_PATH/restore.sh"
|
|
|
|
# Create info file
|
|
cat > "$BACKUP_PATH/backup_info.txt" << EOF
|
|
Gitea Backup Information
|
|
========================
|
|
Backup Date: $(date)
|
|
Backup Location: $BACKUP_PATH
|
|
Gitea Version: $(docker-compose exec -T server gitea --version | head -1)
|
|
PostgreSQL Version: $(docker-compose exec -T db postgres --version)
|
|
|
|
Files included:
|
|
- database.sql: PostgreSQL database dump
|
|
- gitea_data.tar.gz: Gitea data volume
|
|
- postgres_data.tar.gz: PostgreSQL data volume
|
|
- docker-compose.yml: Docker compose configuration
|
|
- .env: Environment variables (if exists)
|
|
- restore.sh: Restore script
|
|
|
|
To restore this backup, run:
|
|
cd $BACKUP_PATH
|
|
./restore.sh
|
|
EOF
|
|
|
|
# Cleanup old backups (keep last 7 days)
|
|
echo "Cleaning up old backups..."
|
|
find "$BACKUP_DIR" -type d -name "gitea_backup_*" -mtime +7 -exec rm -rf {} + 2>/dev/null || true
|
|
|
|
echo "Backup completed successfully!"
|
|
echo "Backup saved to: $BACKUP_PATH"
|
|
echo "Backup size: $(du -sh "$BACKUP_PATH" | cut -f1)" |