apps/gitea/restore.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
if [[ $# -ne 1 || ! -f "$1" ]]; then
echo "Usage: $0 path/to/gitea-YYYYMMDDTHHMMSS.NNNNNNNNNZ.tar" >&2
exit 2
fi
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
archive="$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
cd "$script_dir"
if [[ -f .env ]]; then
set -a
# shellcheck disable=SC1091
. ./.env
set +a
fi
data_volume="${GITEA_DATA_VOLUME:-gitea-data}"
db_user="${POSTGRES_USER:-gitea}"
db_name="${POSTGRES_DB:-gitea}"
staging="$(mktemp -d)"
trap 'rm -rf "$staging"' EXIT
tar -C "$staging" -xf "$archive" database.sql.gz gitea-data.tar.gz
# Keep an emergency copy of the state that is about to be replaced.
bash "$script_dir/backup.sh"
docker compose stop gitea
docker run --rm -v "${data_volume}:/target" -v "${staging}:/restore:ro" alpine:3.22 sh -c 'rm -rf /target/* /target/.[!.]* /target/..?* 2>/dev/null || true; tar -C /target -xzf /restore/gitea-data.tar.gz'
gunzip --stdout "$staging/database.sql.gz" | docker compose exec -T database psql --username="$db_user" --dbname="$db_name" --single-transaction --set ON_ERROR_STOP=on >/dev/null
docker compose up -d --wait
# Hook scripts embed absolute paths and the binary version, so they are
# rewritten after the data directory is replaced. The binary refuses to run as
# root, so the command goes in as the image's own `git` user.
docker compose exec -T --user git gitea gitea admin regenerate hooks
echo "Backup restored from: $archive"