42 lines
1.7 KiB
Bash
42 lines
1.7 KiB
Bash
#!/usr/bin/env bash
|
|
# Restores an archive produced by backup-server.sh. Existing server state requires --force.
|
|
set -euo pipefail
|
|
|
|
root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
archive=${1:-}
|
|
force=${2:-}
|
|
project=${PROJECT_NAME:-eternitymail}
|
|
staging=$(mktemp -d)
|
|
|
|
cleanup() { rm -rf "$staging"; }
|
|
trap cleanup EXIT
|
|
|
|
[[ -n "$archive" && -f "$archive" ]] || { echo "Usage: $0 /path/to/backup.tar.gz [--force]" >&2; exit 1; }
|
|
[[ "$force" == "--force" || ! -e "$root/.env" ]] || { echo "Refusing to overwrite an existing deployment without --force." >&2; exit 1; }
|
|
|
|
tar -C "$staging" -xzf "$archive"
|
|
(cd "$staging" && sha256sum -c SHA256SUMS)
|
|
|
|
if [[ "$force" == "--force" ]]; then
|
|
docker compose -f "$root/docker-compose.yml" --env-file "$root/.env" down || true
|
|
docker volume rm "${project}-stalwart-etc" "${project}-stalwart-data" "${project}-stalwart-certs" 2>/dev/null || true
|
|
rm -rf /opt/eternitymail/roundcube-db /opt/eternitymail/roundcube-config
|
|
fi
|
|
|
|
cp "$staging/.env" "$root/.env"
|
|
project=$(sed -n 's/^PROJECT_NAME=//p' "$root/.env" | head -n1)
|
|
project=${project:-eternitymail}
|
|
for volume in stalwart-etc stalwart-data stalwart-certs; do
|
|
docker volume create "${project}-${volume}" >/dev/null
|
|
docker run --rm -v "${project}-${volume}:/destination" -v "$staging:/backup:ro" alpine:3.21 \
|
|
tar -C /destination -xzf "/backup/volumes/${volume}.tar.gz"
|
|
done
|
|
|
|
for directory in roundcube-db roundcube-config; do
|
|
mkdir -p "/opt/eternitymail/${directory}"
|
|
docker run --rm -v "/opt/eternitymail/${directory}:/destination" -v "$staging:/backup:ro" alpine:3.21 \
|
|
tar -C /destination -xzf "/backup/bind-mounts/${directory}.tar.gz"
|
|
done
|
|
|
|
docker compose -f "$root/docker-compose.yml" --env-file "$root/.env" up -d
|
|
echo "Restore complete. Verify with: docker compose ps" |