Passer au contenu principal Passer à la navigation Passer au pied de page
Offre limitée : Design Partner Program. Plan BUSINESS gratuit à vie.

Dépôts

Créez, gérez et opérez des dépôts chiffrés LUKS sur des machines distantes.

Dépôts

Un dépôt est une image disque chiffrée LUKS sur un serveur distant. Quand elle est montée, elle fournit :

  • Un système de fichiers isolé pour les données de votre application
  • Un démon Docker dédié (séparé du Docker de l’hôte)
  • Des adresses IP loopback uniques pour chaque service dans un sous-réseau /26

Créer un dépôt

rdc repo create --name my-app -m server-1 --size 10G
OptionObligatoireDescription
-m, --machine <name>OuiMachine cible où le dépôt sera créé
--size <size>OuiTaille de l’image disque chiffrée (par ex. 5G, 10G, 50G)
--skip-router-restartNonIgnorer le redémarrage du serveur de routage après l’opération

La sortie affichera trois valeurs générées automatiquement :

  • GUID du dépôt - Un UUID qui identifie l’image disque chiffrée sur le serveur.
  • Credential - Une phrase de passe aléatoire utilisée pour chiffrer/déchiffrer le volume LUKS.
  • ID réseau - Un entier (commençant à 2816, incrémentant de 64) qui détermine le sous-réseau IP pour les services de ce dépôt.

Stockez le credential de manière sécurisée. C’est la clé de chiffrement de votre dépôt. S’il est perdu, les données ne peuvent pas être récupérées. Le credential est stocké dans votre config.json local mais n’est pas stocké sur le serveur.

Monter et démonter

Le montage déchiffre et rend le système de fichiers du dépôt accessible. Le démontage ferme le volume chiffré.

rdc repo mount --name my-app -m server-1  # Déchiffrer et monter
rdc repo unmount --name my-app -m server-1  # Démonter et re-chiffrer
OptionDescription
--checkpointCréer un point de contrôle CRIU avant le montage/démontage (pour les conteneurs avec le label rediacc.checkpoint=true)
--skip-router-restartIgnorer le redémarrage du serveur de routage après l’opération

Vérifier le statut

rdc repo status --name my-app -m server-1

Lister les dépôts

rdc repo list -m server-1

Colonne Type et miroir d’état

La table de sortie inclut une colonne Type avec trois valeurs :

  • grand. Un dépôt de niveau supérieur enregistré dans votre configuration CLI locale sans parent. Le cas de base.
  • fork. Un fork copy-on-write d’un autre dépôt. Identifié soit via grandGuid dans la configuration locale soit via le miroir .interim/state de renet sur la machine. L’une ou l’autre source est autoritaire ; les deux doivent être en accord une fois le miroir rempli.
  • unknown. Aucun signal ne peut classifier le dépôt. Le plus souvent un fork legacy pré-miroir (créé avant le code du miroir et jamais remonté depuis), ou un grand obsolète dont l’entrée de configuration locale a été supprimée par erreur. Le CLI refuse de deviner ; l’opérateur doit exécuter le remplissage du miroir ou supprimer le répertoire s’il est réellement orphelin.

Le miroir .interim/state/<guid>/.rediacc.json est un petit fichier annexe écrit en dehors du volume chiffré LUKS, de sorte que les outils de sauvegarde et repo list peuvent lire la lignée des forks sans déverrouiller chaque image. Il a la même structure que le .rediacc.json dans le volume (is_fork, grand_guid, name, etc.) et est actualisé à chaque Repository.SaveState. C’est-à-dire à chaque montage et à chaque mutation d’état. C’est la source de vérité pour la détection de forks dans les sauvegardes planifiées : un fork non monté avec un miroir qui dit is_fork: true est correctement ignoré des uploads cold et hot.

Pour le nettoyage régulier des entrées unknown, voir rdc machine prune --prune-unknown.

Redimensionner

Définir le dépôt à une taille exacte ou l’agrandir d’une quantité donnée :

rdc repo resize --name my-app -m server-1 --size 20G  # Définir à une taille exacte
rdc repo expand --name my-app -m server-1 --size 5G  # Ajouter 5G à la taille actuelle

Le dépôt doit être démonté avant le redimensionnement. repo expand fonctionne en ligne. Le redimensionnement modifie la taille maximale du dépôt ; pour restituer les blocs libérés au pool sans changer le maximum, utilisez repo trim à la place.

Récupérer de l’espace (trim)

Supprimer des fichiers dans un dépôt libère de l’espace pour ce dépôt, et repo trim restitue ces blocs libérés au pool du datastore partagé. Il s’exécute en ligne sans aucune interruption de service :

rdc repo trim -m server-1                       # Trim every mounted repository plus the datastore
rdc repo trim -m server-1 --name my-app          # Trim one repository
rdc repo trim -m server-1 --report-only          # Show reclaimable space without trimming
rdc repo trim -m server-1 --docker               # Also clear stopped containers, dangling images, and build cache first

Fonctionnement : les images de dépôt sont des fichiers épars, et le volume chiffré propage les discards. Un trim ordonne au système de fichiers à l’intérieur du dépôt de libérer chaque bloc inutilisé, ce qui perce des trous dans l’image de support et réduit immédiatement l’utilisation du pool.

Remarques :

  • Le trim du système de fichiers est ignoré et signalé pour les dépôts sous une sauvegarde active, car le snapshot de sauvegarde référence encore les blocs et percer des trous ne libérerait pas d’espace dans le pool. La récupération --docker n’est pas concernée et s’exécute quand même (voir ci-dessous).
  • Exécuter trim deux fois de suite renvoie 0 octet la deuxième fois. Le système de fichiers mémorise les groupes de blocs déjà trimés ; ce comportement est attendu, pas un échec.
  • --docker ne supprime jamais les images étiquetées, seulement les images sans référence, les conteneurs arrêtés et le cache de build. Ajoutez --docker-volumes pour supprimer aussi les volumes inutilisés (cela efface des données ; CLI uniquement). Contrairement au trim du système de fichiers, la récupération --docker s’exécute même pendant une sauvegarde en cours, ce qui permet de vider un cache de build bloqué sans attendre la fin de la fenêtre de sauvegarde.

Politique de taille automatique

Plutôt que de redimensionner manuellement, laissez la machine gérer les tailles des dépôts. Une politique active la croissance automatique en ligne (la taille maximale du dépôt augmente quand il se remplit) et les trims planifiés. La machine applique les politiques toutes les quelques minutes via le timer systemd rediacc-storage-maintain.

# Machine-wide default: trim every repository daily
rdc repo policy set -m server-1 --auto-trim true

# Per-repository: grow my-app automatically, up to a hard ceiling
rdc repo policy set -m server-1 --name my-app --auto-grow true --max-quota 50G

# Inspect the stored and effective policy
rdc repo policy get -m server-1 --name my-app

Champs de la politique :

ChampSignificationDéfaut
--auto-growAgrandit le dépôt en ligne quand son système de fichiers dépasse le seuiloff
--max-quotaPlafond dur pour la croissance automatique. Obligatoire : le définir est votre consentement explicite au sur-provisionnement du poolnone
--grow-thresholdPourcentage d’utilisation du système de fichiers qui déclenche une croissance85
--grow-stepQuantité ajoutée par croissance : absolue (10G) ou pourcentage de la taille actuelle (20%)20%
--auto-trimExécuter des trims planifiésoff
--trim-intervalNombre minimal d’heures entre deux trims automatiques24

Garde-fous : la croissance automatique est refusée quand l’espace libre du pool est inférieur à une réserve (10 Go ou 5 % du pool, selon le plus grand des deux), attend au moins 30 minutes entre deux croissances du même dépôt, et ne dépasse jamais --max-quota. Il n’existe pas de réduction automatique : diminuer la taille maximale d’un dépôt reste une opération manuelle, hors ligne via repo resize.

Les paramètres par dépôt remplacent la valeur par défaut à l’échelle de la machine. Les appels successifs à policy set ne modifient que les flags que vous passez.

Fork

Créer une copie d’un dépôt existant à son état actuel :

rdc repo fork --parent my-app --tag staging -m server-1

Les forks utilisent le modèle name:tag : le fork résultant est nommé my-app:staging. Cela crée une nouvelle copie chiffrée avec son propre GUID et ID réseau, tout en partageant le nom du parent. Le fork partage le même credential LUKS que le parent.

Les forks partagent les données du parent via reflink BTRFS, y compris tous les credentials stockés sur le disque. Voir Ce que Rediacc n’isole pas pour les implications quand ces credentials autorisent des services externes comme Stripe, AWS ou Railway. Pour garder les credentials de déploiement hors de la portée du fork, utilisez les secrets par dépôt plutôt que d’intégrer les valeurs dans les fichiers .env du dépôt.

À la création du fork, repo fork écrit le fichier annexe du miroir d’état à <datastore>/.interim/state/<fork-guid>/.rediacc.json immédiatement. Sans déverrouiller le volume. De sorte que le nouveau fork est correctement identifié comme is_fork: true dès le moment de sa création. Cela permet aux sauvegardes planifiées de l’ignorer (les forks sont exclus du pipeline d’upload par défaut) même s’il n’est jamais monté. Lors du fork d’un fork, grand_guid s’enchaîne correctement : le miroir du nouveau fork pointe vers le GUID du grand-parent original, pas vers le fork intermédiaire.

Forker et démarrer en une seule opération

--up enchaîne le fork, le montage et le démarrage des services en une unique opération distante. Ajoutez --detach pour récupérer la main dès que les conteneurs sont lancés ; les vérifications de santé se terminent en arrière-plan, et le proxy réessaie jusqu’à ce que chaque service soit prêt à répondre :

rdc repo fork --parent my-app --tag staging -m server-1 --up
rdc repo fork --parent my-app --tag scratch -m server-1 --up --detach

Lors de nos tests, un dépôt de 128 Go a forké et atteint des services en cours d’exécution en environ 57 secondes, et environ 31 secondes avec --detach. Le mode détaché affiche une indication pour suivre la progression : rdc machine query --containers --name <machine>.

Répartition du temps d’exécution

Les opérations de plus de quelques secondes se terminent par un récapitulatif de chronométrage : un découpage étape par étape, un graphique en cascade montrant ce qui s’est exécuté en parallèle, et une ligne d’attribution séparant le pipeline Rediacc du démarrage propre à vos services :

  Rediacc pipeline 19.2s (61%) · service startup 12.3s (39%)

Le démarrage des services correspond à la phase de boot de vos conteneurs (images, init, vérifications de santé, tels que définis par le Rediaccfile du dépôt ) et varie donc selon l’application. Les graphiques s’affichent sur les terminaux interactifs ; définissez RDC_TIMING_CHART=1 pour les forcer dans une sortie redirigée.

Gestion de versions à la manière de git

Les forks peuvent jouer le rôle de commits git. rdc repo commit gèle un fork de travail en un commit immuable et stable en octets ; rdc repo branch nomme une ligne d’historique ; rdc repo checkout clone par reflink un commit dans un nouveau fork de travail modifiable ; rdc repo log parcourt la chaîne de parents ; et rdc repo merge combine deux lignes sans muter un dépôt actif en place. rdc repo fork --immutable produit en une seule étape une base équivalente à un commit.

rdc repo commit --name my-app:work --message "schéma migré" -m server-1
rdc repo branch --branch staging --name my-app:work
rdc repo checkout --ref staging --from my-app:work --tag staging-copy -m server-1

Voir la référence du branchement à la manière de git pour l’ensemble des commandes, les options et les exemples travaillés.

Secrets

Les secrets par dépôt sont des credentials de déploiement injectés dans les conteneurs sans être écrits dans l’image du dépôt chiffré. Ils sont conservés sur un plan séparé des données du dépôt, de sorte que rdc repo fork ne les propage pas. Un fork commence avec une map de secrets vide et ses conteneurs démarrent en s’identifiant comme un principal externe différent du parent.

Vous voulez une procédure pas à pas ? Consultez le tutoriel de gestion des secrets pour le cycle complet set/list/deploy/verify/rotate.

Modèle d’écriture seule (style GitHub) : get retourne uniquement le digest SHA-256. La valeur en texte brut n’est jamais retournée à personne, humain ou agent. Si vous oubliez quelle est une valeur, cherchez-la dans votre gestionnaire de mots de passe et effectuez une rotation ; vous ne pouvez pas la relire depuis Rediacc par conception. Cela élimine toute une classe de fuite : enregistrements de terminal, historique shell, redirection accidentelle, coup d’oeil.

Deux modes de livraison :

  • env. Le secret est exporté comme REDIACC_SECRET_<KEY> dans le shell renet sur la machine cible. Référencez-le depuis votre docker-compose.yml via l’interpolation ${REDIACC_SECRET_<KEY>}. Visible à l’intérieur de l’environnement du conteneur, utilisez ceci pour les valeurs en forme de chaîne de connexion que l’application attend déjà dans env.
  • file. Le secret est écrit à /var/run/rediacc/secrets/<networkID>/<KEY> sur l’hôte (tmpfs, jamais persisté). Référencez-le depuis votre fichier compose via une déclaration secrets: de haut niveau avec source file:, plus une liste secrets: par service. Les conteneurs lisent depuis /run/secrets/<key>. Préférez ce mode pour tout ce qui est sensible. Il n’apparaît jamais dans docker inspect ou /proc/<pid>/environ.
# Définir, lister, obtenir (digest uniquement), supprimer
rdc repo secret set --name my-app --key STRIPE_LIVE_KEY --value sk_live_xxx --mode file --current ""
rdc repo secret set --name my-app --key DB_HOST         --value postgres.internal --mode env --current ""
rdc repo secret list --name my-app
rdc repo secret get  --name my-app --key DB_HOST    # → { key, mode, digest } (pas de valeur)
rdc repo secret unset --name my-app --key STRIPE_LIVE_KEY --current sk_live_xxx

Portail de mutation symétrique. Les humains et les agents ont besoin de --current <previous-value> pour écraser ou supprimer un secret (condition préalable de type passwd). Pour la première écriture d’une nouvelle clé, passez --current "" (vide). Pour effectuer une rotation sans vérifier la valeur antérieure, passez --rotate-secret à la place. Ceci est fortement audité comme une rotation. --current et --rotate-secret s’excluent mutuellement.

Passez --value - pour lire depuis stdin au lieu de argv (évite l’exposition de l’historique shell pour les écritures uniques).

Dans votre docker-compose.yml :

services:
  api:
    image: myapp
    environment:
      DATABASE_HOST: ${REDIACC_SECRET_DB_HOST}
    secrets:
      - stripe_live_key

secrets:
  stripe_live_key:
    file: /var/run/rediacc/secrets/${REDIACC_NETWORK_ID}/STRIPE_LIVE_KEY

La référence côté service en minuscules (stripe_live_key) est le nom de fichier /run/secrets/<name> dans le conteneur ; la fin en majuscules du chemin hôte (STRIPE_LIVE_KEY) correspond à ce que vous définissez avec --key. ${REDIACC_NETWORK_ID} est interpolé automatiquement par renet compose.

Isolation cross-repo appliquée : le validateur compose de renet rejette les chemins secrets: file: (et configs: file:, et env_file:) qui référencent l’ID réseau d’un autre dépôt. Le token littéral ${REDIACC_NETWORK_ID} (ou l’entier de votre réseau) est la seule forme acceptée pour les références /var/run/rediacc/secrets/.... Et --unsafe ne remplace PAS ce contrôle. Le bac à sable Landlock autour du sous-processus bash Rediaccfile limite également l’accès au système de fichiers uniquement à votre répertoire de secrets du réseau, de sorte qu’une cat /var/run/rediacc/secrets/<other>/X malveillante depuis un Rediaccfile échoue avec EACCES au niveau du noyau.

Forks : rdc repo fork ne copie pas les secrets. Pour utiliser les secrets dans un fork, exécutez rdc repo secret set --name <fork> sur le fork explicitement. C’est la propriété de sécurité essentielle. Les conteneurs du fork ne doivent pas pouvoir agir comme le principal de production envers les services externes.

Agents (Claude Code, Cursor, etc.) : repo secret list et repo secret get sont exposés comme outils MCP (lecture-sûr. Noms + digests uniquement, jamais de valeurs). set et unset sont CLI-only car la cérémonie --current/--rotate-secret nécessite une surveillance humaine ; les agents les appelant via shell obtiennent le même portail que les humains. Quand la condition préalable échoue, l’enveloppe JSON contient un champ structuré errors[].next.options[].run. Les agents doivent relayer ces commandes verbatim à l’utilisateur. Voir sécurité des agents AI pour le modèle complet.

Valider

Vérifier l’intégrité du système de fichiers d’un dépôt :

rdc repo validate --name my-app -m server-1

Propriété

Définir la propriété des fichiers dans un dépôt à l’utilisateur universel (UID 7111). Ceci est généralement nécessaire après avoir téléchargé des fichiers depuis votre station de travail, qui arrivent avec votre UID local.

rdc repo ownership --name my-app -m server-1

La commande détecte automatiquement les répertoires de données des conteneurs Docker (montages bind inscriptibles) et les exclut. Cela évite de casser les conteneurs qui gèrent les fichiers avec leurs propres UIDs (par ex. MariaDB=999, www-data=33).

OptionDescription
--uid <uid>Définir un UID personnalisé au lieu de 7111
--skip-router-restartIgnorer le redémarrage du serveur de routage après l’opération

Pour forcer la propriété sur tous les fichiers, y compris les données du conteneur :

rdc repo ownership --name my-app -m server-1

Consultez le Guide de migration pour une procédure complète de quand et comment utiliser la propriété lors de la migration de projet.

Modèle

Appliquer un modèle pour initialiser un dépôt avec des fichiers :

rdc repo template apply --name my-template -m server-1 -r my-app --file ./my-template.tar.gz

Supprimer

Détruire de manière permanente un dépôt et toutes les données qu’il contient :

rdc repo delete --name my-app -m server-1

Cela détruit définitivement l’image disque chiffrée. Cette action ne peut pas être annulée.

Migrer un dépôt

Migrer en direct un dépôt d’une machine à une autre. Le seul temps d’arrêt est la phase de synchronisation delta finale : généralement quelques secondes à quelques minutes selon le taux d’écriture au moment du basculement.

rdc repo migrate --name my-app --from server-1 --to server-2
OptionDescription
--provisionProvisionner le dépôt sur la machine cible avant la migration (crée l’image LUKS et enregistre la config)
--checkpointCréer un point de contrôle CRIU des conteneurs en cours d’exécution avant le basculement
--bwlimit <kbps>Limiter la bande passante rsync en kilooctets par seconde
--skip-dnsIgnorer la mise à jour des enregistrements DNS après le basculement

Flux en trois phases :

  1. Pré-copie en direct - rsync transfère les données tandis que le dépôt reste en cours d’exécution sur la source. Les fichiers volumineux sont transférés avant tout temps d’arrêt.
  2. Basculement - le dépôt est arrêté sur la source, une dernière passe rsync synchronise les modifications restantes, et le dépôt démarre sur la cible.
  3. Démarrer sur la cible - renet monte et démarre le dépôt sur la machine cible. Le DNS est mis à jour sauf si --skip-dns est passé.

Repository Live Migration

Push vs migrate :

repo pushrepo migrate
OpérationCopierDéplacer
Source aprèsInchangéeArrêtée
Temps d’arrêtAucun (copie uniquement)Fenêtre de basculement brève
Mise à jour DNSNonOui (sauf --skip-dns)
Cas d’utilisationSauvegarde, clone de stagingRemplacement de machine, déplacement de serveur

Élaguer

Après suppression de dépôts ou récupération d’opérations échouées, des répertoires de montage orphelins, des fichiers de verrouillage et des marqueurs immobiles peuvent rester. L’élagage les supprime de manière sûre :

# Aperçu de ce qui serait supprimé
rdc machine prune --name server-1 --dry-run

# Supprimer les ressources orphelines
rdc machine prune --name server-1

Seules les ressources sans image de dépôt correspondante sont affectées. Les répertoires de montage non vides ne sont jamais supprimés.