#!/usr/bin/env bash # ============================================================================== # Gitea Backup Script # ============================================================================== # Creates a backup archive of Gitea + PostgreSQL data and Traefik config. # # Hot backup (default): runs gitea dump + pg_dump while containers stay up. # Cold backup (--cold): stops containers, tars data, restarts. # # Usage: backup-gitea.sh # backup-gitea.sh --cold # ============================================================================== set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/common.sh" parse_args "$@" SERVICE_NAME="gitea" BASE_DIR="/opt/${SERVICE_NAME}" CONFIG_NAME="${SERVICE_NAME}" BACKUP_DIR="/opt/backup" STAMP="$(date +%Y%m%d-%H%M%S)" BACKUP_FILE="${BACKUP_DIR}/backup-${SERVICE_NAME}-${STAMP}.tar.gz" [[ -d "$BASE_DIR" ]] || fatal "Gitea is not deployed at ${BASE_DIR}." mkdir -p "$BACKUP_DIR" # --- Hot backup: application-level dumps --- if [[ "$ARG_COLD" != "1" ]]; then info "Running hot backup (containers stay up)..." # Gitea built-in dump info "Running gitea dump..." mkdir -p "${BASE_DIR}/gitea/data/backup" docker exec -u git gitea bash -c \ '/app/gitea/gitea dump -c /data/gitea/conf/app.ini --type tar.gz -f /data/backup/gitea-dump.tar.gz' \ 2>/dev/null || warn "Gitea dump failed — archive will contain live data files only." # PostgreSQL dump info "Running pg_dump..." docker exec gitea-postgres pg_dump -U gitea -d gitea \ > "${BASE_DIR}/postgres/dump.sql" \ 2>/dev/null || warn "pg_dump failed — archive will contain live data files only." fi # --- Cold backup: stop containers --- if [[ "$ARG_COLD" == "1" ]]; then info "Running cold backup (stopping containers)..." (cd "$BASE_DIR" && docker compose down) fi # --- Create archive --- info "Creating archive..." tar czf "$BACKUP_FILE" -C / \ "opt/${SERVICE_NAME}" \ "opt/traefik/dynamic/${CONFIG_NAME}.yml" 2>/dev/null || \ tar czf "$BACKUP_FILE" -C / \ "opt/${SERVICE_NAME}" # --- Cold: restart --- if [[ "$ARG_COLD" == "1" ]]; then (cd "$BASE_DIR" && docker compose up -d) ok "Containers restarted." fi # --- Clean up dump files --- rm -f "${BASE_DIR}/gitea/data/backup/gitea-dump.tar.gz" 2>/dev/null rm -f "${BASE_DIR}/postgres/dump.sql" 2>/dev/null # --- Rotate old backups (keep last 5) --- # shellcheck disable=SC2012 ls -t "${BACKUP_DIR}/backup-${SERVICE_NAME}-"*.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm -- ok "Backup: ${BACKUP_FILE} ($(du -h "$BACKUP_FILE" | cut -f1))"