You deleted a config file, overwrote a template, or need one database dump from last week. You do not need to restore the whole snapshot — restic can pull a single file or folder out of any snapshot in seconds. This guide walks through finding the right snapshot, checking what is inside it, and restoring only the path you need.
Before you start
You need:
- SSH access to the Linux VPS that holds the restic repository. If you are connecting for the first time, see Connect to your Linux VPS with SSH.
- The
resticbinary installed (restic versionshould print a version). - The repository location and the password. If you have not set up a repository yet, start with Encrypted off-site backups with restic.
- Enough free space in
/tmpor wherever you restore to. A single file needs almost nothing; a full directory needs roughly its uncompressed size.
Export the connection details once so every command below works without repeating flags:
export RESTIC_REPOSITORY="sftp:backup@203.0.113.10:/srv/restic-repo"
export RESTIC_PASSWORD_FILE="/root/.restic-pass"
restic snapshots --latest 3If that prints snapshots, you are ready. If it fails, fix the repository path or password before continuing.
Tip: Run restic snapshots with no arguments first to see hosts, tags and paths. The ID column is the short snapshot ID you will pass to later commands.
Find the snapshot that contains the file
Start by narrowing the list. Filter by host, path or tag instead of scrolling through hundreds of entries:
restic snapshots --host web01 --path /var/www/html
restic snapshots --tag daily --latest 5If you do not know which snapshot holds the file, let restic search the index for you:
restic find "wp-config.php"
restic find --snapshot latest "*.conf"restic find prints every snapshot that contains a matching path, plus the full path inside the snapshot. That output is usually all you need to pick an ID.
Inspect the snapshot before restoring
List the contents of a snapshot without touching the live filesystem:
restic ls latest
restic ls latest /var/www/html
restic ls -l latest /etc/nginxThe first command dumps the whole tree, which is noisy on a busy server. Pass a directory to limit it. -l adds size and mode, which is handy when you are looking for the most recent version of a file.
Compare two snapshots when you are unsure which one is good:
restic ls latest /var/www/html/index.php
restic ls 3f9c1a2b /var/www/html/index.phpPaths inside a snapshot are absolute and match what was backed up. If your backup used --path /var/www, then the file appears as /var/www/html/index.php, not html/index.php.
Restore one file or folder
Restore to a scratch directory first. Never write straight over a live file until you have looked at the restored copy.
mkdir -p /tmp/restic-restore
restic restore latest \
--target /tmp/restic-restore \
--include /var/www/html/wp-config.phpThe result lands at /tmp/restic-restore/var/www/html/wp-config.php — restic recreates the full path under the target. Add --verify to re-read the restored data and confirm it matches the repository.
For a whole directory, repeat --include for each path or pass the parent:
restic restore latest \
--target /tmp/restic-restore \
--include /etc/nginx \
--exclude /etc/nginx/cacheTo restore from a specific snapshot instead of latest, replace latest with the short ID from restic snapshots:
restic restore 3f9c1a2b --target /tmp/restic-restore --include /etc/nginx/nginx.confWarning: Do not add --delete to a restore aimed at a live directory. It removes files in the target that are not in the snapshot, which can wipe data you still need.
Once the file looks right, copy it into place and fix ownership:
sudo cp /tmp/restic-restore/var/www/html/wp-config.php /var/www/html/wp-config.php
sudo chown www-data:www-data /var/www/html/wp-config.php
sudo chmod 640 /var/www/html/wp-config.phpRestoring as root preserves the ownership and permissions recorded at backup time. Restoring as a normal user skips ownership, so check with ls -l afterwards.
Pull one file to stdout with restic dump
When you only need to read a file, or pipe it somewhere, skip the restore step entirely:
restic dump latest /var/www/html/wp-config.php
restic dump latest /etc/nginx/nginx.conf > /tmp/nginx.confrestic dump writes the file contents to standard output. Point it at a directory and it streams a tar archive:
restic dump latest /var/www/html | tar -x -C /tmp/restic-restoreThis is the fastest option for a single small file, and it never writes to the live path.
Check it works
Confirm the restored copy is the version you expected:
diff -u /var/www/html/wp-config.php /tmp/restic-restore/var/www/html/wp-config.phpThen reload whatever reads the file and check the service:
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl status nginx --no-pagerFor an application file, open the site or run the app's own health check. If the service starts and the diff shows only the change you wanted, the restore is done. Clean up the scratch directory when you are finished:
rm -rf /tmp/restic-restoreTroubleshooting
Fatal: unable to open repositoryorwrong password— the repository URL or password file is wrong. Re-checkRESTIC_REPOSITORYandRESTIC_PASSWORD_FILE, and confirm the remote host is reachable withssh backup@203.0.113.10.path not found in snapshot— the--includepath does not match the snapshot exactly. Runrestic ls <snapshot> /and copy the path character for character; a trailing slash or a relative path will fail.- Restored file has the wrong owner — you ran the restore as a non-root user. Re-run with
sudo, or set ownership manually withchownas shown above. target directory is not empty— restic refuses to overwrite a populated target in some versions. Use a fresh directory such as/tmp/restic-restore-$(date +%s).- Restore is very slow — a large
--includestill has to read many pack files. Restore only the exact subdirectory you need, or userestic dumpfor a single file.
Next steps
- Rebuild a full server from a snapshot with Encrypted off-site backups with restic: init, snapshot, restore.
- Restore container data the same way in Back up Docker volumes with restic and restore them.
- If the file you lost was a database dump, follow Restore a MySQL Database from a mysqldump File.
