5dfd5b1814
Build & Deploy / Build & Push Docker Image (push) Failing after 34s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 57s
Test / API Unit Tests (push) Failing after 52s
Test / Homepage Unit Tests (push) Successful in 46s
Test / Storefront Unit Tests (push) Successful in 44s
Test / Admin Unit Tests (push) Successful in 41s
Test / Dashboard Unit Tests (push) Successful in 43s
Test / API Integration Tests (push) Has been cancelled
101 lines
2.9 KiB
Bash
Executable File
101 lines
2.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
source "${ROOT_DIR}/scripts/docker-prod-common.sh"
|
|
|
|
BACKUP_ROOT="${1:-${ROOT_DIR}/backups}"
|
|
shift || true
|
|
EXTRA_VOLUMES=("$@")
|
|
TIMESTAMP="$(date -u +"%Y%m%dT%H%M%SZ")"
|
|
mkdir -p "${BACKUP_ROOT}"
|
|
BACKUP_ROOT="$(cd "${BACKUP_ROOT}" && pwd)"
|
|
BACKUP_DIR="${BACKUP_ROOT}/rentaldrivego-prod-${TIMESTAMP}"
|
|
VOLUME_BACKUP_DIR="${BACKUP_DIR}/volumes"
|
|
|
|
DEFAULT_VOLUMES=(
|
|
"${PROJECT_NAME}_api_uploads"
|
|
"${PROJECT_NAME}_pgmanage_prod_data"
|
|
"${PROJECT_NAME}_postgres_prod_data"
|
|
"${PROJECT_NAME}_redis_prod_data"
|
|
)
|
|
|
|
mkdir -p "${BACKUP_DIR}"
|
|
mkdir -p "${VOLUME_BACKUP_DIR}"
|
|
|
|
ensure_env_file
|
|
ensure_traefik_network
|
|
|
|
echo "Creating production backup in ${BACKUP_DIR}"
|
|
|
|
prod_compose up -d postgres >/dev/null
|
|
|
|
echo "Backing up PostgreSQL database..."
|
|
prod_compose exec -T postgres sh -lc 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' > "${BACKUP_DIR}/postgres.dump"
|
|
|
|
echo "Backing up uploaded files..."
|
|
prod_compose run --rm --no-deps api bash -lc '
|
|
mkdir -p /var/lib/rentaldrivego/storage
|
|
tar -czf - -C /var/lib/rentaldrivego/storage .
|
|
' > "${BACKUP_DIR}/api-uploads.tar.gz"
|
|
|
|
echo "Backing up Traefik certificates..."
|
|
if traefik_compose run --rm traefik sh -lc 'test -d /letsencrypt' > /dev/null 2>&1; then
|
|
traefik_compose run --rm traefik sh -lc '
|
|
mkdir -p /letsencrypt
|
|
tar -czf - -C /letsencrypt .
|
|
' > "${BACKUP_DIR}/traefik-letsencrypt.tar.gz"
|
|
else
|
|
echo "Skipping Traefik certificate backup; Traefik runtime is not available."
|
|
fi
|
|
|
|
declare -a ALL_VOLUMES=("${DEFAULT_VOLUMES[@]}")
|
|
|
|
if [[ -n "${DOCKER_EXTRA_BACKUP_VOLUMES:-}" ]]; then
|
|
# shellcheck disable=SC2206
|
|
ALL_VOLUMES+=(${DOCKER_EXTRA_BACKUP_VOLUMES})
|
|
fi
|
|
|
|
if [[ "${#EXTRA_VOLUMES[@]}" -gt 0 ]]; then
|
|
ALL_VOLUMES+=("${EXTRA_VOLUMES[@]}")
|
|
fi
|
|
|
|
echo "Backing up named Docker volumes..."
|
|
declare -A seen_volumes=()
|
|
for volume_name in "${ALL_VOLUMES[@]}"; do
|
|
[[ -n "${volume_name}" ]] || continue
|
|
if [[ -n "${seen_volumes[${volume_name}]:-}" ]]; then
|
|
continue
|
|
fi
|
|
seen_volumes["${volume_name}"]=1
|
|
|
|
if ! docker_volume_exists "${volume_name}"; then
|
|
echo "Skipping missing volume: ${volume_name}"
|
|
continue
|
|
fi
|
|
|
|
echo " - ${volume_name}"
|
|
backup_named_volume "${volume_name}" "${VOLUME_BACKUP_DIR}/${volume_name}.tar.gz"
|
|
done
|
|
|
|
cat > "${BACKUP_DIR}/manifest.txt" <<EOF
|
|
project=${PROJECT_NAME}
|
|
created_at_utc=${TIMESTAMP}
|
|
database_backup=postgres.dump
|
|
uploads_backup=api-uploads.tar.gz
|
|
traefik_backup=traefik-letsencrypt.tar.gz
|
|
volume_backup_dir=volumes
|
|
EOF
|
|
|
|
echo "Backup complete:"
|
|
echo " - ${BACKUP_DIR}/postgres.dump"
|
|
echo " - ${BACKUP_DIR}/api-uploads.tar.gz"
|
|
if [[ -f "${BACKUP_DIR}/traefik-letsencrypt.tar.gz" ]]; then
|
|
echo " - ${BACKUP_DIR}/traefik-letsencrypt.tar.gz"
|
|
fi
|
|
if compgen -G "${VOLUME_BACKUP_DIR}/*.tar.gz" > /dev/null; then
|
|
echo " - ${VOLUME_BACKUP_DIR}/*.tar.gz"
|
|
fi
|
|
echo " - ${BACKUP_DIR}/manifest.txt"
|