Déploiement de WatchTower, registre d’infrastructure du laboratoire

Déploiement reproductible de WatchTower dans un conteneur LXC depuis un nœud Proxmox : empaquetage du dépôt, envoi par pct, build du front, environnement Python de l’API, unité systemd versionnée et contrôle HTTP.

  • Publié le
  • Mis à jour
  • Lecture7 min
  • ContexteHomelab / projet
  • NiveauAvancé
  • Durée30 min
  • EnvironnementProxmox VE · LXC · FastAPI · Vite
Version
1.0
Date d’édition
05/10/2026

Mise en service et mise à jour de WatchTower, le registre d’infrastructure développé pour le laboratoire, dans un conteneur LXC non privilégié, sans SSH, par le script de déploiement du dépôt.

1. Objet

WatchTower documente ce qui est décidé, déployé et alloué dans le laboratoire, et affiche l’état mesuré quand un collecteur répond. Il se compose d’une API FastAPI et d’une interface React construite avec Vite. Cette procédure décrit son déploiement reproductible : la même commande sert à la première installation et à chaque mise à jour.

2. Périmètre et prérequis

Périmètre

Couvert : empaquetage du dépôt, envoi dans le conteneur, installation des dépendances, build de l’interface, environnement Python de l’API, unité systemd, redémarrage et contrôle HTTP.

Non couvert : création du conteneur, publication derrière le proxy inverse et certificat TLS, saisie des connecteurs dans l’écran Paramètres.

Prérequis

  • Un conteneur LXC démarré, avec Node.js, npm et Python 3 installés.
  • Un accès au nœud Proxmox qui héberge le conteneur, avec les droits d’administration pct.
  • Une copie du dépôt WatchTower sur ce nœud.
  • Un fichier .env déjà présent dans le conteneur : le script ne le crée pas et ne le modifie jamais.

Paramètres

Toutes les variables sont facultatives : le script applique les valeurs par défaut du laboratoire.

Variable Rôle Valeur par défaut
WT_DEPLOY_CTID Identifiant du conteneur cible 2013
WT_DEPLOY_CHEMIN Emplacement du dépôt dans le conteneur /opt/watchtower
WT_DEPLOY_SERVICE Unité systemd de l’API watchtower-api.service
WT_DEPLOY_HOTE Adresse du contrôle HTTP, depuis le conteneur 127.0.0.1:8000

3. Rôles et responsabilités

Rôle Responsabilité
Administrateur virtualisation Lance le script depuis le nœud Proxmox et vérifie l’état du conteneur.
Développeur Livre un dépôt dont les tests passent ; maintient l’unité systemd versionnée.
Détenteur des secrets Tient le fichier .env et le coffre des connecteurs, jamais versionnés.
Note

Homelab individuel. Les rôles sont tenus par la même personne ; ils sont distingués pour identifier les responsabilités.

4. Procédure de déploiement

Depuis le nœud Proxmox, à la racine du dépôt :

bash scripts/deploiement.sh

Le script s’arrête à la première étape en erreur. Un échec peut toutefois laisser des modifications partielles : avant toute relance, examiner les journaux et l’état des fichiers, des dépendances et des services, et sauvegarder le code, la configuration et les données nécessaires à un retour arrière.

1. Vérification du conteneur

La commande pct doit exister et le conteneur doit être démarré (pct status <CTID>).

2. Empaquetage du dépôt

Le dépôt est archivé sans .git, sans node_modules, sans environnement Python, sans build précédent, sans fichier .env et sans le dossier donnees/ qui contient le coffre chiffré des connecteurs.

3. Envoi dans le conteneur

pct push <CTID> <archive> /tmp/<archive>
pct exec <CTID> -- tar -C /opt/watchtower -xzf /tmp/<archive>

Le conteneur n’accepte que des clés SSH : l’envoi passe par pct, sans ouvrir d’accès supplémentaire. L’archive ne contenant pas de .env, l’extraction ne peut pas l’écraser.

4. Interface : dépendances et build

npm install --no-audit --no-fund
npm run build

5. API : environnement Python

L’environnement virtuel est créé s’il n’existe pas, puis mis à jour ; il n’est jamais recréé.

python3 -m venv .venv
.venv/bin/pip install --upgrade pip
.venv/bin/pip install -e '.[dev]'

6. Unité systemd

L’unité versionnée dans deploy/systemd/ est copiée dans /etc/systemd/system/, puis systemd est rechargé (systemctl daemon-reload).

7. Redémarrage

systemctl restart watchtower-api.service
systemctl is-active watchtower-api.service

En cas d’échec, le script affiche l’état du service et les cinquante dernières lignes du journal.

8. Contrôle HTTP

La racine / doit répondre 200 depuis le conteneur. C’est la seule route publique : tout /api/v1/ est protégé par la session, et l’état détaillé se lit ensuite dans l’écran Paramètres ou avec scripts/sante.sh.

Variante : sans accès au nœud Proxmox

Le script exige pct, donc un accès au nœud qui héberge le conteneur. Sans cet accès, l’administrateur peut réaliser les étapes ci-dessous depuis un client SSH autorisé vers le conteneur. L’exemple réseau conserve la politique hermes-deploy (voir la procédure « Accès SSH par clé à un hôte du laboratoire »).

  • Relever les modifications locales. Avant tout, git diff dans /opt/watchtower : des correctifs ont déjà été appliqués dans le conteneur hors dépôt. Ils sont reportés dans l’archive, sinon ils régressent.
  • Sauvegarder. Archive de /opt/watchtower sans node_modules dans /root/sauvegarde-watchtower-<date>/, avec l’unité systemd et la liste des paquets Python (pip freeze).
  • Construire et contrôler l’archive. Mêmes exclusions que le script, plus ./donnees. La commande suivante doit ne rien afficher : tar -tzf <archive> | grep -E '(^|/)[.]env$|donnees/'. Envoi par scp.
  • Construire l’interface sous le compte propriétaire des fichiers (runuser -u <compte> -- npm install, puis npm run build). Si le build échoue sur un dossier apps/web/dist appartenant à root, reste d’un build par pct, rendre ce dossier au compte propriétaire.
  • Mettre à jour l’API : .venv/bin/pip install -e '.[dev]', puis pytest -q.
  • Redémarrer : copie de l’unité, systemctl daemon-reload, puis systemctl restart watchtower-api.service.
  • Contrôler : WT_DEPLOY_CTID= ./scripts/sante.sh. Un identifiant vide fait passer le script en contrôle local ; résultat attendu : « nominal ».

Comme avec le script, le dossier .git du conteneur n’est pas mis à jour : un git status y montre un écart, attendu.

5. Intégration réseau

  • L’API écoute en local dans le conteneur ; l’accès se fait par le proxy inverse Nginx Proxy Manager, qui porte le certificat TLS.
  • Les collecteurs (Proxmox, Nginx Proxy Manager, Technitium) sont joints depuis le conteneur, avec les accès saisis dans Paramètres → Connecteurs.

6. Durcissement et sécurité

  • Aucun secret dans le dépôt ni dans l’archive envoyée : .env et donnees/ sont exclus.
  • Les accès aux services sont chiffrés dans le coffre des connecteurs ; aucune route ne renvoie un secret.
  • Session à cookie httpOnly, jeton CSRF en mémoire, limitation des tentatives de connexion.
  • Conteneur non privilégié, sans accès par mot de passe.

Retour arrière

Pour revenir à une version précédente, vérifier d’abord la compatibilité de ses dépendances et des éventuelles migrations de données. Restaurer les éléments nécessaires depuis la sauvegarde, puis contrôler le service et les parcours utiles. L’exclusion de .env et du coffre de l’archive ne garantit pas, à elle seule, un retour arrière limité au code.

7. Vérifications finales

Contrôle Critère d’acceptation Statut
Script Le dernier message indique « Déploiement terminé » ☐
Service systemctl is-active watchtower-api.service renvoie active ☐
HTTP / répond 200 depuis le conteneur ☐
Secrets Le .env du conteneur est inchangé après le déploiement ☐
Interface La connexion aboutit et l’écran Paramètres affiche l’état des collecteurs ☐

8. Références et historique des révisions

  • Dépôt WatchTower : scripts/deploiement.sh, scripts/sante.sh, deploy/systemd/watchtower-api.service.
  • HL-PRC-003 — Grappe de virtualisation Proxmox VE, prérequis de l’hébergement du conteneur.
Version Date Modifications
1.0 05/10/2026 Création du document à partir du script de déploiement du dépôt ; variante d’administration par SSH sans accès au nœud Proxmox.
Défiler vers le haut