Add BTRFS snapshots guide, TinyAuth/Pocket ID diagrams, and Backrest restore docs #3

Merged
Djeex merged 9 commits from wip into main 2026-09-09 14:26:09 +02:00
14 changed files with 519 additions and 0 deletions
Showing only changes of commit 1a1e4418bb - Show all commits
+1
View File
@@ -42,3 +42,4 @@ __pycache__
# Scratch/demo files (not part of the site)
scratch
.screenshot
+6
View File
@@ -296,6 +296,8 @@ ui:
icon: text-[#175DDC]
---
Install and deploy Vaultwarden
::
::
::
@@ -313,6 +315,10 @@ Install and deploy Authentik
::card{icon="i-noto-crystal-ball" title="Multi-host Docker manager" to="/serveex/advanced/arcane"}
Install and deploy Arcane
::
::card{icon="i-lucide-database-backup" title="3-2-1 Backups" to="/serveex/advanced/backrest"}
Install and deploy Backrest
::
::
## Coming Soon
@@ -15,6 +15,8 @@ It supports a simple local username/password login out of the box, which is what
- [TinyAuth documentation](https://tinyauth.app/docs/getting-started)
- [TinyAuth on GitHub](https://github.com/tinyauthapp/tinyauth)
![Diagram of TinyAuth sitting behind SWAG as the forward-auth proxy in front of local services](/img/serveex/tinyauth.svg)
## Installation
::file-tree
@@ -15,6 +15,8 @@ This makes it a good fit if you just need a simple, fast SSO backend, for exampl
- [Pocket ID documentation](https://pocket-id.org/docs)
- [Pocket ID on GitHub](https://github.com/pocket-id/pocket-id)
![Diagram of Pocket ID acting as the native OIDC identity provider behind SWAG](/img/serveex/pocket-id-native.svg)
## Installation
::file-tree
@@ -230,6 +232,8 @@ Save, then copy the generated __Client ID__ and __Client Secret__. You'll need t
## Connecting Pocket ID to TinyAuth
[TinyAuth](/serveex/security/tinyauth) can delegate its login to Pocket ID instead of (or alongside) its local username/password, so anyone visiting a protected app authenticates with a passkey and gets forwarded through.
![Diagram of TinyAuth delegating login to Pocket ID via OIDC](/img/serveex/pocket-id.svg)
::steps{level="3"}
### Register TinyAuth as an OIDC client
@@ -0,0 +1,244 @@
---
title: Backrest
description: Install Backrest, a friendly web UI for restic, and back up your server properly following the 3-2-1 rule, to a local disk, another server, S3, or Backblaze B2.
---
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
Let's be honest for a second: "backup strategy" for most homelabbers means copying a few folders to a USB stick that one time in 2019, then hoping for the best. [Backrest](https://github.com/garethgeorge/backrest) is here to fix that, without making you learn a scary command-line tool first.
Under the hood, Backrest is a clean web interface on top of [restic](https://restic.net/), a battle-tested, open-source backup engine. Restic does the actual work (encrypting, deduplicating, and shipping your data wherever you tell it to); Backrest gives you buttons and forms instead of a wall of flags to memorize.
![Backrest's dashboard, showing several repositories and their recent backup activity](/img/serveex/backrest-dashboard.png)
## The 3-2-1 rule, or why one backup is not a backup
Before installing anything, let's talk about the rule that actually matters here, because a backup done wrong gives you false confidence, which is worse than no backup at all.
The **3-2-1 rule** says:
- **3** copies of your data: the original, plus at least two backups.
- **2** different types of storage: not two copies sitting on the same disk, or on two disks in the same machine.
- **1** copy offsite: physically somewhere else, not in the same room, house, or building as the original.
Each number closes a specific failure scenario:
- Only **1** backup? A single mistake (a bad `rm -rf`, a botched restore, a corrupted file silently copied over the good one) can take out your only safety net at the same time as the original.
- Backups on the **same type of storage** (say, a second internal drive in the same server)? A power surge, a firmware bug, or a cheap PSU dying can very well take out every disk in the box at once.
- No **offsite** copy? Fire, flood, theft, or "I unplugged the wrong power strip" don't care how many drives you have, if they're all in the same room.
This is also exactly why [RAID is not a backup](/general/storage/raid): RAID keeps a service running when a disk dies, it does nothing against ransomware encrypting every file it can reach, a fat-fingered delete, or your house catching fire. Backrest, pointed at a destination outside your server, is what actually covers those cases.
## What Backrest actually backs up, and where
Two concepts to know before clicking around:
- A **repository** is the destination: an encrypted, deduplicated storage location. This is your "2" and your "1" from the rule above, an external disk, another server, or cloud storage.
- A **plan** is the rule you define: which folders to back up, into which repository, on what schedule, and how many old snapshots to keep around.
You can have several plans backing up to several repositories at once, which is exactly how you'd build a real 3-2-1 setup: one plan to a local repository for quick restores, another plan to an offsite repository for the "my house is on fire" scenario.
## Installation
::file-tree
---
tree:
/:
- srv:
- docker:
- backrest:
- data/
- config/
- cache/
- compose.yaml
---
::
::steps{level="3"}
### Deploy the stack
Open Dockge, click `compose`, name the stack `backrest`, and paste the following:
```yaml [compose.yaml]
---
services:
backrest:
image: garethgeorge/backrest:latest
container_name: backrest
restart: unless-stopped
ports:
- 9898:9898
volumes:
- ./data:/data
- ./config:/config
- ./cache:/cache
# Whatever you want Backrest to be able to back up has to be
# mounted here too: this stack only sees what it's given.
- /srv/docker:/userdata/docker:ro
environment:
- BACKREST_DATA=/data
- BACKREST_CONFIG=/config/config.json
- XDG_CACHE_HOME=/cache
- TZ=Europe/Paris
```
::note
The `/srv/docker:/userdata/docker:ro` line is what lets Backrest see the rest of your stacks to back them up, mounted read-only since a backup tool has no business writing to the things it's backing up. Add one line per host folder you want covered, `/media:/userdata/media:ro` for your media library, and so on. Got a USB key or external drive plugged in? Mount it too, that's exactly where your first repository is going.
::
::tip{icon=""}
✨ __Tip:__ Add the Watchtower label to automate updates
```yaml [compose.yaml]
services:
backrest:
#...
labels:
- com.centurylinklabs.watchtower.enable=true
```
::
Deploy the container, then open `http://yourserverip:9898`. The first visit asks you to set an admin username and password: do it immediately, Backrest has no account by default and the setup screen is wide open until you do.
### Done!
::
## Creating your first repository
![Backrest's Add Restic Repository form, showing a Backblaze B2 repository URI](/img/serveex/backrest.png)
In Backrest, go to **Add Repo**. The form is split into a few sections, here's what each field actually does:
- **Repo Name**: whatever helps you recognize it later, `usb-key` or `offsite-vps` for instance. You can't rename it afterwards, so pick something you won't regret.
- **Auto Unlock**: leave this off unless you understand what it does. Restic locks a repository while it's working on it, so a second process doesn't corrupt things by writing at the same time. Auto Unlock removes that lock automatically on startup, which is convenient if Backrest crashed mid-backup and left a stale lock behind, but genuinely unsafe if two machines ever write to the same repository at once. For the single-server homelab setup this article covers, it's a minor convenience; leave it off if in doubt.
- **Shared**: only relevant to Backrest's multihost feature (several of your machines managing the same repo config). Ignore it for a single server.
- **Repository URI**: where the data actually lives. This is the field that changes for every destination below.
- **Password**: the encryption password for this repository, click **Generate** for a strong random one. **Save it somewhere outside this server**, a password manager, a note on your phone, anywhere but a text file sitting next to the backups it protects. Lose it, and every single backup becomes an expensive pile of unreadable noise, no exceptions, not even for the developers of restic.
- **Env Vars**: where you'll paste credentials for destinations that need them (S3 and B2 below). Local disks and SFTP don't need any.
::note
The **Scheduling**, **Hooks**, and **Advanced** tabs of this form configure repository-wide maintenance (pruning old data, verifying integrity, notifications) rather than anything destination-specific. They're covered at the end of this article, once you've got a repository actually working.
::
### Backing up to a local disk or USB key
The simplest possible offsite copy is a drive you physically move somewhere else after each backup, or a second machine's disk reached over the network. Either way, from Backrest's point of view it's just a folder, so the setup is identical: plug in the drive (or mount the remote share) on the host, add it to the compose file's volumes the same way you did for `/srv/docker` above, then in the Repository URI field, use the path as it appears **inside the container**:
```text
/userdata/backup-drive
```
That's it, no credentials, no Env Vars. This is the fastest repository to restore from too, since there's no network round-trip involved, which makes it a great pick for your "quick recovery" copy, paired with a proper offsite one below for the "my house is on fire" scenario.
::caution
__If it fails:__ the path has to exist and be writable by the container before you submit the form. An empty folder is fine, restic initializes the repository structure itself on first use.
::
### Backing up to another server
No cloud account, no problem: if you have SSH access to another machine, a friend's server, a cheap VPS, a Raspberry Pi at a relative's house, that's a perfectly valid offsite repository, and it costs whatever that machine already costs you.
First, make sure this server can SSH into the other one without typing a password every time:
```bash [Terminal]
ssh-keygen -t ed25519 -f /srv/docker/backrest/config/id_ed25519 -N ""
ssh-copy-id -i /srv/docker/backrest/config/id_ed25519.pub youruser@theotherserver
```
Mount that key into the container by adding it to the compose file's volumes:
```yaml [compose.yaml]
volumes:
# ...
- ./config/id_ed25519:/root/.ssh/id_ed25519:ro
```
Redeploy the stack, then in Backrest use:
```text
sftp:youruser@theotherserver:/path/to/backups
```
::caution
__If it fails:__ the target folder (`/path/to/backups` above) has to already exist on the other server, and that user needs write access to it. SSH there once by hand first (`ssh youruser@theotherserver`) to confirm the connection works and accept the host key, Backrest running inside a container won't get the interactive prompt for that.
::
## Advanced: cloud object storage
A local drive or a friend's spare server covers the 3-2-1 rule perfectly well, and costs nothing beyond what you already own. Cloud object storage is the other classic option, worth it once you want an offsite copy that doesn't depend on anyone's spare hardware staying online, at the cost of a few cents to a few euros a month depending on how much you back up.
### Backblaze B2
[Backblaze B2](https://www.backblaze.com/cloud-storage) is object storage built with exactly this use case in mind, and it's usually the cheapest option for the "write often, read rarely" pattern a backup is.
Create a bucket in your Backblaze account, then generate an **application key** scoped to it. In Backrest, use:
```text
b2:your-bucket-name:backrest
```
With the following Env Vars:
| Variable | Value |
|----------|-------|
| `B2_ACCOUNT_ID` | The application key ID |
| `B2_ACCOUNT_KEY` | The application key itself |
### S3-compatible storage
S3 isn't just an Amazon thing, it's a storage protocol that most cloud providers speak (OVH, Scaleway, MinIO if you self-host your own, and plenty of others), which makes it a solid, portable choice if you'd rather not depend on one specific provider.
Create a bucket with your provider of choice, then in Backrest's Repository URI field, use:
```text
s3:https://s3.your-provider.com/your-bucket-name/backrest
```
For actual AWS S3, drop the custom endpoint:
```text
s3:s3.amazonaws.com/your-bucket-name/backrest
```
With the following Env Vars:
| Variable | Value |
|----------|-------|
| `AWS_ACCESS_KEY_ID` | The access key from your provider |
| `AWS_SECRET_ACCESS_KEY` | The secret key from your provider |
::note
Generate these from your provider's dashboard, usually under something like "API keys" or "S3 credentials", scoped to that one bucket only if the provider allows it. There's no reason for a backup job's key to be able to touch anything else on your account.
::
### Repository maintenance (optional, but worth setting up once)
Back in the **Scheduling** tab, three policies keep a repository healthy over time. None of them are required to start backing up, restic works fine without ever touching them, but they're worth understanding once your repository has been running for a while:
:::collapsible{name="the three maintenance policies"}
- **Prune Policy**: deletes data that's no longer referenced by any snapshot (because old snapshots holding it were forgotten, see the retention policy in the next section). This is the only operation that actually frees up space on your storage. It's slow and reads a lot of data, so schedule it rarely, once a month is Backrest's own suggestion. **Max Unused After Prune** controls how thorough it is: a higher percentage leaves more unused data behind but finishes faster and copies less.
- **Check Policy**: verifies your repository isn't silently corrupted. **Read Data %** controls how much of the actual backed-up data gets re-read and checksummed, not just the repository's internal structure. 100% means a full re-read of everything, which uses real bandwidth and time; a smaller percentage checks a random sample instead. Once a month is, again, a reasonable default.
- **Forget Policy**: an optional repository-wide retention rule, applied across every plan writing to this repository instead of per-plan. Leave this disabled unless you specifically want one retention policy shared by multiple plans, it disables each plan's own retention policy the moment you turn it on.
Every one of these has a **Schedule Type**: `Disabled`, a plain `Interval` in hours or days, or a `Cron Expression` for anything more specific, plus a **Reference Clock** (your server's local time, UTC, or relative to the last time it ran) to anchor that schedule against.
:::
## Creating a backup plan
Back in Backrest, go to **Add Plan**. This form covers what to back up and when, as opposed to the repository form above, which only covers where:
- **Plan Name**: same rule as the repo name, pick something clear, you can't change it later.
- **Repository**: the one you just created above.
- **Paths**: pick from what you mounted earlier, `/userdata/docker` for your stacks, for instance. You can add several.
- **Excludes** and **Excludes (Case Insensitive)**: patterns to skip within those paths, handy for cache folders or anything genuinely disposable that would otherwise bloat every snapshot for no reason.
- **Schedule Type**: same three choices as the repository's own schedules above, `Disabled`, an `Interval`, or a `Cron Expression`. A nightly cron like `0 3 * * *` (every day at 3 AM) is a reasonable default for a homelab.
- **Retention Policy**: how many snapshots to keep, and for how long. **By Time Period** lets you say "keep 7 daily, 4 weekly, 6 monthly" independently, which gives you plenty of restore points spread over time without the repository growing forever, since restic deduplicates unchanged data between snapshots anyway. **By Count** instead just keeps the last N snapshots regardless of age. **Latest (Count)** on top of either mode guarantees a minimum number of recent snapshots always survive, whatever the rest of the policy says.
- **Advanced**: **Backup Flags** let you pass extra options straight to the underlying `restic backup` command for anything this form doesn't expose; **Hooks** run scripts or send notifications on backup events, the same mechanism as the repository's own Hooks tab, just scoped to this one plan instead of every plan using the repository.
That retention policy is your real defense against ransomware, by the way: if something starts encrypting your files at 2 AM, tonight's backup is compromised, but last week's snapshot isn't, and restic lets you restore from any of them.
::tip{icon="" to="/nonsense/bash/backrest-docker-stop"}
✨ __Going further:__ if some of what you're backing up includes a live database, stopping its container for the few seconds a backup takes is safer than backing it up while it's being written to. See **Backrest Docker Stop** for a script that does exactly that, triggered automatically by Backrest itself.
::
And that's it, you now have an actual backup strategy instead of a folder called `backup_final_v2_REAL`.
+6
View File
@@ -296,6 +296,8 @@ ui:
icon: text-[#175DDC]
---
Installer et déployer Vaultwarden
::
::
::
@@ -313,6 +315,10 @@ Installer et déployer Authentik
::card{icon="i-noto-crystal-ball" title="Gestionnaire Docker multi-hôtes" to="/serveex/advanced/arcane"}
Installer et déployer Arcane
::
::card{icon="i-lucide-database-backup" title="Sauvegardes en 3-2-1" to="/serveex/advanced/backrest"}
Installer et déployer Backrest
::
::
## Bientôt
@@ -15,6 +15,8 @@ Nativement il gère une simple connexion locale identifiant/mot de passe, c'est
- [Documentation de TinyAuth](https://tinyauth.app/docs/getting-started)
- [TinyAuth sur GitHub](https://github.com/tinyauthapp/tinyauth)
![Schéma de TinyAuth placé derrière SWAG en tant que proxy de forward-auth devant les services locaux](/img/serveex/tinyauth.svg)
## Installation
::file-tree
@@ -15,6 +15,8 @@ C'est donc un bon choix si vous voulez simplement un backend SSO simple et rapid
- [Documentation de Pocket ID](https://pocket-id.org/docs)
- [Pocket ID sur GitHub](https://github.com/pocket-id/pocket-id)
![Schéma de Pocket ID agissant comme fournisseur d'identité OIDC natif derrière SWAG](/img/serveex/pocket-id-native.svg)
## Installation
::file-tree
@@ -230,6 +232,8 @@ Enregistrez, puis copiez le __Client ID__ et le __Client Secret__ générés. Vo
## Connecter Pocket ID à TinyAuth
[TinyAuth](/serveex/security/tinyauth) peut déléguer sa connexion à Pocket ID plutôt que (ou en plus de) son identifiant/mot de passe local, de sorte que quiconque visite une application protégée s'authentifie avec une passkey et se retrouve redirigé.
![Schéma de TinyAuth délégant la connexion à Pocket ID via OIDC](/img/serveex/pocket-id.svg)
::steps{level="3"}
### Enregistrer TinyAuth comme client OIDC
@@ -0,0 +1,244 @@
---
title: Backrest
description: Installer Backrest, une interface web conviviale pour restic, et sauvegarder son serveur comme il faut avec la règle 3-2-1, vers un disque local, un autre serveur, S3 ou Backblaze B2.
---
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
Soyons honnêtes deux secondes : la "stratégie de sauvegarde" de la plupart des homelabbers, c'est avoir copié quelques dossiers sur une clé USB une fois en 2019, et espérer que tout ira bien. [Backrest](https://github.com/garethgeorge/backrest) est là pour arranger ça, sans vous forcer à apprendre un outil en ligne de commande qui fait peur.
Sous le capot, Backrest est une interface web propre posée sur [restic](https://restic.net/), un moteur de sauvegarde open-source qui a fait ses preuves. Restic fait le vrai travail (chiffrer, dédupliquer, et envoyer vos données là où vous le lui dites) ; Backrest vous donne des boutons et des formulaires plutôt qu'un mur d'options à retenir.
![Tableau de bord de Backrest, montrant plusieurs dépôts et leur activité de sauvegarde récente](/img/serveex/backrest-dashboard.png)
## La règle du 3-2-1, ou pourquoi une seule sauvegarde n'en est pas une
Avant d'installer quoi que ce soit, parlons de la règle qui compte vraiment ici, parce qu'une sauvegarde mal pensée vous donne une fausse confiance, ce qui est pire que pas de sauvegarde du tout.
La **règle du 3-2-1** dit :
- **3** copies de vos données : l'originale, plus au moins deux sauvegardes.
- **2** types de stockage différents : pas deux copies sur le même disque, ni sur deux disques dans la même machine.
- **1** copie hors site : physiquement ailleurs, pas dans la même pièce, la même maison ou le même bâtiment que l'original.
Chaque chiffre ferme un scénario de panne précis :
- Une seule **(1)** sauvegarde ? Une seule erreur (un `rm -rf` malheureux, une restauration ratée, un fichier corrompu copié par-dessus le bon sans que vous le voyiez) peut emporter votre seul filet de sécurité en même temps que l'original.
- Des sauvegardes sur le **même type de stockage** (disons, un second disque interne dans le même serveur) ? Une surtension, un bug de firmware, ou une alimentation bas de gamme qui lâche peuvent très bien emporter tous les disques du boîtier d'un coup.
- Pas de copie **hors site** ? Un incendie, une inondation, un vol, ou "j'ai débranché la mauvaise multiprise" se moquent du nombre de disques que vous avez, s'ils sont tous dans la même pièce.
C'est aussi exactement pour ça que [le RAID n'est pas une sauvegarde](/general/storage/raid) : le RAID garde un service en marche quand un disque meurt, il ne fait rien contre un ransomware qui chiffre tous les fichiers qu'il peut atteindre, une suppression malheureuse, ou votre maison qui prend feu. Backrest, pointé vers une destination en dehors de votre serveur, est ce qui couvre réellement ces cas-là.
## Ce que Backrest sauvegarde, et où
Deux concepts à connaître avant de cliquer partout :
- Un **dépôt** (repository) est la destination : un espace de stockage chiffré et dédupliqué. C'est votre "2" et votre "1" de la règle ci-dessus, un disque externe, un autre serveur, ou du stockage cloud.
- Un **plan** est la règle que vous définissez : quels dossiers sauvegarder, vers quel dépôt, selon quel planning, et combien d'anciens instantanés (snapshots) conserver.
Vous pouvez avoir plusieurs plans sauvegardant vers plusieurs dépôts en même temps, ce qui est exactement comment on construit un vrai 3-2-1 : un plan vers un dépôt local pour des restaurations rapides, un autre plan vers un dépôt hors site pour le scénario "ma maison brûle".
## Installation
::file-tree
---
tree:
/:
- srv:
- docker:
- backrest:
- data/
- config/
- cache/
- compose.yaml
---
::
::steps{level="3"}
### Déployer la stack
Ouvrez Dockge, cliquez sur `compose`, nommez la stack `backrest`, et collez ce qui suit :
```yaml [compose.yaml]
---
services:
backrest:
image: garethgeorge/backrest:latest
container_name: backrest
restart: unless-stopped
ports:
- 9898:9898
volumes:
- ./data:/data
- ./config:/config
- ./cache:/cache
# Tout ce que vous voulez que Backrest puisse sauvegarder doit
# aussi être monté ici : la stack ne voit que ce qu'on lui donne.
- /srv/docker:/userdata/docker:ro
environment:
- BACKREST_DATA=/data
- BACKREST_CONFIG=/config/config.json
- XDG_CACHE_HOME=/cache
- TZ=Europe/Paris
```
::note
La ligne `/srv/docker:/userdata/docker:ro` est ce qui permet à Backrest de voir le reste de vos stacks pour les sauvegarder, montée en lecture seule puisqu'un outil de sauvegarde n'a aucune raison d'écrire dans ce qu'il sauvegarde. Ajoutez une ligne par dossier de l'hôte à couvrir, `/media:/userdata/media:ro` pour votre bibliothèque média, et ainsi de suite. Une clé USB ou un disque externe branché ? Montez-le aussi, c'est exactement là que va aller votre premier dépôt.
::
::tip{icon=""}
✨ __Astuce :__ ajoutez le label Watchtower pour automatiser les mises à jour
```yaml [compose.yaml]
services:
backrest:
#...
labels:
- com.centurylinklabs.watchtower.enable=true
```
::
Déployez le conteneur, puis ouvrez `http://ipdevotreserveur:9898`. La première visite vous demande de définir un identifiant et un mot de passe administrateur : faites-le immédiatement, Backrest n'a pas de compte par défaut et l'écran de configuration est grand ouvert tant que vous ne l'avez pas fait.
### Terminé !
::
## Créer votre premier dépôt
![Formulaire "Add Restic Repository" de Backrest, montrant une URI de dépôt Backblaze B2](/img/serveex/backrest.png)
Dans Backrest, allez dans **Add Repo**. Le formulaire est découpé en plusieurs sections, voici ce que fait chaque champ :
- **Repo Name** : ce qui vous aidera à le reconnaître plus tard, `cle-usb` ou `vps-hors-site` par exemple. Impossible de le renommer ensuite, choisissez quelque chose que vous ne regretterez pas.
- **Auto Unlock** : laissez désactivé sauf si vous comprenez bien ce que ça fait. Restic verrouille un dépôt pendant qu'il y travaille, pour qu'un second processus ne corrompe pas tout en écrivant en même temps. Auto Unlock retire ce verrou automatiquement au démarrage, pratique si Backrest a planté en pleine sauvegarde et laissé un verrou fantôme, mais réellement dangereux si deux machines écrivent un jour dans le même dépôt en même temps. Pour la configuration mono-serveur de cet article, c'est un confort mineur ; laissez désactivé en cas de doute.
- **Shared** : ne concerne que la fonctionnalité multihost de Backrest (plusieurs de vos machines gérant la même configuration de dépôt). Ignorez-le pour un serveur unique.
- **Repository URI** : là où les données vivent réellement. C'est ce champ qui change pour chaque destination ci-dessous.
- **Password** : le mot de passe de chiffrement de ce dépôt, cliquez sur **Generate** pour en générer un solide aléatoirement. **Conservez-le quelque part en dehors de ce serveur**, un gestionnaire de mots de passe, une note sur votre téléphone, n'importe où sauf un fichier texte posé à côté des sauvegardes qu'il protège. Perdez-le, et chaque sauvegarde devient un tas de bruit illisible et coûteux, sans exception, même pour les développeurs de restic.
- **Env Vars** : là où vous collerez les identifiants pour les destinations qui en ont besoin (S3 et B2 plus bas). Un disque local et le SFTP n'en ont besoin d'aucun.
::note
Les onglets **Scheduling**, **Hooks** et **Advanced** de ce formulaire configurent la maintenance du dépôt dans son ensemble (purge des anciennes données, vérification d'intégrité, notifications) plutôt que quoi que ce soit de spécifique à une destination. Ils sont couverts à la fin de cet article, une fois que vous avez un dépôt qui fonctionne réellement.
::
### Sauvegarder vers un disque local ou une clé USB
La copie hors site la plus simple qui soit est un disque que vous déplacez physiquement ailleurs après chaque sauvegarde, ou le disque d'une seconde machine joint par le réseau. Dans les deux cas, du point de vue de Backrest c'est juste un dossier, donc la configuration est identique : branchez le disque (ou montez le partage réseau) sur l'hôte, ajoutez-le aux volumes du fichier compose comme vous l'avez fait pour `/srv/docker` plus haut, puis dans le champ Repository URI, utilisez le chemin tel qu'il apparaît **à l'intérieur du conteneur** :
```text
/userdata/disque-sauvegarde
```
Voilà, aucun identifiant, aucune variable d'environnement. C'est aussi le dépôt le plus rapide pour restaurer, puisqu'il n'y a aucun aller-retour réseau, ce qui en fait un excellent choix pour votre copie de "récupération rapide", accompagnée d'une vraie copie hors site ci-dessous pour le scénario "ma maison brûle".
::caution
__Si ça ne marche pas :__ le chemin doit exister et être accessible en écriture par le conteneur avant de valider le formulaire. Un dossier vide convient très bien, restic initialise lui-même la structure du dépôt à la première utilisation.
::
### Sauvegarder vers un autre serveur
Pas de compte cloud, pas de problème : si vous avez un accès SSH à une autre machine, le serveur d'un ami, un petit VPS pas cher, un Raspberry Pi chez de la famille, c'est un dépôt hors site parfaitement valable, et ça ne coûte que ce que cette machine vous coûte déjà.
D'abord, assurez-vous que ce serveur peut se connecter en SSH à l'autre sans taper de mot de passe à chaque fois :
```bash [Terminal]
ssh-keygen -t ed25519 -f /srv/docker/backrest/config/id_ed25519 -N ""
ssh-copy-id -i /srv/docker/backrest/config/id_ed25519.pub votreutilisateur@lautreserveur
```
Montez cette clé dans le conteneur en l'ajoutant aux volumes du fichier compose :
```yaml [compose.yaml]
volumes:
# ...
- ./config/id_ed25519:/root/.ssh/id_ed25519:ro
```
Redéployez la stack, puis dans Backrest utilisez :
```text
sftp:votreutilisateur@lautreserveur:/chemin/vers/les/sauvegardes
```
::caution
__Si ça ne marche pas :__ le dossier cible (`/chemin/vers/les/sauvegardes` ci-dessus) doit déjà exister sur l'autre serveur, et cet utilisateur doit avoir le droit d'y écrire. Connectez-vous une fois à la main (`ssh votreutilisateur@lautreserveur`) pour confirmer que la connexion fonctionne et accepter la clé de l'hôte, Backrest tournant dans un conteneur n'aura pas l'invite interactive pour ça.
::
## Avancé : stockage objet dans le cloud
Un disque local ou le serveur de secours d'un ami couvre très bien la règle du 3-2-1, et ne coûte rien de plus que ce que vous possédez déjà. Le stockage objet dans le cloud est l'autre option classique, intéressante quand vous voulez une copie hors site qui ne dépend pas du matériel de quelqu'un d'autre restant allumé, pour un coût de quelques centimes à quelques euros par mois selon ce que vous sauvegardez.
### Backblaze B2
[Backblaze B2](https://www.backblaze.com/cloud-storage) est du stockage objet pensé exactement pour cet usage, et c'est généralement l'option la moins chère pour le schéma "on écrit souvent, on lit rarement" d'une sauvegarde.
Créez un bucket dans votre compte Backblaze, puis générez une **clé d'application** limitée à celui-ci. Dans Backrest, utilisez :
```text
b2:nom-de-votre-bucket:backrest
```
Avec les variables d'environnement suivantes :
| Variable | Valeur |
|----------|-------|
| `B2_ACCOUNT_ID` | L'identifiant de la clé d'application |
| `B2_ACCOUNT_KEY` | La clé d'application elle-même |
### Stockage compatible S3
S3 n'est pas juste un truc Amazon, c'est un protocole de stockage que la plupart des fournisseurs cloud parlent (OVH, Scaleway, MinIO si vous auto-hébergez le vôtre, et bien d'autres), ce qui en fait un choix solide et portable si vous préférez ne pas dépendre d'un fournisseur en particulier.
Créez un bucket chez le fournisseur de votre choix, puis dans le champ Repository URI de Backrest, utilisez :
```text
s3:https://s3.votre-fournisseur.com/nom-de-votre-bucket/backrest
```
Pour du vrai AWS S3, retirez le endpoint personnalisé :
```text
s3:s3.amazonaws.com/nom-de-votre-bucket/backrest
```
Avec les variables d'environnement suivantes :
| Variable | Valeur |
|----------|-------|
| `AWS_ACCESS_KEY_ID` | La clé d'accès de votre fournisseur |
| `AWS_SECRET_ACCESS_KEY` | La clé secrète de votre fournisseur |
::note
Générez ces clés depuis le tableau de bord de votre fournisseur, généralement sous un intitulé du genre "Clés API" ou "Identifiants S3", limitées à ce seul bucket si le fournisseur le permet. Il n'y a aucune raison que la clé d'un job de sauvegarde puisse toucher à autre chose sur votre compte.
::
### Maintenance du dépôt (optionnel, mais à mettre en place une fois pour toutes)
Retour dans l'onglet **Scheduling**, trois politiques gardent un dépôt en bonne santé dans le temps. Aucune n'est nécessaire pour commencer à sauvegarder, restic fonctionne très bien sans jamais y toucher, mais elles valent la peine d'être comprises une fois que votre dépôt tourne depuis un moment :
:::collapsible{name="les trois politiques de maintenance"}
- **Prune Policy** : supprime les données qui ne sont plus référencées par aucun instantané (parce que les anciens instantanés qui les contenaient ont été oubliés, voir la politique de rétention plus bas). C'est la seule opération qui libère réellement de l'espace sur votre stockage. C'est lent et ça lit beaucoup de données, donc planifiez-la rarement, une fois par mois est la suggestion de Backrest lui-même. **Max Unused After Prune** contrôle à quel point c'est minutieux : un pourcentage plus élevé laisse plus de données inutilisées derrière mais termine plus vite et copie moins.
- **Check Policy** : vérifie que votre dépôt n'est pas silencieusement corrompu. **Read Data %** contrôle quelle proportion des données réellement sauvegardées est relue et vérifiée par somme de contrôle, pas juste la structure interne du dépôt. 100% signifie relire l'intégralité du dépôt, ce qui consomme de la bande passante et du temps réels ; un pourcentage plus faible vérifie un échantillon aléatoire à la place. Une fois par mois est, encore une fois, un défaut raisonnable.
- **Forget Policy** : une règle de rétention optionnelle pour tout le dépôt, appliquée à travers tous les plans qui y écrivent au lieu d'être par plan. Laissez-la désactivée sauf si vous voulez spécifiquement une seule politique de rétention partagée par plusieurs plans, elle désactive la politique de rétention propre à chaque plan dès que vous l'activez.
Chacune de ces politiques a un **Schedule Type** : `Disabled`, un simple `Interval` en heures ou en jours, ou une `Cron Expression` pour quelque chose de plus précis, plus une **Reference Clock** (l'heure locale de votre serveur, UTC, ou relative à la dernière exécution) pour ancrer ce planning.
:::
## Créer un plan de sauvegarde
Retour dans Backrest, allez dans **Add Plan**. Ce formulaire couvre quoi sauvegarder et quand, contrairement au formulaire de dépôt ci-dessus, qui ne couvre que où :
- **Plan Name** : même règle que le nom du dépôt, choisissez quelque chose de clair, impossible à changer ensuite.
- **Repository** : celui que vous venez de créer plus haut.
- **Paths** : choisissez parmi ce que vous avez monté plus tôt, `/userdata/docker` pour vos stacks par exemple. Vous pouvez en ajouter plusieurs.
- **Excludes** et **Excludes (Case Insensitive)** : des motifs à ignorer au sein de ces chemins, pratique pour les dossiers de cache ou tout ce qui est vraiment jetable et qui gonflerait chaque instantané pour rien.
- **Schedule Type** : les trois mêmes choix que les plannings du dépôt ci-dessus, `Disabled`, un `Interval`, ou une `Cron Expression`. Un cron nocturne du type `0 3 * * *` (tous les jours à 3h du matin) est un défaut raisonnable pour un homelab.
- **Retention Policy** : combien d'instantanés conserver, et pendant combien de temps. **By Time Period** vous permet de dire "garder 7 quotidiens, 4 hebdomadaires, 6 mensuels" indépendamment, ce qui vous donne largement assez de points de restauration étalés dans le temps sans que le dépôt grossisse indéfiniment, puisque restic déduplique de toute façon les données inchangées entre les instantanés. **By Count** conserve à la place simplement les N derniers instantanés, quel que soit leur âge. **Latest (Count)** en plus de l'un ou l'autre mode garantit qu'un nombre minimum d'instantanés récents survit toujours, quoi que dise le reste de la politique.
- **Advanced** : **Backup Flags** vous permet de passer des options supplémentaires directement à la commande `restic backup` sous-jacente pour tout ce que ce formulaire n'expose pas ; **Hooks** exécute des scripts ou envoie des notifications sur les événements de sauvegarde, le même mécanisme que l'onglet Hooks du dépôt, mais limité à ce seul plan au lieu de tous les plans utilisant le dépôt.
Cette politique de rétention est d'ailleurs votre vraie défense contre les ransomwares : si quelque chose commence à chiffrer vos fichiers à 2h du matin, la sauvegarde de ce soir est compromise, mais celle de la semaine dernière ne l'est pas, et restic vous permet de restaurer depuis n'importe laquelle d'entre elles.
::tip{icon="" to="/nonsense/bash/backrest-docker-stop"}
✨ __Pour aller plus loin :__ si ce que vous sauvegardez inclut une base de données en cours d'exécution, arrêter son conteneur le temps des quelques secondes que prend la sauvegarde est plus sûr que de la sauvegarder pendant qu'elle écrit. Voir **Backrest Docker Stop** pour un script qui fait exactement ça, déclenché automatiquement par Backrest lui-même.
::
Et voilà, vous avez maintenant une vraie stratégie de sauvegarde plutôt qu'un dossier appelé `sauvegarde_finale_v2_LAVRAIE`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 34 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 30 KiB