
September 12, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
Production servers fail at the worst moment—disk corruption, a bad deploy, ransomware, or an operator mistake during a late-night migration. restic: Fast Encrypted Backups solves the operational half of that problem with deduplicated, encrypted snapshots you can push to cheap object storage or a second VPS. I run Linux system administration workflows on Ubuntu servers for Laravel apps, WordPress shops, and legal-tech portals, and restic is the tool I reach for when rsync alone is not enough. This guide covers install, repository setup, daily automation, restore drills, and the trade-offs against plain rsync.
restic backup on a schedule, and restore files or full trees with restic restore—fast incremental uploads after the first run.What makes restic: Fast Encrypted Backups different from rsync?
rsync copies files. restic creates versioned snapshots with content-defined chunking. Changed bytes inside a large file do not force a full re-upload. Encryption happens client-side before data leaves your server.
On sister sites I maintain with Deployer 7 and GitLab CI—legal portals, translation sites, and similar Laravel stacks—off-site restic repos sit alongside rsync mirrors. rsync gives you a browsable copy on another disk. restic gives you history, deduplication, and tamper-resistant encryption at rest.
| Criteria | restic | rsync |
|---|---|---|
| Encryption at rest | Built-in, client-side | None unless disk or bucket encryption added |
| Version history | Every snapshot retained by policy | Mirror only; needs separate rotation |
| Deduplication | Content-defined across snapshots | File-level only |
| Restore granularity | Single file from any snapshot | Whole tree or manual pick |
| Remote target | S3, B2, Azure, SFTP, REST, local | SSH, local, daemon |
| CPU/RAM on first run | Higher (hashing + packing) | Lower |
| Best fit | Off-site encrypted history | Fast mirror to second server |
Neither tool replaces the other. Pair them. rsync for a hot standby copy. restic for encrypted off-site retention. That pattern matches what I document in broader support and maintenance engagements for production Laravel and WordPress hosts.
How do you install and initialize a restic repository?
restic ships as a single static binary on Linux. Install from your distro package or the official release. Ubuntu 22.04 and 24.04 both carry recent builds in universe.
Install on Ubuntu
sudo apt update
sudo apt install restic
restic version Alternatively, download the latest release from the official restic site and place the binary in /usr/local/bin.
Choose a backend and set environment variables
restic reads repository location and credentials from env vars or flags. For S3-compatible storage (AWS S3, Cloudflare R2, Wasabi, MinIO):
export RESTIC_REPOSITORY="s3:s3.amazonaws.com/my-backup-bucket/prod-web01"
export RESTIC_PASSWORD="use-a-long-random-passphrase"
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..." Generate the repository password with a proper tool—not a memorable phrase. A password generator that outputs 32+ random characters is the right starting point. Store it in your team vault. Lose the password and the backups are gone. restic cannot recover encrypted data without it.
Initialize the repository once
restic init You should see confirmation that a new repository was created. Run init exactly once per repo. Re-running against an existing repo returns an error—that is expected.
For Backblaze B2, set B2_ACCOUNT_ID and B2_ACCOUNT_KEY and use an s3:// endpoint URL B2 documents for the S3-compatible API. For local or USB backup:
export RESTIC_REPOSITORY="/mnt/backup-drive/restic-repo"
restic init Official backend docs live in the restic documentation. Read the section for your provider before the first production upload.
How do you run restic backup jobs on a production Linux server?
A useful backup includes application files, config outside the repo, and database dumps. On a typical Laravel stack that means /var/www, nginx or Apache vhost files, .env (handled carefully), and nightly MySQL or PostgreSQL dumps.
Example backup script
Save as /usr/local/bin/restic-backup.sh. Adjust paths for your stack.
#!/bin/bash
set -euo pipefail
STAGING="/backup/staging"
APP_ROOT="/var/www/myapp"
DUMP="$STAGING/db-$(date +%F).sql.gz"
LOG="/var/log/restic-backup.log"
mkdir -p "$STAGING"
mysqldump --single-transaction myapp_db | gzip > "$DUMP"
restic backup \
"$APP_ROOT" \
/etc/nginx/sites-available \
"$STAGING" \
--exclude="$APP_ROOT/node_modules" \
--exclude="$APP_ROOT/vendor" \
--tag nightly \
--host prod-web01 \
2>&1 | tee -a "$LOG"
restic forget \
--tag nightly \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6 \
--prune \
2>&1 | tee -a "$LOG" Vendor and node_modules are reproducible from Git and Composer. Excluding them cuts repo size sharply. Rebuild them after restore from your deploy pipeline.
Schedule with cron
sudo crontab -e Add a line that sources credentials from a root-only file:
15 2 * * * . /root/.restic-env && /usr/local/bin/restic-backup.sh Put secrets in /root/.restic-env with mode 600:
export RESTIC_REPOSITORY="s3:s3.eu-central-1.amazonaws.com/acme-backups/web01"
export RESTIC_PASSWORD="..."
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..." A common mistake is stale cron paths after Deployer symlink swaps. Point backups at shared paths—storage/, database dumps, and config—not release-specific directories that rotate every deploy. I have seen this break restores on Notary Kathmandu-class Laravel sites that share a Deployer pipeline across multiple domains.
How do you restore files quickly from restic snapshots?
Backups you never restore are guesses. Run a restore drill quarterly. Know your snapshot IDs before an incident.
List snapshots
restic snapshots Find a file inside a snapshot
restic find "*.env"
restic ls latest:/var/www/myapp Restore one file or a full tree
restic restore latest --target /restore-test --include /var/www/myapp/.env
restic restore abc123de --target /restore-full --path /var/www/myapp Verify permissions and ownership after restore. restic preserves metadata where the OS allows. On Ubuntu you may need chown -R www-data:www-data on web roots.
For database recovery, pull the gzipped dump from the snapshot staging path and import:
gunzip -c /restore-test/backup/staging/db-2026-09-10.sql.gz | mysql myapp_db Document RTO and RPO for each tier. A brochure WordPress site and a booking portal with live payments do not share the same urgency. Platforms like Adventure Third Pole Trek need faster database recovery than a static marketing page.
How do you tune performance and control backup costs?
The first backup uploads everything. Later runs upload only new chunks. That is where the "fast" label earns its keep—if you structure jobs correctly.
- Exclude aggressively: cache dirs,
vendor/,node_modules/, log files, and session temp paths. - Limit bandwidth on shared hosting or metered links:
--limit-upload 5000caps upload at 5 MB/s. - Run during off-peak hours: 02:00–04:00 NPT avoids Dashain-season traffic spikes on client sites.
- Use nearby regions: an EC2 in Mumbai backing up to
ap-south-1beats cross-continent transfers for Nepal-hosted workloads. - Prune regularly: forgotten snapshots inflate storage bills. Pair
forgetwith--pruneevery run.
Object storage pricing matters on tight budgets. A 40 GB web root with daily deltas might cost Rs 300–800/month (~USD 2–6) on mainstream S3 tiers before egress. Track repo stats:
restic stats --mode raw-data
restic stats latest For application-level backups inside Laravel, Spatie Backup handles zip exports to local or cloud disks. That complements—not replaces—full-server restic jobs. Use Spatie for quick database exports; use restic for entire machine state including configs and keys. See also general guidance on testing and optimization when backup windows overlap with CI deploys.
Integrity and monitoring
Automate checks. A corrupt repo discovered during an outage is useless.
restic check
restic check --read-data-subset 10% Send cron output to mail or a webhook. Exit code non-zero should page someone. Monthly, restore a random file to /tmp/restore-drill and record the time taken.
What backup mistakes break restic deployments in real projects?
Most failures are operational, not tool bugs. Patterns I see on production Linux hosts:
- Password only on one laptop. Put
RESTIC_PASSWORDin a shared vault with break-glass access. - Backing up symlinks blindly. Deployer release paths change. Back shared persistent dirs.
- Never testing restore. Schedule a drill before every major upgrade.
- Same credentials as production S3 app bucket. Use a dedicated IAM user limited to the backup prefix.
- Ignoring database consistency. Always dump with
--single-transactionon InnoDB before file backup. - Skipping off-site copy. Local restic on the same disk does not survive fire, theft, or ransomware.
Legal-tech portals—client uploads, signed PDFs, payment records—need stricter retention than a blog. On projects like Mijar Law Associates and Court Marriage In Nepal, document retention rules belong in the backup policy, not in ad-hoc cron edits.
Hosting choice affects latency. If you manage domains and VPS together, align backup region with your primary server during domain registration and hosting planning—not after an outage.
For WooCommerce and Laravel eCommerce stacks—Quick And Easy Nepalese Grocery, gift-card platforms, multi-currency florists—add order tables to dump priority. Media uploads belong in the file backup set. Test cart checkout after every restore drill.
WordPress sites on shared cPanel rarely run restic natively. Move to a VPS you control, or use provider snapshots plus plugin exports as a bridge. Long term, WordPress development on proper Linux infrastructure makes restic automation straightforward.
Migrating from weak backup habits to restic fits under website migration projects: new server, init repo, first full backup, cut DNS, keep old host read-only for seven days.
Enterprise apps with PostgreSQL 18 or MySQL 9.7 need consistent dumps. Point-in-time recovery still wants binary logs or WAL archiving. restic captures those dump files; it is not a replacement for DB-native PITR. Layer both if RPO under one hour is contractual.
AWS documents IAM least-privilege policies for S3 backup prefixes in the AWS IAM policy guide. Scope keys to s3:PutObject, s3:GetObject, s3:ListBucket, and s3:DeleteObject on one bucket path—nothing wider.
Key Takeaways
- Initialize one restic repo per environment, store the password in a vault, and never commit credentials to Git.
- Chain database dumps, file backup, forget/prune, and monthly restore drills—automation without testing is theater.
- Exclude reproducible dirs (
vendor/,node_modules/) to keep deduplicated repos small and uploads fast. - Pair restic off-site encrypted snapshots with rsync mirrors for same-day failover on critical Laravel and WordPress hosts.
- Use S3-compatible object storage in a nearby region for Nepal-hosted VPS workloads; budget Rs 300–800/month (~USD 2–6) for typical small sites.
- Run
restic checkregularly and alert on failure—corruption found during recovery is too late.
People Also Ask
Is restic better than rsync for server backups?
restic is better for encrypted, deduplicated, versioned off-site snapshots. rsync is better for fast mirrors to a second server. Production setups should use both: rsync for hot standby, restic for history and ransomware resilience.
Can restic backup to Cloudflare R2 or Backblaze B2?
Yes. Both expose S3-compatible APIs. Point RESTIC_REPOSITORY at the provider endpoint and supply the matching access keys. R2 often saves egress fees when your origin also sits on Cloudflare.
How do you migrate restic repositories to a new bucket?
Use restic copy or restic migrate between repositories with the same password. Init the destination repo, then copy snapshots incrementally. Verify with restic check on the new repo before retiring the old one.
What happens if you lose the restic repository password?
Backups are permanently unreadable. restic uses AES-256 encryption with no vendor backdoor. Store the password in a team vault and maintain an offline break-glass copy.
Build a backup stack you will actually restore from
restic: Fast Encrypted Backups earns its place on every production Linux box I touch: one binary, strong encryption, cheap object-storage targets, and restores granular enough to pull a single .env from last Tuesday. Start tonight—init a repo, back up /var/www plus last night's database dump, and restore one file to prove the chain works. For full-stack setup on Ubuntu hosts running Laravel, WordPress, or custom apps, see the Linux system administration service or browse the portfolio of production sites that rely on disciplined ops. More backup patterns live on the blog. Ready to harden a server that still copies files to USB once a month? Contact us and we will design a 3-2-1 plan that survives real failures.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

