−25%

on annual Windows plans, until 31 Oct. See plans

EQVPS

How to back up a VPS with restic (encrypted, off-site)

Encrypted, deduplicated VPS backups with restic: a repository on S3-compatible storage or another server, a systemd timer, retention and a restore test.

Everyone has backups until they try to restore one. The folder turns out to be empty, the cron job died in March, or the archive sits on the same disk that just failed. restic fixes most of that: it encrypts on your side, stores each piece of data once, and makes restoring a single file as easy as backing up the whole server.

Here's a setup we'd actually trust, on Ubuntu or Debian.

1. Install restic

apt update && apt install -y restic
restic self-update

Distribution packages lag behind; self-update pulls the current release.

2. Pick a place for the repository

The repository must not live on the server you're protecting. Two common choices:

3. Store the credentials

Keep everything in one root-only file so the timer and your shell use the same settings:

cat > /root/.restic-env <<'EOF'
export RESTIC_REPOSITORY="s3:https://s3.example.com/my-bucket/web1"
export RESTIC_PASSWORD_FILE="/root/.restic-pass"
export AWS_ACCESS_KEY_ID="your-key-id"
export AWS_SECRET_ACCESS_KEY="your-secret"
EOF
openssl rand -base64 32 > /root/.restic-pass
chmod 600 /root/.restic-env /root/.restic-pass

Now copy the contents of /root/.restic-pass into your password manager. Without it, the backups can't be decrypted — by you or anyone else.

4. Initialise and run the first backup

source /root/.restic-env
restic init
restic backup /etc /home /root /srv /var/www \
  --exclude-caches --exclude '/root/.cache'
restic snapshots

Adjust the paths to where your data actually lives. Docker volumes sit under /var/lib/docker/volumes; application data is often in /srv or /opt.

5. Databases: dump, then back up

Don't back up the raw files of a running database. Dump it just before the backup:

mkdir -p /var/backups/db
sudo -u postgres pg_dump -Fc mydb > /var/backups/db/mydb.dump

Add /var/backups/db to the backup paths. Our PostgreSQL guide has more on dumps.

6. Schedule it with systemd

A timer beats cron here: it logs to the journal, and it catches up if the server was off at run time.

# /etc/systemd/system/restic-backup.service
[Unit]
Description=restic backup

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'source /root/.restic-env && restic backup /etc /home /root /srv /var/www /var/backups/db --exclude-caches && restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune'
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Daily restic backup

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now restic-backup.timer
systemctl list-timers restic-backup.timer

forget --prune keeps 7 daily, 4 weekly and 6 monthly snapshots and deletes the rest. If you have a database dump step, put it in an ExecStartPre= line.

7. Actually restore something

This is the step that turns "we have backups" into a fact. Pull one directory back into a temporary folder and look at it:

source /root/.restic-env
restic restore latest --target /tmp/restore-test --include /etc/nginx
ls -la /tmp/restore-test/etc/nginx
restic check

Do this once now and again every few months. restic check verifies the repository structure; the restore proves the data is really there.

restic and Managed Backups

They don't compete. Managed Backups take a daily restore point of the whole server that you roll back from the dashboard — the fast fix after a broken upgrade. They cost $2/month and are included free with any annual plan. restic gives you file-level, off-site copies in storage you control, which matters when the problem is a deleted file from last Tuesday or you want a copy outside our infrastructure entirely.

If you store sensitive data, pair this with full-disk encryption, or look at the encrypted storage use case for running your own backup target. A Micro plan is enough for most small servers plus their backup jobs.

FAQ

What happens if I lose the restic password?

The backups are gone for good. restic encrypts everything on the client, and there is no recovery key. Store the password in a password manager, not only on the server you're backing up.

Where should the repository live?

Anywhere except the server itself: S3-compatible object storage, another VPS over SFTP, or a machine at home. A backup on the same disk dies with that disk.

How do I back up a database with restic?

Dump it first and back up the dump — for PostgreSQL 'pg_dump -Fc', for MySQL 'mysqldump --single-transaction'. Copying live database files can give you a backup that won't start.

How much space do the backups take?

Less than you'd expect. restic splits files into chunks and stores each chunk once, so daily snapshots of a mostly unchanged server add only the changed data.

Do I still need Managed Backups?

They solve different problems. Managed Backups give you daily restore points of the whole server that you can roll back from the dashboard. restic gives you file-level, off-site copies you control. Many people run both.

Comments

No comments yet. Be the first.

Leave a comment

Comments are moderated before they appear.