---
title: "Production"
description: "Reverse proxy et en-têtes forwarded, confiance envers l'IP du client, invariant de l'instance unique, sauvegarde régulière par la commande intégrée."
---

# Production

Cette page traite de la mise en production d'une instance : comment la placer correctement derrière un reverse proxy, ce que signifie l'invariant de l'instance unique et comment la sauvegarder. Notarium se déploie sous forme d'[un conteneur unique](/docs/self-hosting/install/) — la configuration de production se résume aux trois points ci-dessous.

## Reverse proxy et en-têtes forwarded

Vous placez un reverse proxy (nginx, Caddy, Traefik) devant l'application — il termine le TLS et relaie vers le port de Notarium. L'exigence clé : le proxy **doit** transmettre les en-têtes décrivant l'adresse externe.

> [!warning] L'erreur de déploiement la plus fréquente
> Le reverse proxy doit envoyer `X-Forwarded-Host` (ou laisser `Host` intact) et `X-Forwarded-Proto: https`. Sinon, les mutations authentifiées par cookie depuis l'interface sont rejetées comme cross-origin — le symptôme est « je le vois mais je ne peux pas enregistrer ». La transmission de `X-Forwarded-Proto` est également nécessaire pour que le cookie de session reçoive le drapeau `Secure`.

Voici pourquoi : lors des mutations, le contrôle d'Origin compare la source de la requête à l'adresse que voit le navigateur — et cette adresse arrive dans un en-tête forwarded. Les appels d'agents via un PAT Bearer sont dispensés de ce contrôle (ils ne portent aucun cookie — donc aucune surface CSRF). Le proxy, quant à lui, doit **écraser** les en-têtes forwarded avec ses propres valeurs, et non laisser passer tels quels ceux du client.

Si vous activez l'autorisation OAuth pour les agents, définissez `PUBLIC_BASE_URL` lorsque vous êtes derrière le proxy (par exemple, `https://notes.example.com`) — une adresse externe stable pour les métadonnées OAuth. Sans elle, l'adresse est déduite des en-têtes forwarded. Voir [Configuration](/docs/self-hosting/configuration/).

## La confiance envers l'adresse IP du client

Un axe distinct de celui de l'adresse : la **véritable adresse IP du client**. Deux limites se comptent par IP : les tentatives de connexion et l'admission de nouveaux clients OAuth. Derrière un proxy, toutes les requêtes arrivent de la même adresse ; sans configuration explicite, ces limites se compteraient donc par proxy — c'est-à-dire pour tout le monde à la fois.

Le réglage s'appelle `TRUST_PROXY` : la liste, séparée par des virgules, des IP/CIDR des proxys **immédiats**.

```bash
# .env — mettez l'adresse de votre propre conteneur proxy ou de votre hôte
TRUST_PROXY=172.18.0.0/16
```

Le défaut sûr, c'est de laisser la variable non définie : `X-Forwarded-For` n'a alors aucune incidence sur les limites, et aucun en-tête ne permet d'usurper l'IP d'autrui. Ne la définissez que si vous connaissez l'adresse de votre proxy avec certitude, et gardez la liste aussi restreinte que possible.

> [!warning] N'y inscrivez pas « tout le monde »
> Les valeurs booléennes, les nombres de sauts, les plages nommées et les plages couvrant toutes les adresses (`/0`) sont rejetés au démarrage. Faire confiance à toutes les adresses reviendrait à laisser n'importe quel client s'attribuer une IP par en-tête et contourner la limite de connexion.

Ce réglage n'a aucun effet sur la transmission de `X-Forwarded-Host` et `X-Forwarded-Proto` — ce sont des axes indépendants, et le contrat de la section précédente reste inchangé.

## L'invariant de l'instance unique

Notarium est conçu pour un **processus unique**. Deux états d'authentification vivent dans la mémoire du processus :

- **la limite de tentatives de connexion** — les compteurs de tentatives ;
- **le registre des sockets SSE** — le mécanisme par lequel la révocation d'un accès coupe instantanément les connexions actives.

Derrière un répartiteur de charge avec plusieurs instances et sans stockage partagé, ces mécanismes s'effondrent : un attaquant multiplie la limite par le nombre d'instances, et révoquer un accès sur une instance ne fermera pas une connexion SSE maintenue ouverte sur une autre.

> [!note] Plusieurs instances derrière un répartiteur de charge
> Les deux états vivent dans la mémoire du processus ; c'est pourquoi, derrière un répartiteur de charge avec plusieurs instances et sans stockage partagé, ces mécanismes ne fonctionnent pas. [Déplacer la base de métadonnées vers Postgres](/docs/self-hosting/database/) vous donne un état partagé, mais cela seul ne suffit pas pour la mise à l'échelle horizontale. Gardez une seule instance.

## Sauvegardes

La sauvegarde canonique est une **commande intégrée à l'image**, et non une copie des fichiers effectuée de l'extérieur : `notarium backup` assemble une archive ZIP vérifiée et la renvoie en flux pendant que le service continue de tourner.

```bash
docker compose exec -T notarium backup > notarium-$(date -u +%Y%m%dT%H%M%SZ).zip
docker compose exec -T notarium backup verify < notarium-20260731.zip
```

La vérification doit faire partie de la tâche régulière, et non d'un geste ponctuel : elle ne modifie rien et détecte la corruption avant le jour où l'archive vous sera nécessaire. Pour la tâche elle-même, une simple redirection ne suffit pas — reprenez la séquence de publication sûre (fichier temporaire → synchronisation sur disque → lien physique atomique) décrite dans le runbook : [Sauvegarde et restauration](/docs/self-hosting/backup/). Cette page couvre également la restauration dans un volume vierge et les limites d'applicabilité de la commande.

> [!danger] Ne copiez pas un `meta.db` à chaud
> `cp /data/meta.db`, ou la copie du volume pendant que le service tourne, n'est pas une sauvegarde : la base de métadonnées fonctionne en mode WAL, des lignes déjà validées peuvent encore se trouver dans `meta.db-wal`, et des fichiers copiés un à un ne forment pas un instantané pris à un même instant.

Ce qui entre dans la sauvegarde, et pourquoi :

| Quoi | Rôle |
|---|---|
| `/data/spaces` | Vos fichiers Markdown — la source de vérité. |
| `/data/meta.db` | La base de métadonnées (historique, utilisateurs, accès) — **irrécupérable** à partir des fichiers. |
| `/data/jobs` | Les artefacts et les téléversements des tâches d'import/export. |
| `/data/engine` | Les index dérivés du moteur. Absents de l'archive : ils se reconstruisent à partir des fichiers. |

Si la base de métadonnées a été déplacée vers Postgres, ou si les notes résident hors de la racine des données, la commande intégrée s'arrête sur une erreur plutôt que de produire une archive partielle — sauvegardez alors la base et les répertoires montés avec les outils standard de votre fournisseur. Pour savoir précisément ce que contient la base de métadonnées, voir la page [Base de données](/docs/self-hosting/database/).
