#!/usr/bin/env bash # Creates a consistent, portable backup of Stalwart, Roundcube, and deployment settings. set -euo pipefail root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) destination=${1:-"$root/backups"} project=${PROJECT_NAME:-eternitymail} timestamp=$(date -u +%Y%m%dT%H%M%SZ) staging=$(mktemp -d) archive="$destination/${project}-${timestamp}.tar.gz" cleanup() { rm -rf "$staging" docker compose -f "$root/docker-compose.yml" --env-file "$root/.env" start >/dev/null 2>&1 || true } trap cleanup EXIT [[ -f "$root/.env" ]] || { echo "Missing $root/.env" >&2; exit 1; } mkdir -p "$destination" docker compose -f "$root/docker-compose.yml" --env-file "$root/.env" stop mkdir -p "$staging/volumes" "$staging/bind-mounts" cp "$root/.env" "$root/docker-compose.yml" "$staging/" for volume in stalwart-etc stalwart-data stalwart-certs; do docker run --rm -v "${project}-${volume}:/source:ro" -v "$staging:/backup" alpine:3.21 \ tar -C /source -czf "/backup/volumes/${volume}.tar.gz" . done for directory in roundcube-db roundcube-config; do docker run --rm -v "/opt/eternitymail/${directory}:/source:ro" -v "$staging:/backup" alpine:3.21 \ tar -C /source -czf "/backup/bind-mounts/${directory}.tar.gz" . done sha256sum "$staging"/.env "$staging"/docker-compose.yml "$staging"/volumes/*.tar.gz "$staging"/bind-mounts/*.tar.gz > "$staging/SHA256SUMS" tar -C "$staging" -czf "$archive" . echo "Backup created: $archive"