Skip to main content
skill CX Codex

backup-recovery — Claude Code skill: what it does, how to install

Configures backup and disaster recovery strategies using rsync and Restic. Useful for protecting data locally or in AWS S3 and Backblaze B2 following the 3-2-1 rule.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill backup-recovery -a claude-code
Open on GitHub

What backup-recovery does

The skill guides the agent through setting up backups for servers, databases, and application data. It provides rsync commands for local directories and remote SSH targets, including bandwidth limits, exclude patterns, and space-saving hard links with --link-dest.

It details Restic repository initialization on local disks, AWS S3, MinIO, Backblaze B2, and SFTP. It covers password management via dedicated files, streaming database dumps through stdin, snapshot retention policies with forget and prune, and mounting backups with FUSE.

Running these workflows requires rsync and restic (v0.16+ recommended) preinstalled on the host. Storage destinations need 2-3 times the source data capacity to maintain retention history. Cloud transfers will fail without configured AWS CLI or b2 CLI credentials.

What it helps with

  • configure incremental directory synchronization using rsync and hard links
  • initialize encrypted and deduplicated Restic repositories on AWS S3 or Backblaze B2
  • stream database dumps directly to backup repositories via stdin
  • restore individual files or mount historical snapshots using FUSE
  • automate snapshot retention rules with restic forget and prune

Example prompts for the agent

  • Configure an incremental backup for /data using rsync and --link-dest
  • Show me how to initialize a Restic repository in Backblaze B2
  • How do I set up a retention policy in Restic to keep 7 daily and 4 weekly snapshots?

How to install backup-recovery

1Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill backup-recovery -a claude-code

2Manually: put the files in place

~/.claude/skills/backup-recovery/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/backup-recovery/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about backup-recovery

How to install backup-recovery in Claude Code?

Run the command npx skills add BagelHole/DevOps-Security-Agent-Skills --skill backup-recovery -a claude-code.

What does the backup-recovery skill do?

It provides instructions and commands to set up automated backups and data recovery using rsync, Restic, and cloud storage backends.

What prerequisites are needed before configuring backups?

You need rsync and restic (v0.16+ recommended) installed, appropriate cloud CLI credentials for S3 or B2, and destination storage sized at 2-3 times the source data.

Source text

SKILL.md · MIT
---
name: backup-recovery
description: Implement backup and recovery strategies. Configure rsync, Restic, and cloud backups. Use when designing data protection solutions.
license: MIT
metadata:
  author: devops-skills
  version: "1.0"
---

# Backup and Recovery

Implement comprehensive backup and recovery strategies using rsync, Restic, and cloud storage backends. Covers the 3-2-1 rule, automated scheduling, S3/B2 backends, encryption, restore procedures, and verification testing.

## When to Use

- Designing a backup strategy for servers, databases, or application data
- Setting up Restic for encrypted, deduplicated backups to local or cloud storage
- Automating backups with systemd timers or cron
- Restoring data after accidental deletion, corruption, or disaster
- Migrating data between environments using backup/restore workflows
- Verifying backup integrity and testing recovery procedures

## Prerequisites

- `rsync` installed (included in most Linux distributions)
- `restic` installed (v0.16+ recommended)
- Cloud CLI configured for the backend: AWS CLI for S3, `b2` CLI for Backblaze B2
- Sufficient storage at the backup destination (2-3x source size for retention)
- SSH access for remote rsync targets
- `systemd` or `cron` for scheduling

## The 3-2-1 Backup Rule

- **3** copies of your data (1 primary + 2 backups)
- **2** different storage media or types (e.g., local disk + cloud)
- **1** copy offsite (cloud storage, remote datacenter)

## rsync Backups

### Basic Operations

```bash
# Sync a local directory to a backup location
rsync -avz --delete /data/ /backup/data/

# Flags explained:
# -a  archive mode (preserves permissions, ownership, timestamps, symlinks)
# -v  verbose output
# -z  compress data during transfer
# --delete  remove files at destination that no longer exist at source

# Sync to a remote server over SSH
rsync -avz -e "ssh -i ~/.ssh/backup_key" /data/ backup@remote:/backups/server01/

# Exclude patterns
rsync -avz --delete \
  --exclude='*.tmp' \
  --exclude='*.log' \
  --exclude='.cache/' \
  --exclude='node_modules/' \
  /data/ /backup/data/

# Use an exclude file for complex patterns
rsync -avz --delete --exclude-from=/etc/backup-excludes.txt /data/ /backup/data/

# Dry run (preview what would change)
rsync -avzn --delete /data/ /backup/data/

# Limit bandwidth to 50 MB/s and show progress
rsync -avz --bwlimit=50000 --progress /data/ backup@remote:/backups/
```

### Incremental Backups with Hard Links

```bash
# Incremental: unchanged files hard-linked to previous backup (saves space)
rsync -avz --delete \
  --link-dest=/backup/daily/latest \
  /data/ /backup/daily/$(date +%Y-%m-%d)/

# Update the 'latest' symlink
ln -snf /backup/daily/$(date +%Y-%m-%d) /backup/daily/latest

# Remove backups older than 30 days
find /backup/daily -maxdepth 1 -type d -name "20*" -mtime +30 -exec rm -rf {} \;
```

## Restic Backup

### Installation

```bash
# Debian / Ubuntu
apt install -y restic

# RHEL / CentOS
dnf install -y restic

# Or download the latest binary
curl -L https://github.com/restic/restic/releases/latest/download/restic_0.17.3_linux_amd64.bz2 \
  | bunzip2 > /usr/local/bin/restic
chmod +x /usr/local/bin/restic

# Verify installation
restic version
```

### Initialize a Repository

```bash
# Local repository
restic init --repo /backup/restic-repo

# AWS S3 backend
export AWS_ACCESS_KEY_ID="AKIAEXAMPLE"
export AWS_SECRET_ACCESS_KEY="secretkey"
restic init --repo s3:s3.amazonaws.com/my-backup-bucket

# S3-compatible (MinIO)
export AWS_ACCESS_KEY_ID="minioadmin"
export AWS_SECRET_ACCESS_KEY="miniosecret"
restic init --repo s3:http://minio.example.com:9000/backup-bucket

# Backblaze B2 backend
export B2_ACCOUNT_ID="accountid"
export B2_ACCOUNT_KEY="accountkey"
restic init --repo b2:my-backup-bucket:server01

# SFTP backend
restic init --repo sftp:backup@remote:/backups/server01

# Restic will prompt for a repository password -- store it securely
# Use a password file for automation
echo "my-secure-repo-password" > /etc/restic/password.txt
chmod 600 /etc/restic/password.txt
```

### Backup Operations

```bash
# Basic backup
restic backup /data --repo /backup/restic-repo --password-file /etc/restic/password.txt

# Backup multiple directories
restic backup /data /etc /var/lib/postgresql \
  --repo s3:s3.amazonaws.com/my-backup-bucket \
  --password-file /etc/restic/password.txt

# Backup with exclusions
restic backup /data \
  --exclude='*.tmp' \
  --exclude='*.log' \
  --exclude-file=/etc/restic/excludes.txt \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt

# Backup with tags (useful for filtering snapshots later)
restic backup /data \
  --tag server01 --tag production --tag daily \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt

# Backup stdin (e.g., database dump)
pg_dump -U postgres mydb | restic backup --stdin --stdin-filename mydb.sql \
  --repo s3:s3.amazonaws.com/my-backup-bucket \
  --password-file /etc/restic/password.txt

# Verbose output showing files processed
restic backup /data -v \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt
```

### Snapshot Management

```bash
# List all snapshots (add --tag <tag> to filter)
restic snapshots --repo /backup/restic-repo --password-file /etc/restic/password.txt

# Browse files in the latest snapshot
restic ls latest --repo /backup/restic-repo --password-file /etc/restic/password.txt

# Compare two snapshots
restic diff abc123 def456 --repo /backup/restic-repo --password-file /etc/restic/password.txt
```

### Retention Policy (forget + prune)

```bash
# Apply retention policy and reclaim space
restic forget \
  --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 3 \
  --prune \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt

# Dry run to preview what would be removed
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 \
  --dry-run --repo /backup/restic-repo --password-file /etc/restic/password.txt
```

### Restore Procedures

```bash
# Restore the latest snapshot to a target directory
restic restore latest --target /restore \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt

# Restore a specific snapshot by ID
restic restore abc123 --target /restore \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt

# Restore only specific files or directories
restic restore latest --target /restore --include "/data/config" \
  --repo /backup/restic-repo \
  --password-file /etc/restic/password.txt

# Mount a snapshot as a FUSE filesystem (browse and copy individual files)
mkdir -p /mnt/restic
restic mount /mnt/restic --repo /backup/restic-repo --password-file /etc/restic/password.txt &
# Browse: ls /mnt/restic/snapshots/latest/
# Unmount when done: umount /mnt/restic
```

### Verification

```bash
# Verify repository integrity (checks all data and metadata)
restic check --repo /backup/restic-repo --password-file /etc/restic/password.txt

# Full data verification (reads all pack files -- slow but thorough)
restic check --read-data --repo /backup/restic-repo --password-file /etc/restic/password.txt

# Verify a random subset of data (faster than full read)
restic check --read-data-subset=5% --repo /backup/restic-repo --password-file /etc/restic/password.txt
```

## Automated Backup with Environment File

### /etc/restic/env

```bash
# Repository configuration
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backup-bucket"
export RESTIC_PASSWORD_FILE="/etc/restic/password.txt"
export AWS_ACCESS_KEY_ID="AKIAEXAMPLE"
export AWS_SECRET_ACCESS_KEY="secretkey"

# Optional: set cache directory
export RESTIC_CACHE_DIR="/var/cache/restic"
```

### Backup Script

```bash
#!/bin/bash
# /usr/local/bin/restic-backup.sh
set -euo pipefail
source /etc/restic/env
LOG="/var/log/restic-backup.log"

echo "$(date): Starting backup" >> "$LOG"

restic backup /data /etc /var/lib/postgresql \
  --exclude-file=/etc/restic/excludes.txt \
  --tag "$(hostname)" --tag daily \
  --verbose >> "$LOG" 2>&1

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 \
  --prune >> "$LOG" 2>&1

# Weekly integrity check (Sundays)
[ "$(date +%u)" -eq 7 ] && restic check --read-data-subset=10% >> "$LOG" 2>&1

echo "$(date): Backup completed" >> "$LOG"
```

```bash
chmod +x /usr/local/bin/restic-backup.sh
```

## Scheduled Backups

### Systemd Timer (Recommended)

```ini
# /etc/systemd/system/restic-backup.service
[Unit]
Description=Restic backup
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/restic-backup.sh
Nice=10
IOSchedulingClass=idle
```

```ini
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run Restic backup daily at 2 AM

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=900

[Install]
WantedBy=timers.target
```

```bash
# Enable and start the timer
systemctl daemon-reload
systemctl enable --now restic-backup.timer

# Check timer status
systemctl list-timers restic-backup.timer

# Run manually for testing
systemctl start restic-backup.service
journalctl -u restic-backup.service -f
```

## Database Backups with Restic

```bash
# PostgreSQL: stream dump directly into restic (no temp file)
pg_dump -U postgres -Fc mydb | restic backup --stdin --stdin-filename mydb.dump \
  --tag postgres --tag mydb \
  --repo s3:s3.amazonaws.com/my-backup-bucket \
  --password-file /etc/restic/password.txt

# MySQL / MariaDB: stream dump into restic
mysqldump --all-databases --single-transaction | \
  restic backup --stdin --stdin-filename all-databases.sql \
  --tag mysql \
  --repo s3:s3.amazonaws.com/my-backup-bucket \
  --password-file /etc/restic/password.txt

# Restore PostgreSQL from restic
restic dump latest mydb.dump \
  --repo s3:s3.amazonaws.com/my-backup-bucket \
  --password-file /etc/restic/password.txt \
  | pg_restore -U postgres -d mydb --clean --if-exists
```

## Troubleshooting

| Symptom | Diagnostic Command | Common Fix |
|---|---|---|
| "repository not initialized" | `restic cat config --repo <repo>` | Run `restic init --repo <repo>` first |
| "wrong password" | Check env vars / password file | Verify RESTIC_PASSWORD_FILE contents and permissions |
| Backup is slow | `restic backup -v` for progress | Check network bandwidth; exclude large unneeded dirs |
| S3 permission denied | `aws s3 ls s3://bucket/` | Check IAM policy includes s3:GetObject, s3:PutObject |
| "unable to create lock" | `restic unlock --repo <repo>` | A previous backup crashed; unlock the repository |
| Restore shows empty dirs | `restic ls <snapshot-id>` | Verify correct snapshot ID; check --include path syntax |
| Repository growing too large | `restic stats --repo <repo>` | Run `restic forget --prune` with stricter retention |
| Check fails with pack errors | `restic check --read-data` | Rebuild index: `restic rebuild-index`; restore from another copy |

## Related Skills

- `linux-administration` -- Server maintenance and log management
- `systemd-services` -- Scheduling backups with systemd timers
- `object-storage` -- S3 and MinIO as backup destinations
- `block-storage` -- LVM snapshots for consistent backups
- `nfs-storage` -- Backing up NFS-shared data

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Similar skills

Everything for DevOps and infrastructure →

From the same set127

vulnerability-scanning A skill for finding and prioritizing CVEs across systems and dependencies with Nessus, OpenVAS, Qualys and Nuclei. Useful for audits and compliance work. CX Codex +1 424installs postgresql Guides PostgreSQL database administration, streaming replication, backups, and performance tuning. Useful when deploying or optimizing database instances. CX Codex +1 419installs ssl-tls-management A skill for SSL/TLS work: issuing Let's Encrypt certificates, automating renewal, running cert-manager in Kubernetes and checking cipher suites. Useful when you set up HTTPS or fix an expired cert. CX Codex +1 420installs hashicorp-vault A skill that walks your agent through HashiCorp Vault: secret engines, auth methods, policies and certificate issuance, without guessing CLI syntax. CX Codex +1 413installs database-backups A skill that helps your AI agent set up automated backups for PostgreSQL, MySQL and MongoDB, then verify that restores actually work. CX Codex +1 405installs sops-encryption A skill that walks your agent through encrypting configs and Kubernetes secrets with Mozilla SOPS, using AWS KMS, GCP KMS or PGP keys. Useful when secrets live in Git. CX Codex +1 403installs performance-tuning A skill for Linux performance work: kernel parameter tuning, bottleneck hunting, I/O scheduler and memory settings. Useful when a server lags or needs to survive a traffic spike. CX Codex +1 403installs podman Guides the agent to run daemonless and rootless containers with Podman. Handy for managing pods and generating systemd unit files. CX Codex +1 400installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor