[{"data":1,"prerenderedAt":190},["ShallowReactive",2],{"seo-verification":3,"blog-automate-your-vps-backups-with-restic-ma-en":6,"promo-bar-likely":189},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-automate-your-vps-backups-with-restic-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":28,"featuredImage":30,"bgImage":31,"posterImage":32,"relatedSolution":30,"intro":33,"sections":34,"ctaTitle":130,"ctaBody":131,"ctaButton":132,"ctaUrl":133,"relatedPosts":134},113,"automate-your-vps-backups-with-restic",{"fr":12,"en":10,"ar":13,"es":14},"sauvegardes-restic-vps","أتمتة-نسخ-خادمك-vps-الاحتياطية-باستخدام-restic","copias-de-seguridad-vps-con-restic","Automate Your VPS Backups with Restic","Automate your VPS backups with Restic: encrypted snapshots, deduplication and shipping to S3 or any object backend.",11,0,false,"2026-02-27T00:00:00+00:00","2026-11-08T01:13:12+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[29],{"id":23,"name":24,"slug":25,"color":26,"icon":27},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fsauvegardes-restic-vps-poster.svg","A backup that is neither tested nor encrypted is worthless on the day of an incident. Restic combines incremental snapshots, deduplication and end-to-end encryption in a single binary. On your VPS, it becomes the automated safety net for your data, pushed to remote object storage at low cost.",[35,39,49,52,59,62,90,118,122,125,128],{"type":36,"title":37,"body":38},"h2","Why automate your backups with Restic","A VPS often hosts irreplaceable data: databases, Docker volumes, configuration files. Restic meets three key requirements of a sound strategy: encryption (AES-256; the repository is unusable without the password), deduplication (identical blocks are stored only once, which drastically reduces volume and cost), and support for varied backends (S3, Backblaze B2, SFTP, local storage). Self-hosting Restic on the VPS rather than relying on a managed backup service gives you full control of encryption: the key stays with you, and the storage provider sees only opaque blobs. This is the foundation of a serious 3-2-1 strategy.",{"type":40,"title":41,"items":42},"ul","What Restic brings you",[43,44,45,46,47,48],"Client-side AES-256 encryption: the storage backend sees only unreadable data.","Block-level deduplication that greatly reduces the size and cost of successive backups.","Fast incremental snapshots: only new blocks are transferred on each run.","Multiple backends (S3, Backblaze B2, SFTP, rest-server, local) without changing your workflow.","Granular restore: a single file, a folder or an entire snapshot via `restic restore`.","Automated retention policy with `forget --prune` (keep N daily, M weekly...).",{"type":36,"title":50,"body":51},"The 3-2-1 rule: why a provider snapshot is not enough","Turning on your VPS provider's snapshots is useful, but it is not a backup strategy: it is a single extra copy, at the same provider, sharing the fate of your VM. Three scenarios show why. If the VM is deleted (a slip, an unpaid invoice, a termination), its snapshots often vanish with it. If an attacker takes over your hosting account, they can wipe VM and snapshots in a few clicks or through the API. And a snapshot is never restored as a test: a database frozen mid-write may turn out to be unusable on the day you need it.\n\nThe 3-2-1 rule answers these three risks: **three** copies of the data, on **two** distinct media, **one** of them outside the provider and encrypted before it leaves the server. Restic builds exactly that last link, the only one that survives losing the hosting account entirely.",{"type":40,"title":53,"items":54},"The three copies of a 3-2-1 strategy on a VPS",[55,56,57,58],"**Copy 1, the live data** on the VPS disk: the original, and the source of the fastest restores.","**Copy 2, the provider's snapshots**: they cover a failed upgrade or a configuration mistake by rolling back the whole machine.","**Copy 3, the Restic repository at another object storage provider**: encrypted client-side, it stays out of reach of your host's dashboard.","**Two truly separate media**: the VPS disk on one side, a third party's object storage on the other, with distinct credentials.",{"type":36,"title":60,"body":61},"Prerequisites for this deployment","Restic is frugal: it runs on any VPS, including 1 vCPU and 1 GB of RAM, with deduplication using a little memory in proportion to repository size. You need the `restic` binary, a remote destination backend (an S3-compatible bucket at a provider, or another server over SFTP) and its credentials. No Docker required here: Restic is a command-line tool.\n\nCheck the version your distribution ships: Debian 13 and Ubuntu 26.04 provide 0.18, but Ubuntu 24.04 is at 0.16.4 and Debian 12 at 0.14.0, too old for the `--stdin-from-command` option used below (introduced in 0.17.0). In that case, install the official binary from the \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Frestic\u002Frestic\u002Freleases\">releases page\u003C\u002Fa> (0.19.1, published on 5 July 2026): only these official binaries include the `restic self-update` command, while a distribution package is updated through `apt`. Finally, plan a systemd timer (or `cron`) for automation, and a safe place outside the VPS to keep the repository password.",{"type":63,"title":64,"headers":65,"rows":69},"comparison","Backblaze B2 or Cloudflare R2: choosing the S3 backend",[66,67,68],"Criterion","Backblaze B2","Cloudflare R2",[70,74,78,82,86],[71,72,73],"Free storage","The first 10 GB","10 GB-month per month (Standard class)",[75,76,77],"Data egress","Free up to 3 times the average monthly stored volume, and with no cap to partner CDNs (Cloudflare, Fastly)","Free, no cap",[79,80,81],"S3 endpoint","Specific to the account's region, for example `s3.us-west-004.backblazeb2.com`","`\u003Caccount-id>.r2.cloudflarestorage.com`, region `auto`",[83,84,85],"Access keys","A dedicated Application Key: the master key is rejected by the S3 API","An R2 API token with object read and write permissions",[87,88,89],"Watch out for","Frequent full restores can exceed the free egress allowance","Regular restore tests add no egress cost",{"type":91,"title":92,"steps":93},"steps","Setting up automated Restic backups",[94,97,100,103,106,109,112,115],{"title":95,"body":96},"Install Restic and prepare the environment file","Install `restic` (a recent package or the official binary, see the prerequisites), then create `\u002Froot\u002F.restic-env`. Write it as plain `KEY=value` lines, **without** `export`: that is the format read by systemd's `EnvironmentFile=` directive, and it also loads in a shell. With Restic, B2 is best used through its S3-compatible API:\n\n```bash\n# \u002Froot\u002F.restic-env  (Backblaze B2, S3 API)\nRESTIC_REPOSITORY=s3:https:\u002F\u002Fs3.us-west-004.backblazeb2.com\u002Fmy-bucket\nRESTIC_PASSWORD=change-me\nAWS_ACCESS_KEY_ID=b2-key-id\nAWS_SECRET_ACCESS_KEY=b2-application-key\n\n# Cloudflare R2\n# RESTIC_REPOSITORY=s3:https:\u002F\u002F\u003Caccount-id>.r2.cloudflarestorage.com\u002Fmy-bucket\n```\n\nRestrict the file's permissions, then load it into your session:\n\n```bash\nchmod 600 \u002Froot\u002F.restic-env\nset -a; . \u002Froot\u002F.restic-env; set +a\n```",{"title":98,"body":99},"Initialize the encrypted repository","```bash\nrestic init\n```\n\nThis command creates the repository structure and seals the encryption with your password; recent repositories (format 2, since Restic 0.14.0) also compress the data. Keep this password **off the VPS**, in a password manager or a vault on another machine: without it, no restore is possible, even with the complete bucket.",{"title":101,"body":102},"Run a first backup","Back up your critical directories, then your databases. For a dump, prefer `--stdin-from-command` to a `pg_dump | restic backup --stdin` pipe: Restic cannot tell whether a stream read from standard input is complete, and a dump that fails midway would produce a truncated snapshot without any error. With `--stdin-from-command`, a non-zero exit code from the command cancels the backup and no snapshot is created.\n\n```bash\nrestic backup \u002Fetc \u002Fvar\u002Fwww \u002Fopt\u002Fdocker-data\nrestic backup --stdin-filename mydb.sql --stdin-from-command -- pg_dump -U postgres mydb\nrestic snapshots\n```",{"title":104,"body":105},"Define a retention policy","```bash\nrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune\n```\n\nSeven dailies cover a full week, enough to catch corruption that only shows up after a few days. Four weeklies open a one-month window for a slow application problem, such as data disappearing bit by bit. Six monthlies let you go back to a state from before a failed migration. The `--prune` pass is essential: `forget` alone removes snapshots from the list without freeing space, and the storage bill keeps growing.",{"title":107,"body":108},"Check integrity: check, then read-data","These commands do not verify the same thing:\n\n```bash\nrestic check\nrestic check --read-data-subset=10%\nrestic check --read-data\n```\n\n`restic check` validates the repository structure (snapshots, trees, indexes, packs) without reading the content of the data files: it is fast and runs after every `forget --prune`. `--read-data` downloads and verifies every pack, which takes time and consumes egress bandwidth. In between, `--read-data-subset` checks a random share (`10%`, or a size such as `5G`) or a fixed slice (`1\u002F5` to `5\u002F5`, covering everything in five runs). A partial check every week and a full one once a month is a sound compromise.",{"title":110,"body":111},"Write the backup script and its systemd service","Group the steps into a script. It first writes a timestamped sentinel file, used later by the restore test, and stops at the first error thanks to `set -eu`:\n\n```bash\n#!\u002Fbin\u002Fsh\n# \u002Fusr\u002Flocal\u002Fbin\u002Frestic-backup.sh\nset -eu\ndate +%s > \u002Fopt\u002Frestic-sentinel.txt\nrestic backup \u002Fetc \u002Fvar\u002Fwww \u002Fopt\u002Fdocker-data \u002Fopt\u002Frestic-sentinel.txt\nrestic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune\nrestic check\n```\n\nThe service runs it with the variables from the environment file, without any secret appearing in the unit definition:\n\n```bash\n# \u002Fetc\u002Fsystemd\u002Fsystem\u002Frestic-backup.service\n[Unit]\nDescription=Restic backup\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=oneshot\nEnvironmentFile=\u002Froot\u002F.restic-env\nExecStart=\u002Fusr\u002Flocal\u002Fbin\u002Frestic-backup.sh\n```",{"title":113,"body":114},"Schedule it with a systemd timer","The timer triggers the service every night. `Persistent=true` catches up on a missed run if the VPS was off at the scheduled time, and `RandomizedDelaySec=900` spreads the start over fifteen minutes, useful when several servers target the same bucket:\n\n```bash\n# \u002Fetc\u002Fsystemd\u002Fsystem\u002Frestic-backup.timer\n[Unit]\nDescription=Daily restic backup\n\n[Timer]\nOnCalendar=*-*-* 03:00:00\nPersistent=true\nRandomizedDelaySec=900\n\n[Install]\nWantedBy=timers.target\n```\n\nEnable it, then check the next run and the logs of the last one:\n\n```bash\nchmod 700 \u002Fusr\u002Flocal\u002Fbin\u002Frestic-backup.sh\nsystemctl daemon-reload\nsystemctl enable --now restic-backup.timer\nsystemctl list-timers restic-backup.timer\njournalctl -u restic-backup.service --since today\n```\n\nIf you prefer `cron`, a `0 3 * * *` line that loads the environment file and calls the same script does the job, without the catch-up provided by `Persistent=`.",{"title":116,"body":117},"Automate the restore test","A backup that has never been restored remains a hypothesis. This second script restores only the sentinel file from the latest snapshot and compares it with the original: if last night's backup failed or the repository no longer returns anything, `cmp` fails and the service enters the `failed` state. The test targets the most recent snapshot: if you add `--stdin-from-command` dumps to the backup script, place them before the file backup, which must remain the last one.\n\n```bash\n#!\u002Fbin\u002Fsh\n# \u002Fusr\u002Flocal\u002Fbin\u002Frestic-restore-test.sh\nset -eu\nrm -rf \u002Ftmp\u002Frestic-test-restore\nrestic restore latest --target \u002Ftmp\u002Frestic-test-restore --include \u002Fopt\u002Frestic-sentinel.txt\ncmp \u002Ftmp\u002Frestic-test-restore\u002Fopt\u002Frestic-sentinel.txt \u002Fopt\u002Frestic-sentinel.txt\n```\n\nSchedule it weekly, after the nightly backup:\n\n```bash\n# \u002Fetc\u002Fsystemd\u002Fsystem\u002Frestic-restore-test.service\n[Service]\nType=oneshot\nEnvironmentFile=\u002Froot\u002F.restic-env\nExecStart=\u002Fusr\u002Flocal\u002Fbin\u002Frestic-restore-test.sh\n\n# \u002Fetc\u002Fsystemd\u002Fsystem\u002Frestic-restore-test.timer\n[Timer]\nOnCalendar=Sun 05:00:00\nPersistent=true\n\n[Install]\nWantedBy=timers.target\n```\n\nEnable the timer with `systemctl enable --now restic-restore-test.timer`, and wire the `failed` state of both services into your monitoring. Once a quarter, also restore a real directory, database included, on a test machine.",{"type":119,"title":120,"body":121},"tip","Restic secrets: an isolated file, never hard-coded in the unit","Never put `RESTIC_PASSWORD` or the S3 keys in an `Environment=` line of a systemd unit, in a versioned script or in a Dockerfile: variables declared in the unit can be read with `systemctl show`. The `\u002Froot\u002F.restic-env` file with `chmod 600`, loaded by `EnvironmentFile=`, keeps secrets out of the unit definition. To go further, systemd's `LoadCredential=` directive exposes a secret in a directory reserved for the service (`$CREDENTIALS_DIRECTORY`): Restic then reads its password through `RESTIC_PASSWORD_FILE`.",{"type":36,"title":123,"body":124},"Troubleshooting: common errors","**`restic init` or the first `backup` fails on the bucket.** First check that the variables are loaded (`echo $RESTIC_REPOSITORY`), then the endpoint: on B2 it must match your account's region, and the AWS endpoint (`s3.amazonaws.com`) is a frequent mistake. A B2 Application Key restricted to a single bucket also needs the `listAllBucketNames` permission to work with S3 tools, and the account's master key does not work with the S3 API. On R2, the token needs read and write permissions on the bucket's objects.\n\n**The timer does not fire.** Three commands are enough: `systemctl status restic-backup.timer` (active or not), `systemctl list-timers --all | grep restic` (next run), `journalctl -u restic-backup.service --since today` (log of the last run). To validate an `OnCalendar` expression, `systemd-analyze calendar '*-*-* 03:00:00'` must print the next trigger date.\n\n**The repository stays locked.** An interrupted backup (reboot, network drop) can leave a lock behind: `restic list locks` shows it, and `restic unlock` removes stale locks. Make sure beforehand that no other Restic operation is running.\n\n**`restic check --read-data` takes too long.** On a repository of several tens of GB, a full read takes hours and weighs on the egress allowance. Switch to `--read-data-subset=10%` or a `1\u002F4` slice every week, and keep the full read for a monthly maintenance window.",{"type":36,"title":126,"body":127},"Recovery plan: how long to restore everything?","The duration of a full restore depends on repository size, bandwidth between the VPS and the bucket, and the provider's egress policy. On R2, egress is free: nothing forces you to spread a restore out. On B2, it is free up to three times the average volume stored over the month; beyond that, a full restore of a large repository is billed.\n\nDo not guess this time, measure it. `restic stats` gives the repository size; then restore a meaningful directory (`restic restore latest --target \u002Ftmp\u002Ftest --include \u002Fetc`) and time the operation to extrapolate. Two practices shorten recovery: back up only what matters (no caches, logs, `\u002Ftmp` or abandoned Docker volumes), and write down in your procedure the order in which services come back, databases first, then the applications that depend on them.",{"type":119,"body":129},"Protect your backups against ransomware by enabling \"append-only\" mode on the backend: deploy a remote `rest-server` with the `--append-only` option, or use an S3 bucket with an IAM policy that forbids deletions. That way, even if your VPS is compromised and the attacker obtains the credentials, they will be unable to erase or encrypt your existing snapshots. Combine this with running `restic forget --prune` from a separate machine that does hold deletion rights.","Secure your data from day one","On a ServOrbit Cloud VPS with a preconfigured template, you install Restic in a few commands and schedule encrypted backups to the object storage of your choice.","Deploy my backup VPS","\u002Fvps-cloud",[135,153,171],{"id":136,"slug":137,"slugs":138,"title":142,"excerpt":143,"readTime":23,"views":18,"isPinned":19,"noindex":19,"publishedAt":144,"updatedAt":145,"category":146,"categories":147,"featuredImage":30,"bgImage":31,"posterImage":149,"relatedSolution":150},105,"monitoring-your-vps-with-uptime-kuma",{"fr":139,"en":137,"ar":140,"es":141},"superviser-vps-uptime-kuma","مراقبة-خادمك-الافتراضي-vps-باستخدام-uptime-kuma","supervisar-vps-con-uptime-kuma","Monitoring your VPS with Uptime Kuma","Deploy Uptime Kuma on your VPS to monitor your sites and services self-hosted, with alerts and a public status page.","2026-03-07T00:00:00+00:00","2026-11-09T20:55:19+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[148],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fsuperviser-vps-uptime-kuma-poster.svg",{"categorySlug":151,"appSlug":152},"monitoring-observability","uptime-kuma",{"id":154,"slug":155,"slugs":156,"title":160,"excerpt":161,"readTime":17,"views":162,"isPinned":19,"noindex":19,"publishedAt":163,"updatedAt":164,"category":165,"categories":166,"featuredImage":30,"bgImage":31,"posterImage":168,"relatedSolution":169},106,"vps-monitoring-with-grafana-and-prometheus",{"fr":157,"en":155,"ar":158,"es":159},"monitoring-vps-grafana-prometheus","مراقبة-الخادم-الافتراضي-vps-باستخدام-grafana-و-prometheus","monitorizacion-vps-grafana-prometheus","VPS Monitoring with Grafana and Prometheus","Deploy Prometheus 3.x, Grafana 13.x, Node Exporter and Alertmanager on your VPS with Docker Compose. Dashboards, alerts and hardening.",1,"2026-03-06T00:00:00+00:00","2026-10-05T14:05:27+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[167],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fmonitoring-vps-grafana-prometheus-poster.svg",{"categorySlug":151,"appSlug":170},"grafana",{"id":172,"slug":173,"slugs":174,"title":178,"excerpt":179,"readTime":180,"views":162,"isPinned":19,"noindex":19,"publishedAt":181,"updatedAt":182,"category":183,"categories":184,"featuredImage":30,"bgImage":31,"posterImage":186,"relatedSolution":187},107,"monitor-your-vps-in-real-time-with-netdata",{"fr":175,"en":173,"ar":176,"es":177},"monitorer-vps-netdata","راقب-خادمك-الافتراضي-vps-في-الوقت-الفعلي-باستخدام-netdata","monitorizar-vps-en-tiempo-real-con-netdata","Monitor your VPS in real time with Netdata","Install Netdata on your VPS for per-second real-time monitoring: thousands of metrics, zero configuration, alerts included.",3,"2026-03-05T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":23,"name":24,"slug":25,"color":26,"icon":27},[185],{"id":23,"name":24,"slug":25,"color":26,"icon":27},"\u002Fblog\u002Fcovers\u002Fmonitorer-vps-netdata-poster.svg",{"categorySlug":151,"appSlug":188},"netdata",true,1794270370088]