Article de la série « Mon ordinateur Ubuntu » Actions et articles créés avec l’aide de Claude.ai et 100% testé et ajusté par moi.
Home Assistant est une plateforme domotique open source puissante. Il en existe plusieurs variantes d’installation. Cet article explique comment installer la variante « Container » sur un ordinateur Ubuntu qui fait déjà tourner d’autres services Docker, avec un accès sécurisé depuis l’extérieur via Nginx Proxy Manager.
Quelle variante de Home Assistant choisir ?
Il existe trois grandes variantes :
HA OS – remplace complètement l’OS de la machine. À réserver à un appareil dédié (Raspberry Pi par exemple).
HA Supervised – donne accès au magasin d’add-ons officiel, mais officiellement supporté sur Debian uniquement. Risques de friction sur Ubuntu.
HA Container – s’installe comme n’importe quel container Docker. Pas d’accès au magasin d’add-ons natif, mais les add-ons les plus courants ont un équivalent en container Docker séparé. C’est la solution la plus cohérente si tu as déjà un PC Ubuntu avec Docker et Portainer.
C’est cohérent avec l’organisation décrite dans Docker et Portainer : regrouper les données. Toutes les données de HA seront dans ce dossier, et donc automatiquement couvertes par ta sauvegarde rclone.
Étape 2 – Déployer la stack dans Portainer
Connecte-toi à Portainer (https://TON-IP:9443), clique sur ton environnement « local », puis « Stacks » dans le menu gauche. Clique sur « + Add stack » et donne-lui le nom home-assistant.
network_mode: host – HA utilise directement le réseau du PC, sans isolation. C’est recommandé par le projet HA pour la découverte automatique des appareils sur le réseau local.
privileged: true – nécessaire pour accéder au matériel (Bluetooth, USB, etc.).
/run/dbus:/run/dbus:ro – permet à HA de communiquer avec les services système, utile pour Bluetooth notamment.
Le volume letsencrypt n’est pas nécessaire ici – c’est Nginx Proxy Manager qui gère les certificats SSL.
Clique sur « Deploy the stack ». Au bout de quelques secondes, HA est accessible sur ton réseau local via http://TON-IP:8123.
Étape 3 – Accès externe via Nginx Proxy Manager
Ouvrir le port 8123
Dans l’interface de gestion de ton routeur, ajoute une règle de redirection de port :
Port externe : 8123
IP locale de destination : l’IP fixe de ton PC Linux
Port interne : 8123
Protocole : TCP
Créer le proxy host dans NPM
Connecte-toi à NPM (http://TON-IP:81), va dans « Proxy Hosts » et clique sur « Add Proxy Host ».
Onglet « Details » :
Domain Names : ha.TON-DOMAINE.com
Scheme : http
Forward Name/IP : 127.0.0.1
Forward Port : 8123
Coche « Block Common Exploits » et « Websockets Support »
Onglet « SSL » :
SSL Certificate : « Request a new SSL Certificate »
Coche « Force SSL », « HTTP/2 Support » et « HSTS Enabled »
Clique sur « Save ».
Le point spécifique à Home Assistant – configuration.yaml
Contrairement aux autres containers, HA intègre une protection contre les accès via proxy non déclarés. Sans configuration supplémentaire, tu obtiendras une erreur 400 (Bad Request) en accédant via https://ha.TON-DOMAINE.com.
Il faut déclarer NPM comme proxy de confiance. Ouvre le fichier de configuration :
Attention à l’indentation : 2 espaces par niveau, pas de tabulations. YAML est strict là-dessus.
Redémarre le container HA dans Portainer. HA est maintenant accessible depuis l’extérieur via https://ha.TON-DOMAINE.com.
Étape 4 – Premier démarrage et assistant de configuration
Au premier accès, HA t’ouvre automatiquement l’assistant de démarrage. Tu y crées ton compte administrateur, choisis la langue, le fuseau horaire et la localisation.
Bonne surprise : HA scanne ton réseau local et détecte automatiquement les appareils compatibles. Sur mon réseau il a trouvé Bluetooth, Google Cast, Frontier Silicon, Matter, Tado, Thread et UPnP – sans aucune configuration de ma part. La connexion effective de ces appareils est une étape ultérieure, mais la détection automatique donne un bon aperçu du potentiel.
Étape 5 – Sauvegardes
Si tu as déjà mis en place la sauvegarde automatique avec rclone décrite dans Sauvegarder ses containers Docker automatiquement avec Rclone, il n’y a rien à faire de plus. Le dossier /home/USER/docker/home-assistant/ est automatiquement inclus dans la sauvegarde quotidienne.
Une vulnérabilité Copy Fail a été découverte fin avril 2026. Elle concerne beaucoup d’ordinateurs sous linux.
Pour savoir si la vulnérabilité existe sur votre ordinateur : taper les commandes indiquées à la fin de cet article, dans le chapitre sur la vérification.
mettre à jour mon ordinateur linux
J’ai suivi les instructions de cet excellent site.
On peut aussi vérifier ensuite que tout a bien fonctionné :
lsmod | grep algif_aead
Rien ne devrait s’afficher en principe. Si rien ne s’affiche ça signifie que le module vulnérable ne se charge pas. C’est bien ce que l’on veut.
Ultime vérification : Pour Ubuntu 24.04 (Noble Numbat), tu devrais avoir une version égale ou supérieure à la 6.8.0-31 (ou une version spécifique 6.14 si tu es sur un kernel HWE). C’est ce que me dit Gemini le 11 mai.
uname -r
La réponse est « 6.17.0-23-generic ». Tout va bien donc.
Une image explicative de la faille
Image créée par Gemini
L’image est conçue comme une infographie technique simplifiée, divisée en deux parties distinctes pour expliquer le fonctionnement et les risques de la vulnérabilité CVE-2026-31431 :
La zone « VULNERABILITY » (à gauche) : Un utilisateur avec des privilèges normaux lance une commande de copie de fichier. Cette action, normalement anodine, déclenche une erreur dans le noyau Linux. Cette erreur est symbolisée par des fragments de code brisés et une « fuite » d’informations qui contourne les sécurités habituelles.
La zone « RISK » (à droite) : Un attaquant exploite cette corruption de mémoire pour contourner les protections. Un pictogramme montre un cadenas qui se brise, menant à une icône de l’utilisateur « Root » (super-utilisateur) symbolisé par une clé et une couronne, indiquant une prise de contrôle totale du système.
L’interface Nginx : En haut de l’image, une interface graphique simplifiée de Nginx agit comme une barrière externe. Elle souligne le point que nous avons abordé : le danger survient lorsqu’une application exposée sur le web (via Nginx) est piratée et sert de point d’entrée pour lancer l’exploit « Copy Fail ».
J’utilise Obsidian depuis peu pour stocker mes notes personnelles et professionnelles. L’objectif était simple : avoir mes notes accessibles sur mon PC Windows, mon téléphone Android et mon ordinateur Linux, sans payer d’abonnement. Voici comment j’ai mis ça en place, les obstacles rencontrés et les décisions prises.
Obsidian est un outil de prise de notes basé sur des fichiers markdown (.md) stockés localement sur votre machine. Pas de cloud propriétaire, pas d’abonnement obligatoire pour les fonctions de base – mes notes m’appartiennent et restent dans un dossier normal de mon ordinateur.
Mon usage principal : stocker des notes diverses au fil des jours, faire de la veille en conservant des liens commentés, et disposer d’une base de notes accessible depuis n’importe lequel de mes appareils.
Ce que je ne cherchais pas : un système complexe avec des dizaines de plugins. La règle que je me suis fixée – n’ajouter de la structure que si un vrai besoin se manifeste.
Ce qu’il faut avant de commencer
Un compte Dropbox (il peut être gratuit, 2 Go suffisent largement pour des notes texte)
Dropbox Desktop installé sur le PC Windows
Dropbox installé sur le PC linux (ce n’était pas mon cas, la synchronisation ne se fait pas)
Environ 30 minutes pour l’ensemble de l’installation
Étape 1 – Installation Windows et création du vault dans Dropbox
Au premier lancement, Obsidian propose de créer un vault (coffre). C’est le dossier qui contiendra toutes vos notes. Point crucial : place ce vault directement dans ton dossier Dropbox local.
Sur mon installation, le vault se trouve dans D:\Dropbox\OBSIDIAN\obsidian-vault.
Vérifie ensuite que Dropbox synchronise bien le dossier – l’icône Dropbox dans la barre des tâches doit indiquer une synchronisation en cours puis un statut « à jour ».
Étape 2 – Plugin Remotely Save – configuration et authentification Dropbox
Remotely Save est le plugin qui va gérer la synchronisation entre tes appareils via Dropbox. Il est gratuit pour Dropbox (attention : Google Drive est une fonctionnalité payante dans ce plugin).
Pour l’installer :
Paramètres > Modules complémentaires > activer les plugins communautaires
Dans les réglages du plugin : choisir Dropbox comme service
Cliquer sur Authentifier et autoriser l’accès à votre compte Dropbox
Tester une première synchronisation manuelle avec l’icône de synchronisation en bas à gauche
Le vault se retrouve alors dans un dossier OBSIDIAN dans ta Dropbox. On peut vérifier directement sur dropbox.com.
Étape 3 – Installation Android et première synchronisation
Installe Obsidian depuis le Play Store.
Au premier lancement, crée un vault avec le même nom que sur Windows. Pour le stockage, choisis « Stockage de l’application ».
Installe ensuite Remotely Save depuis les modules complémentaires (même procédure que sur Windows), configure Dropbox, authentifie-toi.
Lance une première synchronisation manuelle – toutes les notes créées sur Windows apparaissent sur le téléphone, et inversement.
Étape 4 – Installation Linux – cas particulier et limites
Sur Ubuntu, Obsidian est disponible directement dans l’App Center. Installation en un clic, aucune ligne de commande nécessaire.
La synchronisation est plus complexe sur Linux car Dropbox Desktop n’est pas installé sur ma machine. J’ai installé Remotely Save et configuré Dropbox, mais sans Dropbox Desktop local, le vault Linux reste isolé des autres appareils.
Ma décision : ne pas installer Dropbox sur Linux pour l’instant, car mon usage Linux d’Obsidian est incertain. Si le besoin se confirme, j’installerai Dropbox Desktop Linux.
Ce que j’ai appris en passant : les installations en container (Docker) n’ont pas de sens pour une application graphique comme Obsidian. Docker est fait pour des services auxquels on accède à distance, pas pour des interfaces utilisateur.
Étape 5 – Synchronisation automatique – les réglages essentiels
Par défaut, Remotely Save ne synchronise que manuellement. Pour automatiser, voici les réglages à faire sur chaque appareil séparément :
L’icône calendrier dans la barre latérale gauche ouvre la note du jour en un clic. tu y notes ce que tu veux sans te poser de questions d’organisation.
Pour la veille, deux approches simples :
Coller les URLs directement dans la note quotidienne avec un mot de contexte
Créer une note dédiée par thème (exemple : « Veille IA ») pour les liens que vous voulez retrouver facilement
Mon conseil : résiste à la tentation dde structurer avant d’avoir des notes à organiser. Obsidian peut devenir très complexe très vite – commence simple.
Ce que j’ai retenu de cette installation
Remotely Save + Dropbox est la combinaison gratuite et fiable pour synchroniser Obsidian sur plusieurs appareils. Google Drive aurait été plus naturel pour moi mais c’est une fonctionnalité payante dans ce plugin.
Le vault placé directement dans Dropbox sur Windows fonctionne sans friction. Sur Android, le plugin Remotely Save fait tout le travail. Sur Linux, la synchronisation nécessite Dropbox Desktop – à installer si l’usage se confirme.
La synchronisation automatique toutes les 5 minutes est un bon équilibre entre réactivité et consommation batterie sur mobile.
Cet article fait partie de ma démarche de capitalisation des compétences acquises. Si tu as des questions ou des retours sur cette installation, les commentaires sont ouverts.
La sauvegarde automatique mise en place dans l’article précédent ne vaut que si on sait s’en servir le jour où on en a besoin. Cet article décrit la procédure complète de restauration d’un container Docker depuis une sauvegarde Google Drive – testée sur Stirling PDF, Nginx Proxy Manager et Portainer.
Avant de commencer : vérifie que tu as bien une sauvegarde récente dans Google Drive. La commande suivante liste les dates disponibles :
Note la date de la sauvegarde que tu veux restaurer – tu en auras besoin à l’étape 4.
Vue d’ensemble de la procédure
Noter l’état actuel du container (point de comparaison)
Arrêter et supprimer le container
Renommer le dossier local (précaution de sécurité)
Restaurer les fichiers depuis Google Drive
Relancer le container
Vérifier que tout fonctionne
Nota : dans tout ce qui suit, tu remplaceras USER par ton nom d’utilisateur linux.
Procédure standard (Stirling PDF et containers similaires)
Étape 1 – Noter l’état actuel
Avant de toucher quoi que ce soit, note les éléments qui te permettront de vérifier que la restauration a bien fonctionné :
les réglages personnalisés du logiciel (utilisateurs, mots de passe, configuration)
les favoris, l’historique, tout ce qui est propre à ton usage
Vérifie l’empreinte des fichiers locaux actuels :
ls -la /home/USER/docker/nom-du-logiciel/
pour chaque sous-dossier :
ls -la /home/USER/docker/nom-du-logiciel/sous-dossier/
Vérifie aussi, pour chaque sous-dossier également, que la sauvegarde Drive contient bien les fichiers critiques et que leurs tailles correspondent :
sudo rclone --config /home/USER/.config/rclone/rclone.conf ls "gdrive:/daily/YYYY-MM-DD/nom-du-logiciel/sous-dossier/"
Les tailles en octets doivent correspondre à celles des fichiers locaux. Ce qui importe c’est que les fichiers principaux (base de données, configuration) soient de taille identique – pas besoin de vérifier les logs. Si c’est le cas, tu peux continuer en confiance.
Étape 2 – Arrêter et supprimer le container dans Portainer
Si tu restaure Portainer, va voir le cas particulier plus bas.
Depuis ton navigateur, ouvre Portainer :
Va dans Stacks dans le menu de gauche
Clique sur la stack du logiciel à restaurer
Clique sur Stop puis sur Delete this stack
Confirme la suppression
Le logiciel n’est plus accessible. C’est normal, on va le reconstruire depuis la sauvegarde.
Étape 3 – Renommer le dossier local (précaution)
Plutôt que de supprimer définitivement le dossier local, on le renomme. Si quelque chose se passe mal pendant la restauration, on peut revenir en arrière immédiatement.
NPM contient des données critiques : tes certificats Let’s Encrypt et ta configuration de proxy. La procédure standard s’applique, avec deux différences importantes.
Différence 1 – commande de restauration
Les certificats Let’s Encrypt dans letsencrypt/live/ sont des liens symboliques (symlinks) qui pointent vers les vrais fichiers dans letsencrypt/archive/. Sans l’option --copy-links, rclone refuse de les copier et la restauration échoue au démarrage avec l’erreur cannot load certificate.
La commande de restauration doit donc inclure --copy-links :
que tes proxy hosts sont bien présents dans l’interface NPM
que le cadenas vert s’affiche sur pdf.DOMAINE.com (certificat SSL actif)
Si les certificats ont expiré pendant une longue interruption, NPM les renouvellera automatiquement au redémarrage.
Cas particulier – Portainer
Portainer est un cas spécial car il s’auto-gère. On ne peut pas le restaurer depuis son propre interface puisqu’il sera arrêté pendant la procédure. Toute la restauration se fait en ligne de commande.
1 – Noter l’état actuel
ls -la /home/USER/docker/portainer/
ls -la /home/USER/docker/portainer/data/
Vérifie que la sauvegarde contient bien les fichiers critiques :
sudo rclone --config /home/USER/.config/rclone/rclone.conf ls "gdrive:/daily/YYYY-MM-DD/portainer/data/"
Tu dois voir portainer.db, portainer.key et portainer.pub avec des tailles cohérentes.
2 – Arrêter et supprimer Portainer en ligne de commande
5 – Redonner les droits root et relancer Portainer
Les fichiers dans portainer/data/ doivent appartenir à root – Portainer les gère en root et refuse de démarrer autrement. C’est une étape indispensable après restauration :
Ouvre Portainer dans ton navigateur (https://[IP-DU-BEELINK]:9443).
Si Portainer retrouve ton tableau de bord habituel sans te demander de créer un nouveau mot de passe, la restauration est réussie. Vérifie que tes stacks sont bien présentes dans l’onglet Stacks.
Nettoyage
rm -rf /home/USER/docker/portainer-BACKUP-TEST
En cas de problème
Le logiciel démarre mais ne retrouve pas les données Vérifie que les chemins dans le docker-compose.yml correspondent bien aux dossiers restaurés. Un chemin mal copié suffit à pointer vers un dossier vide.
« Can’t follow symlink without -L/–copy-links » Ce message apparaît lors de la restauration de NPM. Ajoute --copy-links à la commande rclone de restauration – voir la section NPM ci-dessus.
« Permission denied » au démarrage du container Les fichiers restaurés par Rclone appartiennent à USER, mais certains containers ont besoin que leurs dossiers appartiennent à root. C’est systématiquement le cas pour Portainer. Tape :
Portainer affiche « New Portainer installation » Les fichiers de données n’ont pas les bons droits après restauration. Arrête le container, refais sudo chown -R root:root /home/USER/docker/portainer/data, puis relance avec docker run.
Tu veux restaurer une version plus ancienne Remplace simplement YYYY-MM-DD par la date souhaitée dans la commande de l’étape 4. Les sauvegardes hebdomadaires sont dans gdrive:/weekly/YYYY-Wxx/ et les mensuelles dans gdrive:/monthly/YYYY-MM/.
Dans le prochain article
Maintenant que la sauvegarde et la restauration sont opérationnelles et testées, on verra comment installer un nouveau container en suivant dès le départ les bonnes pratiques – sans avoir à corriger la configuration après coup.
Pour information, je me suis aidée de Claude.ai pour réaliser ces actions et rédiger l’article.
Maintenant que tous les fichiers importants de mes containers Docker sont regroupés dans /home/USER/docker/, je peux mettre en place une sauvegarde automatique vers Google Drive. C’est l’objectif de cet article.
J’utilise Rclone, un outil en ligne de commande qui synchronise des dossiers locaux vers des dizaines de services cloud. Couplé à un script bash et au planificateur cron, il permet d’automatiser complètement les sauvegardes, sans intervention manuelle.
Mise à jour du 17/08/2026 : la méthode décrite dans cet article (copie fichier par fichier) peut saturer le quota de requêtes de l’API Google Drive si ton dossier à sauvegarder contient beaucoup de fichiers. Je te recommande de lire d’abord
le nouvel article
qui corrige ce problème avec une approche par archive compressée.
La stratégie de rétention Grand-Père / Père / Fils
Plutôt qu’une simple copie quotidienne qui s’écrase, j’ai mis en place une stratégie de rétention appelée Grand-Père / Père / Fils (GFF) :
les sauvegardes quotidiennes sont conservées 7 jours
une sauvegarde hebdomadaire est créée chaque dimanche et conservée 4 semaines
une sauvegarde mensuelle est créée le 1er de chaque mois et conservée 12 mois
une sauvegarde annuelle est créée le 1er janvier et conservée indéfiniment
Rclone ne gère pas cette logique nativement. C’est le script bash qui s’en charge.
Ce que tu auras dans Google Drive au bout de quelques semaines
La partie après /folders/ est l’ID du dossier. Copie-la et garde-la de côté.
En indiquant cet ID à Rclone, il ne verra que ce dossier et rien d’autre de ton Drive – c’est plus propre et plus sûr.
Étape 2 – Installer Rclone
Sur le Beelink, ouvre un terminal :
sudo apt install rclone
Vérifie l’installation :
rclone version
Tu dois voir quelque chose comme rclone v1.xx.x.
Étape 3 – Connecter Rclone à Google Drive
Lance la configuration interactive :
rclone config
Suis ces étapes dans le menu :
n → nouveau remote
Nom : gdrive
Type : drive → tape le numéro correspondant à "Google Drive"
client_id : → laisse vide, Entrée
client_secret : → laisse vide, Entrée
scope : 1 → accès complet à Drive
Edit advanced config : y → on répond oui pour pouvoir renseigner root_folder_id
laisser tout vide sauf :
root_folder_id : → colle ici l'ID copié à l'étape 1
laisser tout le reste vide, Entrée à chaque fois
Edit advanced config : n → la question est reposée, on répond non cette fois
Use auto config : y → ou n si tu es en SSH depuis Windows
Si tu travailles directement sur le Beelink (avec écran et clavier) :
Use auto config : y
Un navigateur s’ouvre – connecte-toi à Google et autorise Rclone.
Si tu travailles depuis ton PC Windows en SSH :
Use auto config : n
Rclone te donne une URL. Ouvre-la dans ton navigateur Windows, autorise l’accès, et colle le code retourné dans le terminal.
Si la commande retourne le contenu de ton dossier Drive (ou rien si le dossier est vide), la connexion est établie. Rclone ne voit que ce dossier – rien d’autre de ton Drive.
Étape 4 – Configurer sudo sans mot de passe pour Rclone
Portainer et Nginx Proxy Manager écrivent leurs fichiers en root à l’intérieur du container. Pour que Rclone puisse les lire, il doit s’exécuter avec sudo – y compris quand cron lance le script automatiquement la nuit, sans session interactive.
Note : selon ta configuration Ubuntu, cette étape peut ne pas être nécessaire. Si tu viens de taper ton mot de passe sudo, il est en cache pour quelques minutes. Pour être sûr que cron fonctionnera la nuit sans session ouverte, configure cette règle dans tous les cas.
sudo visudo
Ajoute cette ligne tout en bas :
USER ALL=(ALL) NOPASSWD: /usr/bin/rclone
Sauvegarde avec Ctrl+O puis quitte avec Ctrl+X.
Attention avec visudo : ne ferme jamais le fichier directement avec Ctrl+X sans avoir d’abord sauvegardé avec Ctrl+O. visudo valide la syntaxe avant d’enregistrer – une faute de frappe dans ce fichier pourrait te bloquer hors de sudo.
Étape 5 – Créer le token API Portainer
Le script de sauvegarde interroge l’API Portainer avant chaque sauvegarde pour exporter automatiquement le docker-compose.yml de chaque stack dans son dossier. Ainsi la sauvegarde contient toujours le YAML exact et à jour.
Pour cela il faut créer un token d’accès dans Portainer :
Ouvre Portainer dans ton navigateur
Clique sur ton nom d’utilisateur en haut à droite
Clique sur My account
Descends jusqu’à la section Access tokens
Clique sur Add access token
Donne-lui un nom : backup-script
Copie immédiatement le token affiché – il ne sera plus visible ensuite
Colle ce contenu (remplace USER par ton nom d’utilisateur Linux) :
#!/bin/bash
# ═══════════════════════════════════════════════════════════════
# backup-docker.sh — Sauvegarde Docker vers Google Drive
# Stratégie Grand-Père / Père / Fils (quotidien / hebdo / mensuel / annuel)
# v4 - export automatique des YAML depuis l'API Portainer
# --links pour les symlinks Let's Encrypt
# ═══════════════════════════════════════════════════════════════
# -- Configuration ────────────────────────────────────────────────
SOURCE="/home/ald/docker"
REMOTE="gdrive:"
LOG="/home/ald/rclone-logs/backup-docker.log" # hors /docker/ pour éviter de sauvegarder un fichier en cours d'écriture
RCLONE_CONF="/home/ald/.config/rclone/rclone.conf"
PORTAINER_URL="https://192.168.86.101:9443"
PORTAINER_TOKEN=$(cat /home/ald/docker/scripts/.portainer-token)
DATE=$(date +%Y-%m-%d)
DAY=$(date +%u) # 1=lundi ... 7=dimanche
DOM=$(date +%d) # jour du mois (01-31)
MONTH=$(date +%m) # mois (01-12)
# -- Création du dossier de log si nécessaire ─────────────────────
mkdir -p /home/ald/rclone-logs
# -- Fonction de log ──────────────────────────────────────────────
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG"
}
# -- Commande rclone de base ──────────────────────────────────────
# --exclude "*.db-shm" : exclut les fichiers temporaires SQLite WAL
# --exclude "*.db-wal" : idem - ces fichiers changent en permanence
# et sont inutiles pour une restauration
# --links : copie les liens symboliques comme de vrais fichiers
# indispensable pour les certificats Let's Encrypt de NPM
# Important : ne pas ajouter --log-level, incompatible avec --log-file
RCLONE="sudo rclone --config $RCLONE_CONF --log-file=$LOG --links --exclude *.db-shm --exclude *.db-wal"
log "=== Début sauvegarde ==="
# -- Export automatique des YAML depuis l'API Portainer ───────────
log "Export des YAML depuis Portainer..."
STACKS_JSON=$(curl -sk \
-H "X-API-Key: $PORTAINER_TOKEN" \
"$PORTAINER_URL/api/stacks")
if [ -z "$STACKS_JSON" ] || [ "$STACKS_JSON" = "null" ]; then
log "ERREUR : impossible de contacter l'API Portainer - les YAML ne seront pas mis à jour."
else
STACK_COUNT=$(echo "$STACKS_JSON" | python3 -c "
import sys, json
stacks = json.load(sys.stdin)
print(len(stacks))
" 2>/dev/null)
log "$STACK_COUNT stack(s) trouvée(s) dans Portainer."
echo "$STACKS_JSON" | python3 -c "
import sys, json
stacks = json.load(sys.stdin)
for s in stacks:
print(s['Id'], s['Name'])
" 2>/dev/null | while read stack_id stack_name; do
YAML_CONTENT=$(curl -sk \
-H "X-API-Key: $PORTAINER_TOKEN" \
"$PORTAINER_URL/api/stacks/$stack_id/file" \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
print(data.get('StackFileContent', ''))
" 2>/dev/null)
if [ -n "$YAML_CONTENT" ]; then
DEST="$SOURCE/$stack_name/docker-compose.yml"
mkdir -p "$SOURCE/$stack_name"
echo "$YAML_CONTENT" > "$DEST"
log "YAML exporté : $stack_name/docker-compose.yml"
else
log "ATTENTION : YAML vide ou inaccessible pour la stack $stack_name"
fi
done
fi
# -- Vérification des docker-compose.yml manquants ────────────────
# Le dossier "scripts" est exclu : ce n'est pas un container Docker
# Portainer lui-même ne figure pas dans les stacks - son docker-compose.yml
# doit être créé manuellement une fois (voir article sur le regroupement).
log "Vérification des docker-compose.yml..."
for dir in "$SOURCE"/*/; do
logiciel=$(basename "$dir")
compose="$dir/docker-compose.yml"
if [ ! -f "$compose" ]; then
log "ATTENTION : docker-compose.yml manquant dans $logiciel - à créer manuellement !"
fi
done
# -- Sauvegarde quotidienne ───────────────────────────────────────
log "Copie vers daily/$DATE..."
$RCLONE copy "$SOURCE" "$REMOTE/daily/$DATE"
# -- Sauvegarde hebdomadaire (chaque dimanche) ────────────────────
if [ "$DAY" -eq 7 ]; then
WEEK=$(date +%Y-W%V)
log "Dimanche : création sauvegarde hebdomadaire $WEEK"
$RCLONE copy "$REMOTE/daily/$DATE" "$REMOTE/weekly/$WEEK"
fi
# -- Sauvegarde mensuelle (le 1er de chaque mois) ─────────────────
if [ "$DOM" -eq 01 ]; then
YEARMONTH=$(date +%Y-%m)
log "1er du mois : création sauvegarde mensuelle $YEARMONTH"
$RCLONE copy "$REMOTE/daily/$DATE" "$REMOTE/monthly/$YEARMONTH"
fi
# -- Sauvegarde annuelle (le 1er janvier) ─────────────────────────
if [ "$DOM" -eq 01 ] && [ "$MONTH" -eq 01 ]; then
YEAR=$(date +%Y)
log "1er janvier : création sauvegarde annuelle $YEAR"
$RCLONE copy "$REMOTE/daily/$DATE" "$REMOTE/yearly/$YEAR"
fi
# -- Nettoyage des anciennes sauvegardes sur Drive ────────────────
# Quotidiennes : on garde 7 jours
log "Nettoyage daily > 7 jours..."
RCLONE_CLEAN="sudo rclone --config $RCLONE_CONF --log-file=$LOG"
$RCLONE_CLEAN delete "$REMOTE/daily" --min-age 7d 2>/dev/null
$RCLONE_CLEAN rmdirs "$REMOTE/daily" 2>/dev/null
# Hebdomadaires : on garde 4 semaines
if sudo rclone --config "$RCLONE_CONF" lsd "$REMOTE/weekly" > /dev/null 2>&1; then
log "Nettoyage weekly > 28 jours..."
$RCLONE_CLEAN delete "$REMOTE/weekly" --min-age 28d
$RCLONE_CLEAN rmdirs "$REMOTE/weekly"
else
log "Dossier weekly inexistant sur Drive, nettoyage ignoré."
fi
# Mensuelles : on garde 12 mois
if sudo rclone --config "$RCLONE_CONF" lsd "$REMOTE/monthly" > /dev/null 2>&1; then
log "Nettoyage monthly > 365 jours..."
$RCLONE_CLEAN delete "$REMOTE/monthly" --min-age 365d
$RCLONE_CLEAN rmdirs "$REMOTE/monthly"
else
log "Dossier monthly inexistant sur Drive, nettoyage ignoré."
fi
# Annuelles : conservées indéfiniment, pas de nettoyage automatique
log "=== Sauvegarde terminée ==="
La copie prend plusieurs minutes selon la taille de tes données. C’est normal et rassurant – si ça se termine en moins de 5 secondes, c’est qu’il y a un problème (voir encart erreurs fréquentes ci-dessous).
Cela lance le script tous les jours à 3h du matin. Assure-toi que le Beelink est allumé à cette heure. Sauvegarde avec Ctrl+O puis quitte avec Ctrl+X.
Vérifie que cron a bien enregistré :
crontab -l
Comment vérifier que la sauvegarde automatique a bien tourné
Le lendemain matin, consulte la fin du log :
tail -20 /home/USER/rclone-logs/backup-docker.log
La dernière entrée doit être datée de cette nuit avec === Sauvegarde terminée ===.
Déboguer une sauvegarde qui ne fonctionne pas
Si le log montre une sauvegarde terminée en moins de 5 secondes sans aucune ligne de copie de fichiers, c’est le signe que rclone s’est lancé mais n’a rien fait – souvent à cause d’une erreur silencieuse au démarrage.
La méthode pour diagnostiquer : lance rclone directement en ligne de commande et observe ce qui se passe :
Si cette commande fonctionne, la connexion Drive est bonne. Si elle échoue, le problème est dans la config rclone ou le token Google.
Ensuite relance le script manuellement et surveille le log en temps réel dans un second terminal :
tail -f /home/USER/rclone-logs/backup-docker.log
Erreurs fréquentes
La sauvegarde se termine en moins de 5 secondes Rclone a rencontré une erreur dès le départ et n’a rien copié, mais le script bash a continué jusqu’à la fin. Cause la plus fréquente : un conflit d’options ou un token Google Drive expiré. Diagnostique avec la commande lsd décrite ci-dessus.
« Can’t set -v and –log-level » Ce message apparaît si tu utilises à la fois --verbose et --log-level dans la même commande rclone. Les deux options sont incompatibles. Solution : n’utilise que --log-file sans --log-level – c’est ce que fait le script ci-dessus.
« Can’t follow symlink without -L/–copy-links » Ce message apparaît lors d’une restauration de Nginx Proxy Manager. Les certificats Let’s Encrypt dans letsencrypt/live/ sont des liens symboliques. Lors de la restauration, ajoute --copy-links à la commande rclone. La sauvegarde elle-même est correcte car le script utilise --links.
« Permission denied » sur les fichiers de Portainer ou NPM Ces containers écrivent leurs fichiers en root. Rclone doit s’exécuter avec sudo pour les lire. Vérifie que la ligne NOPASSWD est bien présente dans sudoers (étape 4), et que le chemin /usr/bin/rclone est correct sur ton système (which rclone pour le vérifier).
« Permission denied » lors de l’export du YAML Le fichier docker-compose.yml dans le dossier du logiciel appartient à root (créé avec sudo). Corrige les droits :
Le dossier weekly ou monthly n’apparaît pas C’est normal les premières semaines et les premiers mois. weekly se crée le premier dimanche après la mise en place, monthly le 1er du mois suivant. Le script vérifie leur existence avant de tenter un nettoyage – pas d’erreur à attendre.
Cron ne lance pas le script Vérifie que le service cron tourne : systemctl status cron. S’il est inactif : sudo systemctl enable cron && sudo systemctl start cron. Vérifie aussi que le script est bien exécutable : ls -la /home/USER/docker/scripts/backup-docker.sh doit afficher -rwxr-xr-x.
Dans le prochain article
On verra comment restaurer un container depuis une sauvegarde Google Drive – c’est-à-dire utiliser concrètement tout ce qu’on vient de mettre en place.
Commentaires récents