How to Set Up Incremental Backups with Restic and S3-Compatible Storage (Fast, Encrypted, and Automated)

Modern backups are not just about copying files to an external disk. If you manage a Linux server, a development workstation, or even a home lab, you need backups that are incremental, encrypted, and easy to restore. In this tutorial, you’ll configure restic (a fast, deduplicating backup tool) to send backups to S3-compatible object storage such as MinIO, Backblaze B2 (S3 API), Wasabi, or an on-prem S3 gateway. The result is a secure backup setup that scales well and can be automated with systemd.

Why restic + S3 is a strong backup combo

Restic is popular because it encrypts data before it leaves your machine, stores only changed blocks (deduplication), and keeps snapshots you can browse and restore from. Pairing it with S3-compatible storage makes your backups resilient: object storage is designed for durability, and you can back up over the network without mounting remote filesystems.

Prerequisites

You’ll need a Linux machine (Debian/Ubuntu/Fedora/AlmaLinux all work), an S3 endpoint (cloud or self-hosted), and credentials (access key and secret key). Make sure the target bucket exists or that your provider allows creating it via API. Also decide what to back up: typical choices are /etc, application configs, and data directories like /srv or /var/lib (be careful with databases; see notes below).

Step 1: Install restic

On Ubuntu/Debian:

sudo apt update && sudo apt install -y restic

On Fedora:

sudo dnf install -y restic

Verify:

restic version

Step 2: Export S3 credentials securely

Restic uses environment variables for S3 credentials. For a quick test in your current shell:

export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"

export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"

If you’re using a non-AWS endpoint (MinIO, Wasabi, etc.), also set a custom endpoint URL:

export AWS_DEFAULT_REGION="us-east-1"

export RESTIC_REPOSITORY="s3:https://s3.example.com/my-restic-bucket"

For AWS S3, your repository might look like:

export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-restic-bucket"

Step 3: Initialize the backup repository

Initialize once per repository. Restic will prompt for a repository password (this is used for encryption):

restic init

Store this password carefully. If you lose it, you cannot decrypt your backups.

Step 4: Run your first incremental backup

Start with a small but meaningful set of paths. Example:

restic backup /etc /home --exclude /home/*/.cache

Run the same command again later and you’ll get an incremental snapshot: restic will upload only what changed. To see what was saved:

restic snapshots

To verify repository integrity (recommended after initial setup):

restic check

Step 5: Create a smart retention policy (forget + prune)

Backups are only useful if they don’t grow forever. Restic can enforce retention rules and remove unneeded data. A common policy is: keep daily backups for 7 days, weekly for 4 weeks, and monthly for 12 months:

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

The --prune flag actually removes unreferenced data, reclaiming space in the S3 bucket.

Step 6: Automate backups with systemd (service + timer)

For reliable automation, use a systemd timer instead of cron. Create an environment file that root can read, for example:

sudo nano /etc/restic.env

Add:

AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY

AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY

AWS_DEFAULT_REGION=us-east-1

RESTIC_REPOSITORY=s3:https://s3.example.com/my-restic-bucket

RESTIC_PASSWORD=YOUR_STRONG_REPO_PASSWORD

Now create the service unit:

sudo nano /etc/systemd/system/restic-backup.service

Example content:

[Unit]
Description=Restic Backup
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic.env
ExecStart=/usr/bin/restic backup /etc /home --exclude /home/*/.cache
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

[Install]
WantedBy=multi-user.target

Create the timer:

sudo nano /etc/systemd/system/restic-backup.timer

Example content:

[Unit]
Description=Run Restic Backup Daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Enable and start:

sudo systemctl daemon-reload

sudo systemctl enable --now restic-backup.timer

Check status and logs:

systemctl list-timers | grep restic

journalctl -u restic-backup.service -e

Step 7: Test a restore (don’t skip this)

A backup you haven’t restored from is just a hope. List snapshots, pick one, then restore to a temporary directory:

restic snapshots

restic restore latest --target /tmp/restic-restore-test

To restore a single file or folder, you can use restic dump or browse snapshots with restic ls to find the path.

Practical notes for servers and databases

If you back up database files directly (like PostgreSQL under /var/lib/postgresql), you risk capturing inconsistent data. Prefer application-aware backups: use pg_dump for PostgreSQL, mysqldump for MySQL/MariaDB, or filesystem snapshots (LVM/ZFS) followed by restic. Also exclude large volatile paths such as caches, build folders, and container image layers unless you truly need them.

Conclusion

With restic and S3-compatible storage, you get fast incremental backups, strong encryption, simple retention rules, and clean automation through systemd timers. Once you’ve tested restores and verified the schedule, you’ll have a backup system that behaves like a reliable utility: quiet when it works, loud when it fails, and easy to trust when disaster strikes.

How to Build a Reliable Backup with Restic and S3-Compatible Storage (With Encryption and Automation)

A modern backup should be encrypted, versioned, and easy to restore under pressure. If you are still copying folders to an external disk or relying on a single cloud sync tool, you are one hardware failure or ransomware incident away from a bad day. In this tutorial, you will set up restic (a fast, encrypted backup tool) to back up a Linux server to S3-compatible object storage such as MinIO, Backblaze B2 (S3 API), Wasabi, or many private cloud providers.

The goal is to create a backup that is secure by design (client-side encryption), storage-efficient (deduplication), and maintainable (automatic scheduling and retention policies). The same approach works for a VPS, a home server, or a small business file server.

What You Need

Prerequisites: a Linux machine (Ubuntu/Debian examples here), network access to your S3-compatible endpoint, and an S3 access key/secret key with permission to read and write to a bucket. You should also have enough disk space for temporary operations and stable time synchronization (NTP) to avoid confusing logs.

Step 1: Install Restic

On Ubuntu/Debian, restic is available via the package manager. Install it and confirm the version:

Commands:

sudo apt update
sudo apt install -y restic
restic version

If your distribution ships an older build and you need a newer version (for example, due to S3 compatibility fixes), you can install from the official release packages. For many environments, the repository version is sufficient and keeps updates simple.

Step 2: Prepare S3 Credentials and Repository Settings

Restic reads S3 configuration from environment variables. Create a restricted bucket for backups (for example, server-backups) and then define the repository URL like this:

export RESTIC_REPOSITORY="s3:https://s3.example.com/server-backups/restic-repo"

Set the credentials and optional endpoint tuning variables. Replace values to match your provider:

export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"

If your provider requires a specific region value (some do, some ignore it), add:

export AWS_DEFAULT_REGION="us-east-1"

Tip: avoid leaving secrets in shell history. In production, store these in a root-only file and load them from a systemd service (shown later).

Step 3: Initialize the Backup Repository (Encryption Starts Here)

Initialize a new restic repository. You will be prompted to set a password; this password encrypts metadata and data before it leaves your server:

restic init

Choose a long passphrase and store it in a password manager. If you lose it, your backups will be unusable. That is the tradeoff of true zero-knowledge encryption.

Step 4: Run Your First Backup

Start with a simple backup of a few important paths (adjust to your system). For example, system configuration and application data:

restic backup /etc /home /var/www

Restic automatically deduplicates blocks, so subsequent backups are usually much faster and smaller. After the backup completes, list snapshots:

restic snapshots

Step 5: Add Exclusions for Noise and Speed

You typically do not want to back up caches, temporary folders, or large rebuildable directories. Create an exclusions file:

sudo nano /etc/restic-excludes.txt

Example exclusions:

/var/cache
/tmp
/var/tmp
/home/*/.cache

Run the backup using the exclude list:

restic backup / --exclude-file=/etc/restic-excludes.txt

Backing up the entire root filesystem can be useful on smaller servers, but consider carefully if you have databases or constantly changing log files. For databases, consistent dumps (or snapshots) are usually better than copying live files.

Step 6: Apply a Retention Policy (Forgetfulness Is a Feature)

Without cleanup, backups grow forever. Restic includes a clear retention mechanism via forget and prune. A common policy is “daily for 7 days, weekly for 4 weeks, monthly for 12 months”:

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

This removes old snapshots while keeping enough restore points to cover mistakes that are discovered late.

Step 7: Automate Backups with systemd (Safer Than Cron for Secrets)

Create an environment file that only root can read:

sudo nano /etc/restic.env
sudo chmod 600 /etc/restic.env

Add variables (example):

RESTIC_REPOSITORY=s3:https://s3.example.com/server-backups/restic-repo
AWS_ACCESS_KEY_ID=YOUR_ACCESS_KEY
AWS_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
AWS_DEFAULT_REGION=us-east-1
RESTIC_PASSWORD=YOUR_LONG_REPO_PASSWORD

Now create a systemd service:

sudo nano /etc/systemd/system/restic-backup.service

Service content:

[Unit]
Description=Restic Backup to S3
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic.env
ExecStart=/usr/bin/restic backup /etc /home /var/www --exclude-file=/etc/restic-excludes.txt
ExecStartPost=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

Create a timer to run nightly:

sudo nano /etc/systemd/system/restic-backup.timer

Timer content:

[Unit]
Description=Run Restic Backup Nightly

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

[Install]
WantedBy=timers.target

Enable and start the timer:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
systemctl list-timers | grep restic

Step 8: Test Restore (The Part People Skip)

A backup is only real if it restores. Pick a small file and test a restore to a safe directory:

mkdir -p /tmp/restic-restore-test
restic snapshots
restic restore latest --target /tmp/restic-restore-test

If you only need one file, use restic ls to locate it and then restore selectively, or mount the repository for browsing (useful for investigations and audits). Build the habit of monthly restore tests, especially before major upgrades.

Common Troubleshooting Tips

403 Access Denied: confirm the bucket policy and credentials. Ensure the key has permission for list, get, put, and delete operations in the backup prefix.

Slow uploads: check MTU issues, DNS, and consider running backups during off-peak hours. For some providers, setting an explicit region or endpoint URL is required for stable performance.

Password failures in automation: verify RESTIC_PASSWORD is correctly set in /etc/restic.env and that the file permissions are restrictive.

With restic and S3-compatible storage, you get encrypted, deduplicated backups that are easy to automate and straightforward to restore. Once the basics are working, the next upgrade is adding alerting (email or webhook on failure) and keeping a second copy in another region or provider for true disaster recovery.

Set Up Encrypted Restic Backups to S3 (Backblaze B2 or Cloudflare R2) on Linux and Windows

Why restic + S3 is a great backup combo in 2025

Restic is a fast, open-source, and cross-platform backup tool that encrypts data by default and deduplicates efficiently. Pairing restic with an S3-compatible storage such as Backblaze B2 or Cloudflare R2 gives you affordable, durable, and offsite backups. In this step-by-step guide, you will install restic on Linux and Windows, connect it to an S3 bucket, automate backups, and set safe retention and restore procedures.

Prerequisites

You need an S3-compatible bucket, an access key ID and secret, and the bucket’s endpoint. For Backblaze B2, create a bucket and application key in the B2 console; for Cloudflare R2, create an R2 bucket and a token with S3 API access and note the account-specific endpoint (e.g., https://ACCOUNTID.r2.cloudflarestorage.com). Keep these credentials safe.

Install restic

Linux (Ubuntu/Debian/Fedora/Arch): Use your package manager or the official release binary. Example on Ubuntu 24.04: sudo apt update && sudo apt install restic. Verify with restic version. If your distro ships an older version, download the latest from the restic GitHub releases, place it in /usr/local/bin, and make it executable with chmod +x.

Windows 10/11: Download the latest restic .exe from the official releases page and place it in a directory on your PATH (e.g., C:\Tools\restic\ and add that folder to System PATH). Confirm with restic version in Windows Terminal or PowerShell.

Set environment variables securely

Restic reads credentials from environment variables. Create a small environment file you can source (Linux) or a script (Windows). For S3-compatible providers you’ll typically set:

RESTIC_REPOSITORY=s3:s3.amazonaws.com/your-bucket-name
RESTIC_PASSWORD=YourStrongPassphrase
AWS_ACCESS_KEY_ID=AKIA...orR2Key
AWS_SECRET_ACCESS_KEY=YourSecretHere
AWS_DEFAULT_REGION=us-east-1
AWS_ENDPOINT=https://ACCOUNTID.r2.cloudflarestorage.com (only for R2 or other non-AWS S3)

On Linux, store the password in a file for safety and reference it with RESTIC_PASSWORD_FILE=/path/to/pass.txt instead of RESTIC_PASSWORD. On Windows, use a .cmd script that sets these variables before running restic. Avoid committing credentials to Git or sharing them in logs.

Initialize the repository and run a first backup

Export or set your environment variables, then initialize the repo once:

restic init

Back up a test folder:

restic backup ~/Documents --tag initial

Windows users can back up with Volume Shadow Copy to avoid locked-file issues: run the terminal as Administrator and use restic backup C:\Users\YourName\Documents --use-fs-snapshot --tag initial.

Exclude files and speed tips

Create an exclude file to skip caches, node_modules, or VM images that you back up elsewhere. Example entries: *.iso, *.vdi, */.cache/*, */node_modules/*. Then call restic backup /data --exclude-file /etc/restic/excludes.txt --one-file-system. For slower links, cap bandwidth: --limit-upload 4 (MiB/s).

Schedule automatic backups

Linux with systemd: Create a small script at /usr/local/bin/restic-backup.sh that exports variables (or sources an .env file) and runs backup, forget, and prune. Minimal content:

#!/usr/bin/env bash
set -euo pipefail
source /etc/restic/env
restic backup /home /etc --exclude-file /etc/restic/excludes.txt --tag daily
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
restic check --read-data-subset=1%

Create a service /etc/systemd/system/restic-backup.service:

[Unit] Description=Restic backup
[Service] Type=oneshot ExecStart=/usr/local/bin/restic-backup.sh

Create a timer /etc/systemd/system/restic-backup.timer:

[Unit] Description=Run restic daily
[Timer] OnCalendar=daily Persistent=true
[Install] WantedBy=timers.target

Enable with sudo systemctl enable --now restic-backup.timer. Check status via systemctl list-timers.

Windows with Task Scheduler: Put a script at C:\Scripts\restic-backup.cmd:

set RESTIC_REPOSITORY=s3:s3.amazonaws.com\your-bucket
set RESTIC_PASSWORD_FILE=C:\Scripts\restic-pass.txt
set AWS_ACCESS_KEY_ID=...
set AWS_SECRET_ACCESS_KEY=...
restic backup C:\Users\YourName --use-fs-snapshot --tag daily
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
restic check --read-data-subset=1%

Create a Basic Task to run daily with highest privileges, start in C:\Scripts, and point to the script. Review the History tab for errors.

Verify, prune, and restore

Use forget + prune to enforce retention (e.g., 7 daily, 4 weekly, 12 monthly). Always run restic check periodically. To see snapshots, run restic snapshots. To restore the latest snapshot to a folder:

restic restore latest --target /restore

On Windows: restic restore latest --target D:\Restores. For a single path inside a snapshot, add --include (e.g., --include "/home/user/Documents").

Health checks and notifications

Add a final step that pings a monitoring URL (e.g., Healthchecks.io) only if the backup succeeded. Append to your script: curl -fsS https://hc.example/ping/UUID. If the cron or timer fails, you’ll get an alert.

Troubleshooting

Repository does not exist: Run restic init with the correct environment, bucket, and endpoint. For Cloudflare R2, set AWS_ENDPOINT and omit a region if required.

Access denied: Check your IAM or API token permissions for list/get/put/delete on the bucket. Ensure the bucket name matches exactly.

Slow or flaky uploads: Use --limit-upload, increase --retry-interval, and ensure no ISP or firewall is blocking the endpoint. Consider enabling object-level lifecycle policies on the provider to reduce storage costs for old versions.

Locked or in-use files on Windows: Run terminal as Administrator and use --use-fs-snapshot.

Security best practices

Use a long, unique passphrase; prefer RESTIC_PASSWORD_FILE over inline passwords. Restrict API keys to the specific bucket. Do not share your password or keys—anyone with both can read your backups. If your provider supports immutability (e.g., B2 Object Lock), consider a write-once policy for ransomware protection and adjust restic operations accordingly.

Wrap-up

You now have encrypted, deduplicated, and automated backups to S3-compatible storage using restic on Linux and Windows. Test restores regularly, monitor your backup jobs, and keep your credentials and retention policies tidy. This setup scales from a single laptop to multiple servers with minimal changes, giving you reliable offsite backups at low cost.

How to Back Up Linux Servers to Backblaze B2 with Restic and Rclone (Encrypted, Automated, Pruned)

Summary: This guide shows how to back up a Linux server to Backblaze B2 using Restic with Rclone as the transport. You will set up encryption, implement a retention policy, automate runs with systemd timers, and test restores. The result is a fast, encrypted, and low-cost off-site backup that you control.

Why Restic + Rclone + Backblaze B2?

Restic is a modern, deduplicating backup tool with built-in encryption. Rclone provides wide storage compatibility and reliable transfers. Backblaze B2 offers affordable object storage with per-GB pricing. Together, they form a portable, verifiable, and cost-effective backup solution that works on any Linux distribution.

Prerequisites

- A Linux server (Ubuntu/Debian/RHEL/AlmaLinux, etc.) with sudo/root access
- Backblaze B2 account
- Basic terminal familiarity

Step 1: Create a B2 Bucket and Key

1) In Backblaze, create a bucket (e.g., mycompany-backups). Leave it private.
2) Create an Application Key restricted to that bucket. Copy the KeyID and Application Key now; you will not see the secret again.

Step 2: Install Restic and Rclone

sudo apt update && sudo apt install -y restic rclone

On RHEL/Fedora-based systems:
sudo dnf install -y restic rclone

Step 3: Configure Rclone for B2

We will keep Rclone’s config out of your home directory for clarity.

sudo mkdir -p /etc/rclone
sudo chmod 750 /etc/rclone

sudo rclone config create b2 b2 account <KeyID> key <ApplicationKey> hard_delete true --config /etc/rclone/rclone.conf

Verify the config:

sudo rclone lsd b2: --config /etc/rclone/rclone.conf

Step 4: Initialize the Restic Repository (via Rclone)

Create a password file and initialize the repository path inside the bucket.

sudo mkdir -p /etc/restic
echo "choose-a-strong-long-passphrase" | sudo tee /etc/restic/password > /dev/null
sudo chmod 600 /etc/restic/password

Initialize:

sudo env RCLONE_CONFIG=/etc/rclone/rclone.conf restic -r rclone:b2:mycompany-backups/restic --password-file /etc/restic/password init

Step 5: Exclusions and Environment File

Define what not to back up (caches, runtime, VM disks, etc.).

sudo tee /etc/restic/excludes.txt > /dev/null <<'EOF'
/proc/**
/sys/**
/dev/**
/run/**
/tmp/**
/var/tmp/**
/var/cache/**
*.iso
*.img
*.qcow2
EOF

Create an environment file to avoid repeating flags:

sudo tee /etc/restic/restic.env > /dev/null <<'EOF'
RESTIC_REPOSITORY=rclone:b2:mycompany-backups/restic
RESTIC_PASSWORD_FILE=/etc/restic/password
RCLONE_CONFIG=/etc/rclone/rclone.conf
RESTIC_CACHE_DIR=/var/cache/restic
EOF
sudo mkdir -p /var/cache/restic && sudo chown root:root /var/cache/restic && sudo chmod 700 /var/cache/restic

Step 6: Create a Backup Script

This script performs a backup, applies retention, and verifies the repository.

sudo tee /usr/local/bin/restic-backup.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

# Sources to back up (adjust to your server)
SOURCES=(/etc /home /var/www)

# Nice/ionice to reduce system impact
nice -n 10 ionice -c2 -n7 \

env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) \\
restic backup "${SOURCES[@]}" --exclude-file /etc/restic/excludes.txt --tag scheduled --one-file-system

# Retention policy: keep last 7 daily, 4 weekly, 6 monthly
env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) \\
restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --tag scheduled

# Optional consistency check (weekly via timer, or keep here for every run)
env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic check --read-data-subset=1/20 || true
EOF
sudo chmod 750 /usr/local/bin/restic-backup.sh

Step 7: systemd Service and Timer

Create a systemd unit to run the script, and a timer to schedule it daily.

sudo tee /etc/systemd/system/restic-backup.service > /dev/null <<'EOF'
[Unit]
Description=Restic backup to Backblaze B2 (via rclone)
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/restic.env
ExecStart=/usr/local/bin/restic-backup.sh
Nice=10
IOSchedulingClass=best-effort
IOSchedulingPriority=7
PrivateTmp=yes
NoNewPrivileges=yes
ProtectSystem=full
ProtectHome=yes
ProtectKernelLogs=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
LockPersonality=yes
MemoryDenyWriteExecute=yes

[Install]
WantedBy=multi-user.target
EOF

sudo tee /etc/systemd/system/restic-backup.timer > /dev/null <<'EOF'
[Unit]
Description=Daily Restic backup timer

[Timer]
OnCalendar=03:15
RandomizedDelaySec=20m
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer

Step 8: First Run and Verification

Trigger a manual run and watch the output:

sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -n 200 -f

List snapshots to confirm:

sudo env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic snapshots

Step 9: Tune Retention and Costs

Adjust the restic forget policy to meet recovery objectives and budget. More aggressive pruning reduces storage but limits historical versions. Backblaze B2 costs depend on stored GB, transaction counts, and egress; deduplication in Restic helps keep usage low.

Step 10: Test a Restore

Never trust backups you have not restored. Create a temporary restore folder and recover a small file.

sudo mkdir -p /tmp/restore-test
sudo env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic restore latest --target /tmp/restore-test --include /etc/hostname
ls -l /tmp/restore-test/etc/hostname

Security Best Practices

- Use a long, unique Restic password stored in a root-only file.
- Restrict the Backblaze Application Key to one bucket with minimal permissions.
- Enable MFA on your Backblaze account.
- Keep /etc/rclone/rclone.conf and /etc/restic/password mode 600 and owned by root.
- Consider server-side encryption on B2 as a secondary layer if required by policy, although Restic already encrypts data client-side.

Performance Tips

- Parallel uploads: Restic auto-tunes, but you can increase concurrency on bigger servers via RESTIC_OPTIONS like --jobs 4 for backups or use Rclone env vars (RCLONE_B2_UPLOAD_CONCURRENCY).
- Bandwidth limits: Add --limit-upload 4MiB to Restic, or --bwlimit via Rclone if needed.
- Exclude large/ephemeral paths to reduce churn.

Troubleshooting

Fatal: wrong password or no key found: The password in /etc/restic/password does not match the repository. Fix the password file or re-init a new repo.

Repository locked: A previous run crashed. Remove stale locks only when you are certain no job is running:
sudo env $(grep -v '^\s*#' /etc/restic/restic.env | xargs) restic unlock

Slow uploads or timeouts: Check outbound bandwidth, raise concurrency, and ensure your firewall allows long-lived HTTPS connections. Try adding a randomized delay (already in the timer) to avoid contention on shared links.

What You Achieved

You now have an automated, encrypted, off-site backup pipeline for Linux using Restic, Rclone, and Backblaze B2. Snapshots are deduplicated, retention is enforced, and restores are provable. Regularly verify snapshots, monitor storage usage, and adjust policies as your data grows.

How to Back Up to Backblaze B2 with Restic: Installation, Automation, and Pruning (Linux and Windows)

Overview

Backups should be encrypted, efficient, and easy to automate. Restic meets all three goals: it is a fast, deduplicating, and end‑to‑end encrypted backup tool that works on Linux, Windows, and macOS. In this guide, you will learn how to back up files to Backblaze B2, schedule automatic runs, set a sensible retention policy, and verify your data. The steps cover both Linux and Windows with actionable commands and clear defaults you can copy and adapt.

Why Restic + Backblaze B2

Restic encrypts everything (including filenames) before it leaves your machine. It also deduplicates data, so repeating backups are small and fast. Backblaze B2 is affordable object storage with predictable pricing and a robust API that restic supports natively. The combination gives you offsite, encrypted, incremental backups you can restore from any machine.

Prerequisites

You need a Backblaze B2 account, a bucket created for backups, and an Application Key with permissions limited to that bucket (read, write, list, delete). Note the Key ID and Key. Decide on a repository path such as b2:my-backups:laptop01 so multiple devices can share one bucket cleanly.

Step 1 — Install Restic

Linux (Debian/Ubuntu): sudo apt update && sudo apt install restic. On other distributions, use your package manager or the official binary release. Verify with restic version.

Windows 10/11: Install via Winget: winget install restic.restic. Or via Chocolatey: choco install restic. Verify with restic version in PowerShell.

Step 2 — Configure Environment and Initialize the Repository

Linux: Export the following environment variables in your shell or place them into a root‑readable file such as /etc/restic/env and source it in your scripts.

export B2_ACCOUNT_ID="YOUR_KEY_ID"
export B2_ACCOUNT_KEY="YOUR_APP_KEY"
export RESTIC_REPOSITORY="b2:my-backups:laptop01"
export RESTIC_PASSWORD_FILE="/etc/restic/pass"

Create the password file with strong permissions and a long random passphrase: sudo install -m 600 /dev/null /etc/restic/pass then sudo sh -c 'openssl rand -base64 48 > /etc/restic/pass'. Initialize the repository: restic init. If successful, you will see “created restic repository.”

Windows: In PowerShell, create C:\restic\env.ps1 with:
$env:B2_ACCOUNT_ID="YOUR_KEY_ID"
$env:B2_ACCOUNT_KEY="YOUR_APP_KEY"
$env:RESTIC_REPOSITORY="b2:my-backups:laptop01"
$env:RESTIC_PASSWORD_FILE="C:\restic\pass.txt"

Generate a passphrase: New-Guid | Out-File C:\restic\pass.txt -Encoding ascii (or choose your own). Then run: powershell -ExecutionPolicy Bypass -File C:\restic\env.ps1; restic init.

Step 3 — Choose What to Back Up and What to Skip

Create an exclude file to avoid caches, temp folders, and large throwaway data. Examples:

# Linux excludes
/proc
/sys
/dev
/tmp
/var/tmp
/var/cache
*.ISO

# Windows excludes
C:\Windows\Temp
C:\Users\*\AppData\Local\Temp
*.iso
*.vhdx

Step 4 — Run Your First Backup

Linux: sudo --preserve-env=B2_ACCOUNT_ID,B2_ACCOUNT_KEY,RESTIC_REPOSITORY,RESTIC_PASSWORD_FILE restic backup /home /etc --exclude-file /etc/restic/excludes --tag baseline. List snapshots with restic snapshots. Sanity‑check data with restic check --read-data-subset=10%.

Windows: Open PowerShell as Administrator, then: powershell -ExecutionPolicy Bypass -File C:\restic\env.ps1; restic backup "C:\Users" "D:\Data" --exclude-file "C:\restic\excludes.txt" --tag baseline. View snapshots with restic snapshots.

Step 5 — Automate Daily Backups (Linux via systemd)

Store environment variables in /etc/restic/env and your excludes in /etc/restic/excludes. Create a systemd service /etc/systemd/system/restic-backup.service with:
[Unit]
Description=Restic backup to B2

[Service]
Type=oneshot
EnvironmentFile=/etc/restic/env
ExecStart=/usr/bin/restic backup /home /etc --exclude-file /etc/restic/excludes --tag daily
Nice=10
IOSchedulingClass=best-effort

Create the timer /etc/systemd/system/restic-backup.timer:
[Unit]
Description=Daily Restic backup

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=10m

[Install]
WantedBy=timers.target

Enable and start: sudo systemctl daemon-reload && sudo systemctl enable --now restic-backup.timer.

Step 6 — Retention and Pruning

Keep what you need and trim the rest. A good starting policy keeps a week of daily points, a month of weekly points, and a year of monthly points. Run weekly: restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --keep-yearly 3. Add this to a separate systemd timer (e.g., restic-prune.timer) or include it after the daily backup on Sundays.

To reduce API load and speed up operations on B2, consider limiting parallel connections when pruning: restic -o b2.connections=8 forget --prune .... You can also set a cache directory to speed up metadata operations: export RESTIC_CACHE_DIR=/var/cache/restic (ensure it’s persistent and has room).

Step 7 — Automate on Windows (Task Scheduler)

Create C:\restic\backup.ps1 with:
. C:\restic\env.ps1
restic backup "C:\Users" "D:\Data" --exclude-file "C:\restic\excludes.txt" --tag daily
restic forget --prune --keep-daily 7 --keep-weekly 4 --keep-monthly 12

Then open Task Scheduler → Create Task → General: Run whether user is logged on or not, run with highest privileges. Triggers: Daily at a quiet hour. Actions: Start a Program → Program/script: powershell → Arguments: -ExecutionPolicy Bypass -File C:\restic\backup.ps1 → Start in: C:\restic.

Step 8 — Restores You Can Trust

List snapshots and pick a point in time: restic snapshots. Restore everything to a safe directory: restic restore latest --target /tmp/restore. Restore only a folder: restic restore latest --target /tmp/restore --include "/home/alex/Documents". On Windows, run the same commands in PowerShell with paths like "C:\Users\Alex\Documents". For browsing, Linux supports FUSE: restic mount /mnt/restic (unmount with fusermount -u /mnt/restic).

Security and Cost Tips

Protect your password file and environment files with strict permissions; never hardcode keys in scripts. Use a bucket‑scoped Application Key limited to your backup bucket. Tag backups (e.g., --tag daily, --tag before-upgrade) to make pruning and auditing easier. Keep your monthly bill predictable by excluding caches and VM images that change often, and by using a sensible retention policy.

Troubleshooting

If you see transient B2 errors (429/503), restic will retry; adding -o b2.connections=4 can help. For permission errors, confirm that your Application Key has delete permissions (needed for pruning). If backups seem slow, verify your excludes and consider running restic check --with-cache during off‑hours. Always test a small restore before you need a big one.

What You Achieved

You now have encrypted, offsite, incremental backups to Backblaze B2 with restic, running on a schedule, pruned to a clear retention policy, and verified for integrity. Keep the password safe, periodically test restores, and you will be ready when hardware fails or ransomware strikes.

Ransomware‑Resilient Backups on Linux with Restic and Backblaze B2 Object Lock

Overview

If you need cloud backups that ransomware cannot silently erase, combine Restic with Backblaze B2 buckets that have Object Lock enabled. Restic gives fast, deduplicated encrypted backups, while B2 Object Lock makes every uploaded backup file immutable for a time you choose. This guide shows how to set up the entire pipeline on Linux, from creating an Object Lock bucket to scheduling backups and verifying restores.

What You Need

- A Linux machine with shell access (Ubuntu/Debian/RHEL/AlmaLinux etc.)

- A Backblaze B2 account

- Restic 0.12 or newer (most modern distros provide it)

- Basic understanding of environment variables and systemd (for scheduling)

Step 1 — Create a Backblaze B2 Bucket with Object Lock

1) Sign in to the Backblaze B2 web console and create a new bucket. Choose a unique name, keep it Private, and enable Object Lock during creation. You cannot turn this on later for an existing bucket.

2) In the bucket settings, set a Default Bucket Retention under Object Lock. A common starting point is Governance mode with a retention of 30 days. This applies immutability automatically to all new objects (Restic pack files), blocking deletion or modification until retention expires.

3) Optional: configure lifecycle rules for versioning if you store non-Restic data in the same bucket. For a pure Restic repository, the default retention plus Restic’s own forget/prune policy is usually enough.

Step 2 — Generate a Restricted Application Key

Create a new application key limited to your bucket. In Backblaze, go to App Keys, click Add a New Application Key, restrict it to the bucket you created, and copy the KeyID and Application Key. Treat these like passwords.

Step 3 — Install Restic

On Ubuntu/Debian, run: sudo apt update && sudo apt install restic. On RHEL/AlmaLinux/Rocky, use: sudo dnf install restic. If your distro is outdated, download the latest static binary from Restic’s releases page and place it in /usr/local/bin with executable permissions.

Step 4 — Export Environment Variables

Set environment variables so Restic knows how to reach B2 and encrypt your repository:

export RESTIC_REPOSITORY=b2:your-bucket-name:restic-repo

export B2_ACCOUNT_ID=your-key-id

export B2_ACCOUNT_KEY=your-application-key

export RESTIC_PASSWORD=strong-passphrase (or use RESTIC_PASSWORD_FILE to read it from a file)

Tip: store these in a root-only file such as /root/.restic-env, then source it: set -a; . /root/.restic-env; set +a.

Step 5 — Initialize the Repository

Create the Restic repository in your B2 bucket: restic init. You should see “created restic repository.” From now on, all data is encrypted client-side and written as immutable objects (because the bucket has Object Lock with default retention).

Step 6 — Run Your First Backup

Start with a focused scope. For example: restic backup /etc /home /var/www --exclude "*/node_modules/*" --tag initial. Restic deduplicates files automatically and shows a summary when done. Use tags like --tag server01 to identify hosts or workloads.

Step 7 — Set a Retention Policy (Forget + Prune)

Tell Restic how many restore points to keep. A common policy is: restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune. Note: pruning cannot remove pack files that are still under Object Lock. That is expected. Deletion will occur automatically once retention expires and the data is no longer referenced by any snapshot.

Step 8 — Schedule Automatic Backups with systemd

Create a service file, e.g. /etc/systemd/system/restic-backup.service with:

[Unit]
Description=Restic backup
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=/root/.restic-env
ExecStart=/usr/bin/restic backup /etc /home /var/www --exclude "*/node_modules/*" --tag daily
ExecStart=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

Add a timer in /etc/systemd/system/restic-backup.timer:

[Unit]
Description=Run Restic backup daily

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target

Enable with: sudo systemctl daemon-reload && sudo systemctl enable --now restic-backup.timer.

Step 9 — Test a Restore

List snapshots: restic snapshots. Restore the latest to a safe directory: restic restore latest --target /tmp/restore. To restore a single path, add --include "/etc" or --include "/home/user/Documents". Verify that the restored files open normally.

Security and Cost Tips

- Use RESTIC_PASSWORD_FILE with a root-only file and consider storing it via a secrets manager or an encrypted password store.

- Restrict your B2 application key to the single bucket and avoid account-wide keys.

- Monitor storage growth. Deduplication helps, but backups expand over time. Object Lock increases short-term storage because data cannot be deleted until retention ends.

Troubleshooting

- Permission errors (403): verify the KeyID/key, bucket restriction, and that Object Lock is enabled.

- Time sync issues: B2 rejects requests if the server time is off. Ensure NTP is running (systemd-timesyncd or chrony).

- Prune failures: if objects are still under retention, pruning cannot delete them. This is normal. They will be removed automatically once retention expires and no snapshots reference them.

You’re Done

You now have a backup strategy that is fast, encrypted, deduplicated, and resilient to ransomware. Restic handles the heavy lifting, while Backblaze B2 Object Lock prevents attackers or accidents from wiping out recent restore points. Periodically test restores and review your retention window to balance recoverability and storage costs.

3.

Build Your Own Encrypted S3 Backup with Restic and MinIO (Docker Compose, 2025 Guide)

If you want fast, encrypted, and deduplicated backups without paying for a public cloud, pairing Restic with MinIO is a powerful option. Restic handles client-side encryption and incremental backups; MinIO provides an S3-compatible object store you fully control. In this hands-on guide, you will deploy MinIO using Docker Compose, initialize a Restic repository, automate backups with a retention policy, and verify restores. The steps work on modern Linux distributions (Ubuntu/Debian/RHEL) and on any host that can run Docker.

Prerequisites

- A Linux server with at least 2 CPU cores, 4 GB RAM, and storage sized to your backup needs.
- Docker and Docker Compose installed.
- A shell user with sudo rights.
- Optional but recommended: a hostname and TLS if exposing MinIO beyond localhost.

Step 1 — Create a Docker Compose file for MinIO

We will run MinIO on ports 9000 (S3 API) and 9001 (web console). Use a strong root user and password. Put the credentials into a .env file so they are not hard-coded in the Compose file.

# .env
MINIO_ROOT_USER=minioadmin_change_me_now
MINIO_ROOT_PASSWORD=SuperStrong_Passw0rd_change_me
MINIO_DATA_PATH=./minio-data
# docker-compose.yml
services:
  minio:
    image: minio/minio:latest
    container_name: minio
    command: server /data --console-address ":9001"
    ports:
      - "9000:9000"   # S3 API
      - "9001:9001"   # Web Console
    environment:
      - MINIO_ROOT_USER=${MINIO_ROOT_USER}
      - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
    volumes:
      - ${MINIO_DATA_PATH}:/data
    restart: unless-stopped

Start MinIO:

docker compose up -d

Open the web console at http://<server-ip>:9001 and sign in with the root user credentials from the .env file.

Step 2 — Create a bucket and a dedicated access key

For clear separation, create a bucket named restic and generate a dedicated access key limited to that bucket.

Option A (Web Console):

- Storage → Create bucket → Name: restic.
- Identity → Service Accounts → Create access key → Scope: restrict to the restic bucket (read/write). Save the Access Key and Secret Key.

Option B (CLI, quick start):

# Uses MinIO Client without permanent install
docker run --rm --network host \
  -e MC_HOST_local="http://${MINIO_ROOT_USER}:${MINIO_ROOT_PASSWORD}@127.0.0.1:9000" \
  minio/mc mb local/restic

For production, prefer a limited service account rather than using the root keys in automation.

Step 3 — Initialize a Restic repository

Install Restic from your distribution or from the official releases. Then export environment variables for the repository URL and credentials. Replace placeholders with your actual keys.

export RESTIC_REPOSITORY="s3:http://127.0.0.1:9000/restic"
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export RESTIC_PASSWORD="Choose_A_Strong_Repo_Password"

Initialize the repository (first time only):

restic init

Restic encrypts data with the password you set, before uploading. Keep this password safe; without it, restores are impossible.

Step 4 — Create a backup script with retention

Let’s script a daily backup with sensible retention (7 daily, 4 weekly, 6 monthly) and basic integrity checks.

sudo tee /usr/local/bin/restic-backup.sh >/dev/null <<'EOF'
#!/usr/bin/env bash
set -euo pipefail

# Environment (consider moving to /etc/restic/.env and source it)
export RESTIC_REPOSITORY="s3:http://127.0.0.1:9000/restic"
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
export RESTIC_PASSWORD="Choose_A_Strong_Repo_Password"

# What to back up
INCLUDE_DIRS=(
  "/etc"
  "/var/www"
  "/var/lib/docker/volumes/project_data/_data"
  "$HOME"
)

# Exclusions
EXCLUDES=( 
  "--exclude-file=/etc/restic-excludes.txt"
)

# Run backup
restic backup "${EXCLUDES[@]}" "${INCLUDE_DIRS[@]}"

# Retention and pruning
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

# Lightweight consistency check (5% of data)
restic check --read-data-subset=5%
EOF
sudo chmod +x /usr/local/bin/restic-backup.sh

Create a simple exclusions file to skip caches and temporary data:

sudo tee /etc/restic-excludes.txt >/dev/null <<'EOF'
/home/*/.cache
/var/cache
/var/tmp
*.iso
*.qcow2
node_modules
EOF

Schedule the backup with cron:

(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/restic-backup.sh >> /var/log/restic.log 2>&1") | crontab -

Tip: For long-running servers, a systemd timer is often more reliable than cron. Also consider moving credentials into a protected file (chmod 600) and sourcing it inside the script.

Step 5 — Test listing and restoring

Verify snapshots:

restic snapshots

Restore a file or directory to a safe location:

# Find a snapshot ID from 'restic snapshots'
restic restore latest --target "$HOME/restore-test" --include /etc/hosts

Always test a restore. A backup you cannot restore is not a backup.

Step 6 — Secure access and expose safely

- Use HTTPS for MinIO. Either terminate TLS directly in MinIO (via certificates at /data/.minio/certs) or put MinIO behind a reverse proxy like Caddy or Nginx with automatic Let’s Encrypt.
- If backing up from remote machines, prefer private networks (Tailscale/WireGuard) rather than exposing port 9000 to the internet.
- Set strong passwords and rotate access keys periodically.

Step 7 — Useful maintenance and troubleshooting

- Verify integrity periodically: restic check (run monthly with full read if you can).
- Remove stale locks: restic unlock if a job was interrupted.
- Monitor logs: tail -f /var/log/restic.log for failures or timeouts.
- Storage growth: run restic prune occasionally (already included with forget --prune) and review your exclude list.

Why this stack works in 2025

Restic remains one of the most efficient open-source backup tools thanks to encryption-by-default, deduplication, and built-in S3 support. MinIO provides a modern, high-performance, and S3-compatible backend you can run on-prem or at the edge. With Docker Compose, you can upgrade easily, keep state on mapped volumes, and move the stack between servers without changing your backup commands.

With the steps above, you now have a repeatable, scriptable, and secure backup workflow: data is encrypted before it leaves the host, stored in an S3 bucket you control, and cleaned up automatically with a clear retention policy. Don’t forget to document your RESTIC_PASSWORD location and your MinIO access keys, and test restores on a schedule.

Popular Posts

Install Ollama and Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install Ollama + Open WebUI on Ubuntu 24.04 with NVIDIA GPU Acceleration (Step-by-Step)

Install a Local AI Chatbot on Ubuntu 24.04 with Ollama and Open WebUI (Step-by-Step)

Trending Now

Recovering from Btrfs Boot Failures Using GUI Tools on Fedora

By the end of this guide the reader will be able to identify a Btrfs‑based Fedora installation, boot from a live USB, list and restore snapshots using the graphical utilities btrfs‑assistant and snapper, and verify that the system returns to a functional state without resorting to the command line. Understanding the Btrfs Layout Used by Fedora Fedora Workstation and Fedora KDE install the root filesystem as a single Btrfs partition that contains two default sub‑volumes. One sub‑volume holds the traditional “/” hierarchy, while the second is dedicated to /var/lib/machines . The latter exists to keep container images out of snapshot operations; it remains empty on systems that do not run virtual machines. Because Btrfs stores data in sub‑volumes rather than separate partitions, a snapshot captures the state of an entire sub‑volume at a point in time. The installer (Anaconda) automatically registers these sub‑volumes with the snapper service. Snapper maintains a series of read‑only ...