Files
2026-09-02 08:21:27 +02:00

123 lines
3.4 KiB
Bash

#!/usr/bin/env bash
#
# Odtworzenie instancji z kopii zapasowej.
#
# ./scripts/restore.sh ./backups/20260828-143000
#
# UWAGA: skrypt NADPISUJE biezaca baze i pliki MinIO. Wymaga potwierdzenia.
# Przed odtworzeniem warto zrobic kopie stanu biezacego:
# ./scripts/backup.sh
set -euo pipefail
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.prod.yml}"
ENV_FILE="${ENV_FILE:-.env.production}"
SOURCE="${1:-}"
compose() {
docker compose -f "${COMPOSE_FILE}" --env-file "${ENV_FILE}" "$@"
}
log() {
echo "[$(date +%H:%M:%S)] $*"
}
if [ -z "${SOURCE}" ]; then
echo "Uzycie: $0 <katalog-kopii>" >&2
echo "Dostepne kopie:" >&2
ls -1 ./backups 2>/dev/null | sed 's/^/ /' >&2 || echo " brak katalogu ./backups" >&2
exit 1
fi
if [ ! -f "${SOURCE}/baza.dump" ]; then
echo "BLAD: brak ${SOURCE}/baza.dump" >&2
exit 1
fi
if [ -f "${SOURCE}/INFO.txt" ]; then
echo "--- Kopia do odtworzenia ---"
cat "${SOURCE}/INFO.txt"
echo "----------------------------"
fi
DB_NAME="$(grep -E '^DB_NAME=' "${ENV_FILE}" | cut -d= -f2-)"
DB_USER="$(grep -E '^DB_USER=' "${ENV_FILE}" | cut -d= -f2-)"
echo
echo "UWAGA: ta operacja skasuje biezaca zawartosc bazy ${DB_NAME} i plikow MinIO."
read -r -p "Wpisz ODTWORZ, aby kontynuowac: " CONFIRM
if [ "${CONFIRM}" != "ODTWORZ" ]; then
echo "Przerwano."
exit 1
fi
# Backend musi byc zatrzymany, inaczej trzyma polaczenia do bazy
# i pisze do niej w trakcie odtwarzania.
log "Zatrzymuje backend..."
compose stop backend
log "Odtwarzam baze..."
# --clean --if-exists usuwa istniejace obiekty przed wgraniem
compose exec -T postgres pg_restore \
-U "${DB_USER}" \
-d "${DB_NAME}" \
--clean \
--if-exists \
--no-owner \
< "${SOURCE}/baza.dump"
log "Baza odtworzona"
if [ -f "${SOURCE}/minio.tar.gz" ]; then
log "Odtwarzam pliki MinIO..."
# Obraz MinIO nie zawiera tar, wiec rozpakowujemy z pomocniczego kontenera
# podpietego do tego samego wolumenu. MinIO musi byc w tym czasie zatrzymane,
# zeby nie pisalo do katalogu w trakcie podmiany.
MINIO_CONTAINER="$(compose ps -q minio)"
if [ -z "${MINIO_CONTAINER}" ]; then
echo "BLAD: kontener minio nie istnieje" >&2
exit 1
fi
MINIO_VOLUME="$(docker inspect "${MINIO_CONTAINER}" \
--format '{{range .Mounts}}{{if eq .Destination "/data"}}{{.Name}}{{end}}{{end}}')"
if [ -z "${MINIO_VOLUME}" ]; then
echo "BLAD: nie udalo sie ustalic wolumenu MinIO" >&2
exit 1
fi
log " wolumen: ${MINIO_VOLUME}"
compose stop minio
# czyscimy katalog danych, zeby nie zostaly pliki spoza kopii
docker run --rm -v "${MINIO_VOLUME}:/data" alpine:3.20 \
sh -c 'rm -rf /data/..?* /data/.[!.]* /data/* 2>/dev/null || true'
docker run --rm -i -v "${MINIO_VOLUME}:/data" alpine:3.20 \
tar xzf - -C /data < "${SOURCE}/minio.tar.gz"
log "Pliki MinIO odtworzone"
compose start minio
else
log "Pominieto MinIO: brak minio.tar.gz w kopii"
fi
log "Uruchamiam backend..."
compose start backend
log "Czekam na gotowosc aplikacji..."
for i in $(seq 1 60); do
if compose exec -T backend sh -c 'wget -qO- http://localhost:8080/api/health >/dev/null 2>&1'; then
log "Aplikacja odpowiada"
break
fi
sleep 2
done
echo
log "Gotowe. Sprawdz recznie:"
echo " curl http://localhost:\${FRONTEND_PORT_EXPOSED:-8081}/api/health"
echo " zaloguj sie do panelu i sprawdz liste webinarow"