Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/backup-restore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ on:
- "lib/docker.sh"
- "lib/env.sh"
- "lib/system.sh"
- "pasarguard.sh"
- "tests/backup_restore_roundtrip.sh"
- "tests/fresh_recovery_roundtrip.sh"
- "tests/unit_pasarguard.sh"
pull_request:
paths:
Expand All @@ -24,7 +26,9 @@ on:
- "lib/docker.sh"
- "lib/env.sh"
- "lib/system.sh"
- "pasarguard.sh"
- "tests/backup_restore_roundtrip.sh"
- "tests/fresh_recovery_roundtrip.sh"
- "tests/unit_pasarguard.sh"
workflow_dispatch:

Expand Down Expand Up @@ -80,3 +84,43 @@ jobs:
TIMESCALE_TARGET_IMAGE: timescale/timescaledb:2.28.3-pg17
TIMESCALEDB_COMPAT_IMAGE: timescale/timescaledb-ha:pg17-ts2.28-all
run: bash tests/backup_restore_roundtrip.sh timescaledb single

fresh-recovery:
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
database:
- sqlite
- mysql
- mariadb
- postgresql
- timescaledb
healthcheck:
- healthcheck
include:
- database: mysql
healthcheck: no-healthcheck
- database: mariadb
healthcheck: no-healthcheck
- database: postgresql
healthcheck: no-healthcheck

steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install test dependencies
run: |
sudo apt-get update
sudo apt-get install -y rsync zip unzip sqlite3 jq

# Removes the source installation and its images, so --fresh has to pull
# the recorded digests and recreate the Compose image names.
- name: Recover a removed installation with restore --fresh
env:
FRESH_PULL_IMAGES: "true"
run: sudo -E bash tests/fresh_recovery_roundtrip.sh "${{ matrix.database }}" "${{ matrix.healthcheck }}"
4 changes: 2 additions & 2 deletions .github/workflows/command-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Install archive tooling for restore-safety tests
run: sudo apt-get update && sudo apt-get install -y zip unzip
- name: Install archive tooling for restore tests
run: sudo apt-get update && sudo apt-get install -y zip unzip sqlite3 jq
- name: Run all unit tests
run: bash tests/run_all.sh
36 changes: 28 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,14 +232,34 @@ PasarGuard supports 5 database engines tailored for different workloads:

## 💾 Backups & Disaster Recovery

PasarGuard features an automated disaster recovery engine:
1. **Atomic Dumps**: Creates consistent snapshots. SQLite WAL files are safely truncated, and PostgreSQL/TimescaleDB clusters are dumped with explicit table manifests and role permissions.
2. **Scheduled Telegram Dispatch**: Configure recurring cron intervals (from 5 minutes to daily) using `pasarguard backup-service`. Backups are dispatched directly to your Telegram chat or channel.
3. **Proxy Support**: Connect via SOCKS5 or HTTP proxy (`BACKUP_PROXY_URL`) to bypass Telegram network restrictions.
4. **TimescaleDB Version Safety Preflight**: The restore engine validates source and destination TimescaleDB extension versions, enforcing a fail-closed safety gate that skips mismatched databases before modifying live data.
5. **Fail-Safe Rollback**: Rejects truncated dumps and path traversal attacks before touching live data. If a restore encounters issues, diagnostics are logged to `/opt/pasarguard/backup/pasarguard_restore_error.log`.

👉 *Read the disaster recovery runbook in [docs/backup-and-restore.md](docs/backup-and-restore.md).*
The management script backs up application settings, persistent files and
consistent database snapshots. New backups also record actual image digests,
source database versions and a SHA256 payload inventory.

- Run `pasarguard backup` for an immediate backup, or configure scheduled Telegram
delivery with `pasarguard backup-service` (including optional HTTP/SOCKS proxy).
- Use `pasarguard restore /path/to/backup.zip --check` to validate a downloaded
archive and display its source versions without changing services.
- Ordinary restore checks engine/version compatibility and supports TimescaleDB
conversion using a temporary container. SQL imports do not provide whole-host
rollback; keep a separate backup before replacing an existing installation.

### Recover when the original server is gone

Install only the management script on the new host (`install-script`), copy the
complete backup there, then run:

```bash
sudo pasarguard restore /root/backup.zip --check
sudo pasarguard restore /root/backup.zip --fresh
```

Fresh recovery uses the images recorded in a new backup and starts the database
before the panel. It refuses existing storage and never guesses the source
version from `latest`. Legacy archives remain supported by ordinary restore.
See the [English recovery runbook](docs/backup-and-restore.md) or
[راهنمای فارسی بازیابی](docs/backup-and-restore.fa.md) for old backups,
multipart archives, offline images, and post-recovery checks.

---

Expand Down
Loading
Loading