34 lines
1.6 KiB
Bash
34 lines
1.6 KiB
Bash
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
compose_file="${COMPOSE_FILE:-compose.yaml}"
|
|
data_path="${MEMRELAY_DATA_PATH:-./data}"
|
|
output_dir="${BACKUP_DIR:-./backups}"
|
|
timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
archive="$output_dir/memrelay-$timestamp.tar.gz"
|
|
manifest="$output_dir/memrelay-$timestamp.json"
|
|
|
|
mkdir -p "$output_dir"
|
|
data_path="$(cd "$data_path" && pwd -P)"
|
|
output_dir="$(cd "$output_dir" && pwd -P)"
|
|
archive="$output_dir/memrelay-$timestamp.tar.gz"
|
|
manifest="$output_dir/memrelay-$timestamp.json"
|
|
images="$(docker compose -f "$compose_file" config --images | sort | paste -sd ',' -)"
|
|
docker compose -f "$compose_file" exec -T memrelay python -c \
|
|
"import os, sqlite3; p=os.path.join(os.environ.get('MEMRELAY_DATA_DIR', '/data/memrelay'), 'db', 'memrelay.sqlite3'); c=sqlite3.connect(p); print(c.execute('PRAGMA wal_checkpoint(TRUNCATE)').fetchone()); c.close()"
|
|
docker compose -f "$compose_file" stop
|
|
trap 'docker compose -f "$compose_file" start' EXIT INT TERM
|
|
if ! docker run --rm --user "$(id -u):$(id -g)" \
|
|
--mount "type=bind,source=$data_path,target=/source,readonly" \
|
|
--mount "type=bind,source=$output_dir,target=/backup" \
|
|
alpine:3.22 tar -czf "/backup/$(basename "$archive")" -C /source .; then
|
|
rm -f "$archive" "$archive.sha256" "$manifest"
|
|
exit 1
|
|
fi
|
|
hash="$(sha256sum "$archive" | awk '{print $1}')"
|
|
printf '%s %s\n' "$hash" "$(basename "$archive")" > "$archive.sha256"
|
|
printf '{"product":"MemRelay","created_at":"%s","archive":"%s","sha256":"%s","compose_file":"%s","images":"%s"}\n' \
|
|
"$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$(basename "$archive")" "$hash" "$compose_file" "$images" > "$manifest"
|
|
echo "Backup created: $archive"
|