Documentation
Everything you need to back up your VPS and recover from a disaster.
How it works
Run detect.sh on your VPS. It reads your running services, databases, and config — never modifies anything.
Paste the JSON manifest here. Configure your backup destination. Scripts are generated entirely in your browser — nothing is sent to our servers.
Place backup.sh on your server and schedule it. Store RUNBOOK.md somewhere safe. Sleep well.
Step 1 — Run detect.sh
SSH into your server and run as root. The script is read-only — it only reads system state and never installs, modifies, or deletes anything.
Option A — pipe directly (quick)
curl -fsSL https://gitlab.com/srmdn/recoverfast/-/raw/main/detect.sh | sudo bash
Option B — inspect first (recommended)
curl -fsSL https://gitlab.com/srmdn/recoverfast/-/raw/main/detect.sh -o detect.sh cat detect.sh # review the script sudo bash detect.sh
Save the output to a file
sudo bash detect.sh > manifest.json
Step 2 — Paste the manifest
Copy the JSON output from your terminal (or the contents of manifest.json)
and paste it into the text area on the app page.
Click Parse Manifest. RecoverFast will validate the JSON and show you a summary of what was detected.
Step 3 — Configure backup destination
Choose where your backups will be uploaded. RecoverFast supports object storage and remote servers via rsync:
| Destination | Type | Notes |
|---|---|---|
| AWS S3 | Object storage | Standard AWS credentials, no endpoint needed |
| Cloudflare R2 | Object storage | Free egress · endpoint required |
| Backblaze B2 | Object storage | S3-compatible · endpoint required |
| MinIO | Object storage (self-hosted) | Run on your own server · endpoint required |
| rsync over SSH | Storage VPS / remote server | No object storage needed · SSH key auth |
backup.sh or restore.sh to version control — they contain your access keys.
Step 4 — Download
Click Generate Scripts and download all three files:
backup.sh Dumps your databases, archives app directories, and uploads everything to your configured destination. Schedule this with cron.
restore.sh Step-by-step restore script. Downloads the backup, stops services, restores databases in the correct order, restores files, restarts services, and verifies.
RUNBOOK.md Human-readable disaster recovery document. Print it. Store it in a password manager, Notion, or anywhere outside your server.
Using the scripts
Placing backup.sh on your server
scp backup.sh root@your-server:/root/backup.sh ssh root@your-server chmod 700 /root/backup.sh # restrict to root only
Scheduling with cron
crontab -e # Add this line — runs daily at 2am 0 2 * * * /root/backup.sh >> /var/log/recoverfast-backup.log 2>&1
Running a manual backup
sudo bash /root/backup.sh
Listing available backups
sudo bash restore.sh list # recoverfast-backup-daily-20260308_020000 # recoverfast-backup-daily-20260307_020000 # recoverfast-backup-daily-20260306_020000
Running a restore
sudo bash restore.sh recoverfast-backup-daily-20260308_020000
Testing your restore
The safest way to test is with Docker on your local machine:
# Spin up a clean Ubuntu 24.04 container docker run --rm -it ubuntu:24.04 bash # Inside the container — install the same stack your server uses # (awscli is not in Ubuntu 24.04 apt — install via the official installer) apt-get update && apt-get install -y postgresql nginx curl unzip curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip unzip -q /tmp/awscliv2.zip -d /tmp && /tmp/aws/install # List and run the restore script # sudo bash restore.sh list # sudo bash restore.sh recoverfast-backup-daily-20260308_020000
If the restore completes without errors and your application data is intact, your backup is working correctly. Do this at least once when you first set it up, and again after major stack changes.
Failure notifications
When backup.sh runs unattended via cron, a silent failure means you
won't know your backups are broken until disaster strikes. The optional webhook field in RecoverFast embeds
a failure notification directly into the generated script — no external service required on our end.
How it works
The generated backup.sh registers an ERR trap.
If any command in the script exits with a non-zero status, the trap fires and sends a curl POST
to your webhook URL with the server hostname, backup label, and timestamp. The notification attempt never
blocks or fails the script itself.
ntfy.sh (recommended — easiest setup)
ntfy.sh is a free, open-source push notification service. No account needed — just pick a topic name and subscribe on your phone.
- Install the ntfy app on your phone (iOS or Android)
- Pick a private topic name, e.g.
myserver-backup-a7f3k(use something unguessable) - Subscribe to that topic in the app
- Paste
https://ntfy.sh/myserver-backup-a7f3kinto the webhook field
When a backup fails, you'll get a push notification instantly — even at 2am when cron runs.
Slack
The generated script sends a plain text POST. Slack's Incoming Webhooks expect a JSON payload, so you'll need to
edit one line in backup.sh after downloading:
# Replace the curl command in notify_failure() with:
curl -s --max-time 10 \
-H "Content-Type: application/json" \
-d '{"text": "RecoverFast backup FAILED — ${HOSTNAME} (${BACKUP_LABEL})"}' \
"$WEBHOOK_URL" >/dev/null 2>&1 || true Discord
Same as Slack — Discord webhooks require JSON with a content field:
# Replace the curl command in notify_failure() with:
curl -s --max-time 10 \
-H "Content-Type: application/json" \
-d '{"content": "RecoverFast backup FAILED — ${HOSTNAME} (${BACKUP_LABEL})"}' \
"$WEBHOOK_URL" >/dev/null 2>&1 || true Why not email?
Sending email from a shell script requires a working mail transfer agent (sendmail,
postfix, or msmtp) configured on the server,
plus an authenticated SMTP relay to avoid landing in spam. Most VPS setups don't have this out of the box —
it's a separate configuration task that often takes longer to set up than the backup itself.
Webhooks require nothing beyond curl, which is pre-installed on every
Ubuntu server. ntfy.sh in particular needs zero server-side setup — making it the better default for
unattended backup alerting.
Backup destinations
Cloudflare R2 (recommended)
Free egress, S3-compatible, generous free tier (10 GB/month free).
- Go to Cloudflare Dashboard → R2 → Create bucket
- Go to R2 → Manage R2 API Tokens → Create API token
- Copy Account ID, Access Key ID, Secret Access Key
- Endpoint format:
https://<account-id>.r2.cloudflarestorage.com
AWS S3
Standard S3. Create a dedicated IAM user with s3:PutObject, s3:GetObject, s3:ListBucket permissions on your backup bucket only. Never use your root account credentials.
Backblaze B2
S3-compatible API. Create a bucket, generate an application key with read/write access. Endpoint: https://s3.<region>.backblazeb2.com.
MinIO (self-hosted)
S3-compatible, runs on your own server. Useful if you want full control over where backups are stored.
- Install MinIO on a separate server or VPS
- Create a bucket and generate an access key/secret via the MinIO console
- Use your MinIO server URL as the endpoint:
https://minio.yourdomain.com
rsync over SSH (Storage VPS)
The most common self-hosted backup method. Sync backups to a cheap storage VPS (e.g. Hetzner Storage Box, any VPS with extra disk) using rsync over SSH. No object storage needed.
Setup on the storage server
# On your storage server — create a dedicated backup user adduser --disabled-password --gecos "" backupuser mkdir -p /mnt/backups/myserver chown backupuser:backupuser /mnt/backups/myserver
Setup SSH key authentication
# On your APP server (the one being backed up) — generate a dedicated key ssh-keygen -t ed25519 -f /root/.ssh/backup_key -N "" # Copy the public key to the storage server ssh-copy-id -i /root/.ssh/backup_key.pub backupuser@storage-server # Test the connection ssh -i /root/.ssh/backup_key backupuser@storage-server "echo OK"
RecoverFast config
| SSH Host | storage-server IP or hostname |
| SSH User | backupuser |
| SSH Port | 22 (or your custom port) |
| SSH Key Path | /root/.ssh/backup_key |
| Remote Path | /mnt/backups/myserver |
backupuser account to only what it needs — no sudo, no shell login if possible.
The key path is embedded in the script but the key itself is not.
FAQ
Is this safe to run on a production server?
Yes. detect.sh is read-only — it only inspects running services and configuration. It does not install, modify, or delete anything. You can read the full script before running it.
Does my manifest get sent to RecoverFast servers?
No. The entire app runs in your browser. Paste the manifest, generate the scripts — nothing leaves your machine. This app has no backend. You can verify this in browser devtools → Network tab.
My server uses a different distro. Will it work?
RecoverFast is tested on Ubuntu 22.04 and 24.04. Other Debian-based distros may work but are not officially supported yet. Open an issue to request support.
I changed my stack after running detect.sh. What do I do?
Re-run detect.sh to get a fresh manifest, then regenerate your scripts. The detect script always reads from the live server, so it reflects your current setup.
How is this different from my provider's snapshots?
Provider snapshots back up the entire OS image — expensive, heavy, and provider-locked. RecoverFast generates app-level backups (just your databases and files) that work on any VPS and include a step-by-step restore procedure.
Can I contribute?
Yes. See CONTRIBUTING.md for guidelines.