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.
Comments
Post a Comment