feat(veille): extension du suivi versions au VPS Contabo et mise a jour DSH/FileBrowser

This commit is contained in:
Nabil Derouiche
2026-08-22 17:06:58 +01:00
parent b1c26fc504
commit 2152b06ac9
3 changed files with 558 additions and 851 deletions
+85
View File
@@ -0,0 +1,85 @@
# DeepSeek Harness (DSH) VPS & FileBrowser — Guide d'Exploitation et MAJ
Ce document décrit la structure, la configuration et la procédure de mise à jour de la stack **DeepSeek Harness (`dsh-vps`)** et de son compagnon **FileBrowser (`dsh-vps-filebrowser`)** hébergés sur le VPS Contabo (`100.94.90.119`).
---
## 1. Architecture et Composants
```
/home/dsh-agent/dsh-vps/
├── Dockerfile # node:20-bookworm-slim + @deepseek-ai/dsh pinné + inkstone + patch 0.0.0.0
├── docker-compose.yml # Services: dsh-proxy, dsh-vps, dsh-filebrowser
├── entrypoint.sh # Script de démarrage dsh-web-app
├── nginx.conf # Proxy inverse TLS + Basic Auth (ports 8900 et 8901)
├── auth/ # .htpasswd, credentials.txt
├── certs/ # Certificats auto-signés TLS
└── backups/ # Sauvegardes dsh_vps_home
```
### Services et Ports
| Service | Conteneur | Port Interne | Port Public / Tailscale | Auth | Description |
|---|---|---|---|---|---|
| `dsh-proxy` | `dsh-vps-proxy` | 8900 / 8901 | `100.94.90.119:8900` / `8901` | Basic Auth | Proxy TLS Nginx unifié |
| `dsh-vps` | `dsh-vps` | 3080 | Réseau Docker `dsh_vps_net` | Proxy 8900 | Instance DSH Web UI & Agent |
| `dsh-filebrowser` | `dsh-vps-filebrowser` | 8080 | Réseau Docker `dsh_vps_net` | Proxy 8901 | Explorateur de fichiers workspace |
---
## 2. Points d'Attention & Pièges Techniques
1. **Version DSH dans Dockerfile** :
- La version est explicitement fixée dans le `Dockerfile` à la ligne `RUN npm install -g @deepseek-ai/dsh@<version> @banlan/inkstone`.
- Ne jamais utiliser `@latest` sans vérifier les breaking changes.
2. **Patch de binding `0.0.0.0` dans `startup.js`** :
- Par défaut, `@deepseek-ai/dsh-web-app` interdit l'écoute sur `0.0.0.0` (erreur de sécurité native).
- Dans le conteneur, l'écoute sur `0.0.0.0` est indispensable pour que le proxy Nginx (`dsh-vps-proxy`) puisse lui transférer les requêtes.
- Le `Dockerfile` applique un patch obligatoire :
```dockerfile
RUN find /usr/local/lib/node_modules -name "startup.js" -path "*/@deepseek-ai/dsh-web-app/*" -exec sed -i 's/if (options.host === "0.0.0.0")/if (false \&\& options.host === "0.0.0.0")/' {} +
```
- **Vérification post-build impérative** :
```bash
docker exec dsh-vps sh -c 'grep -n "options.host" $(find /usr/local/lib/node_modules -name startup.js -path "*/@deepseek-ai/dsh-web-app/*")'
```
3. **FileBrowser Entrypoint (`v2.63.23+`)** :
- Depuis les versions récentes de l'image `filebrowser/filebrowser`, le binaire est localisé dans `/bin/filebrowser` (et non `/filebrowser`).
- L'entrypoint officiel utilise `tini` et `/init.sh` qui tente d'écrire dans `/config` appartenant à `root`.
- L'exécution avec `user: "1001:1001"` requiert de surcharger l'entrypoint :
```yaml
entrypoint: ["/bin/filebrowser"]
command: ["--noauth", "-a", "0.0.0.0", "-p", "8080", "-r", "/srv", "-d", "/srv/.filebrowser.db"]
```
---
## 3. Procédure de Mise à Jour DSH
1. **Sauvegarde préalable de `dsh_vps_home`** :
```bash
ssh -i ~/.ssh/vps_dsh_agent dsh-agent@100.94.90.119 \
"docker run --rm -v dsh_vps_home:/source:ro -v /home/dsh-agent/dsh-vps/backups:/backup alpine \
tar -czf /backup/dsh_vps_home-$(date +%Y%m%d-%H%M%S).tar.gz -C /source ."
```
2. **Mise à jour du Dockerfile** :
Modifier le tag de version dans `/home/dsh-agent/dsh-vps/Dockerfile`.
3. **Rebuild sans cache** :
```bash
cd /home/dsh-agent/dsh-vps && docker compose build --no-cache dsh-vps
```
4. **Recréation du conteneur** :
```bash
docker compose up -d --force-recreate dsh-vps
```
5. **Contrôles de conformité** :
- Version binaire : `docker exec dsh-vps dsh --version`
- Patch actif : `docker exec dsh-vps sh -c 'grep -n "options.host" $(find /usr/local/lib/node_modules -name startup.js -path "*/@deepseek-ai/dsh-web-app/*")'`
- Écoute interne : `docker exec dsh-vps curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3080`
- Proxy HTTPS : `curl -sk -u "dsh-admin:..." https://100.94.90.119:8900`
- Vérification Bifrost : `docker exec dsh-vps curl -s -H "Authorization: Bearer sk-bf-..." http://100.86.197.88:3086/v1/models`
+56 -34
View File
@@ -1,6 +1,6 @@
# Veille Versions Stack NAS & Référentiel Baserow
# Veille Versions Stack NAS & VPS — Référentiel Baserow
Ce document décrit le fonctionnement du dispositif de suivi et de veille automatisée des versions des conteneurs du NAS Synology.
Ce document décrit le fonctionnement du dispositif de suivi et de veille automatisée des versions des conteneurs du NAS Synology et du VPS Contabo.
> **Doctrine stricte** : Ce workflow ne fait **que détecter et notifier**. Aucune mise à jour n'est exécutée automatiquement. Toute opération de mise à jour fait l'objet d'un brief de cadrage, d'une exécution contrôlée avec sauvegardes et d'une validation par commandes réelles.
@@ -11,10 +11,11 @@ Ce document décrit le fonctionnement du dispositif de suivi et de veille automa
```mermaid
graph TD
Trigger["Schedule Trigger (Lundi 08h00 Africa/Tunis)"] --> ReadBR["Lire Table Baserow (Table 1097 / Infra Stack)"]
ReadBR --> SSHCheck["SSH Restreint NAS (n8n-versions-ro)"]
SSHCheck --> MapItems["Préparer Mapping & Éléments"]
MapItems --> DHub["API Docker Hub (Tags stables)"]
DHub --> Analyze["Analyser Écarts & Versions"]
ReadBR --> SSHNAS["SSH Restreint NAS (n8n-versions-ro @ 192.168.100.33:22222)"]
SSHNAS --> SSHVPS["SSH Restreint VPS (n8n-versions-ro @ tailscale-nyora-bridge:22223)"]
SSHVPS --> MapItems["Préparer Mapping & Éléments (Fusion NAS & VPS)"]
MapItems --> Registries["API Registres (Docker Hub & npm registry)"]
Registries --> Analyze["Analyser Écarts & Versions (Boucle 11 items)"]
Analyze --> UpdateBR["Mettre à jour Baserow (PATCH Table 1097)"]
UpdateBR --> Filter["Filtrer Alertes (Si nouvel écart détecté)"]
Filter -->|Nouvel écart| Telegram["Notification Telegram (ND_Telegram)"]
@@ -26,16 +27,17 @@ graph TD
## 2. Composants Techniques
### A. Référentiel Baserow (`infra_versions`)
- **Workspace** : `187 (Perso)` *(déplacé depuis le 148 le 21/08/2026)*
- **Workspace** : `187 (Perso)`
- **Database** : `Infra Stack` (ID `317`)
- **Table** : `infra_versions` (ID `1097`)
- **URL** : `https://baserow.bolbol.tn/database/317/table/1097`
- **Token API dédié** : `n8n-infra-versions` (Token ID `32`, scopé Workspace 187 Perso)
- **Champs suivis** :
- `conteneur` (Texte, clé primaire) : Nom du conteneur
- `image_repo` (Texte) : Repository Docker Hub (ex: `n8nio/n8n`, `maximhq/bifrost`)
- `methode_verif` (Single select) : `image_tag` ou `exec_version`
- `version_installee` (Texte) : Version réelle active sur le NAS
- `image_repo` (Texte) : Repository Docker Hub ou nom de package npm (ex: `@deepseek-ai/dsh`)
- `methode_verif` (Single select) : `image_tag`, `exec_version` ou `npm_registry`
- `emplacement` (Single select) : `NAS` ou `VPS`
- `version_installee` (Texte) : Version réelle active sur l'hôte
- `derniere_version_disponible` (Texte) : Dernière version stable publiée
- `ecart` (Texte) : Statut de l'écart (`0`, `Installée: ... ➔ Dispo: ...`)
- `criticite` (Single select) : `Critique`, `Important`, `Mineur`
@@ -48,20 +50,34 @@ graph TD
---
### B. Accès SSH Restreint NAS (`n8n-versions-ro`)
Pour respecter le principe de moindre privilège et interdire tout shell interactif ou injection de commande :
- **Compte DSM** : `n8n-versions-ro` (UID `1041`, membre du groupe `docker` `65538`).
- **Clé SSH** : Clé Ed25519 dédiée (`/volume1/docker/scripts/id_ed25519_n8n_versions`).
- **Restriction `authorized_keys`** :
```text
command="/volume1/docker/scripts/versions-check.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIn3e1VvE3Z/q1W5o6Q+30w7U57u3aK8JqC8Z57Z8z/c n8n-versions-ro
command="/volume1/docker/scripts/versions-check.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKDwuAwKnKiKskL+Vr4WYhn/uySlk5jyOHPh1R/P/9K0 n8n-versions-ro
```
- **Script exécutable** : `/volume1/docker/scripts/versions-check.sh`
- Filtre `$SSH_ORIGINAL_COMMAND` contre une whitelist stricte des 9 conteneurs.
- Toute commande arbitraire (`rm -rf /`, `sh`, etc.) est rejetée avec un code d'erreur `1`.
- **Script exécutable** : `/volume1/docker/scripts/versions-check.sh` (mode 755)
---
### C. Workflow n8n (`veille-versions-stack`)
### C. Accès SSH Restreint VPS (`n8n-versions-ro`)
- **Compte VPS** : `n8n-versions-ro` (UID `1002`, GID `1002`, membre du groupe `docker`).
- **Clé SSH dédiée** : `/volume1/docker/scripts/id_ed25519_n8n_versions_vps`
- **Fingerprint réel** : `256 SHA256:fTDnqFouAhwApAsnQjuLoGjvZCNoHAwYC4gpGqRvygY n8n-versions-ro@vps (ED25519)`
- **Clé publique** : `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdwCzUBTsBKNSRxhjwU82o9T2VbQn4HKbp+3mFyIQTq n8n-versions-ro@vps`
- **Restriction `authorized_keys` VPS** (`/home/n8n-versions-ro/.ssh/authorized_keys`) :
```text
command="/home/n8n-versions-ro/versions-check-vps.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdwCzUBTsBKNSRxhjwU82o9T2VbQn4HKbp+3mFyIQTq n8n-versions-ro@vps
```
- **Script exécutable VPS** : `/home/n8n-versions-ro/versions-check-vps.sh` (mode 755)
- **Relais Réseau n8n ➔ VPS** :
- OpenSSH standard écoute sur le port `22222` sur l'interface `tailscale0` du VPS (`100.94.90.119:22222`).
- Sur le NAS, le conteneur `tailscale-vps-ssh-relay` (partageant l'espace réseau de `tailscale-nyora-bridge`) relaie le port `22223` vers `100.94.90.119:22222`.
- Le conteneur `n8n` interroge directement `tailscale-nyora-bridge:22223`.
---
### D. Workflow n8n (`veille-versions-stack`)
- **ID Workflow** : `zUWN5K4Q1A2JKFIS`
- **Déclenchement** : Hebdomadaire (Lundi à 08h00 Africa/Tunis) + Webhook de test manuel `/webhook/test-veille-versions`.
- **Canal Telegram** : Credential `ND_Telegram` (`OyOHh6jAzCDsiBux`), Chat ID `2084513684`.
@@ -69,32 +85,38 @@ Pour respecter le principe de moindre privilège et interdire tout shell interac
---
## 3. Table des 9 Conteneurs Suivis
## 3. Table des 11 Conteneurs Suivis
| Conteneur | Image Repo | Méthode | Criticité | Particularités |
|---|---|---|---|---|
| `n8n` | `n8nio/n8n` | `exec_version` | Important | Image custom (docx, exceljs) |
| `bifrost` | `maximhq/bifrost` | `image_tag` | Critique | Pin image, backup config.db/config.json |
| `gitea` | `gitea/gitea` | `image_tag` | Important | Pin rootless, backup natif `gitea dump` |
| `portainer` | `portainer/portainer-ce` | `image_tag` | Mineur | Pilote stacks, MAJ en priorité |
| `vaultwarden` | `vaultwarden/server` | `image_tag` | Mineur | Pin alpine, backup db.sqlite3 |
| `baserow` | `baserow/baserow` | `exec_version` | Important | Mode minimal, DNS dynamique Nginx |
| `crowdsec` | `crowdsecurity/crowdsec` | `exec_version` | Important | Sécurité IDS/IPS DSM |
| `tailscale-nyora-bridge` | `tailscale/tailscale` | `image_tag` | Mineur | Bridge HTTP/SOCKS5 |
| `trilium` | `triliumnext/trilium` | `image_tag` | Mineur | `En pause` (exclu des alertes actives) |
| Conteneur | Emplacement | Image Repo / Package | Méthode | Criticité | Particularités |
|---|---|---|---|---|---|
| `n8n` | NAS | `n8nio/n8n` | `exec_version` | Important | Image custom (docx, exceljs) |
| `bifrost` | NAS | `maximhq/bifrost` | `image_tag` | Critique | Pin image, backup config.db/config.json |
| `gitea` | NAS | `gitea/gitea` | `image_tag` | Important | Pin rootless, backup natif `gitea dump` |
| `portainer` | NAS | `portainer/portainer-ce` | `image_tag` | Mineur | Pilote stacks, MAJ en priorité |
| `vaultwarden` | NAS | `vaultwarden/server` | `image_tag` | Mineur | Pin alpine, backup db.sqlite3 |
| `baserow` | NAS | `baserow/baserow` | `exec_version` | Important | Mode minimal, DNS dynamique Nginx |
| `crowdsec` | NAS | `crowdsecurity/crowdsec` | `exec_version` | Important | Sécurité IDS/IPS DSM |
| `tailscale-nyora-bridge` | NAS | `tailscale/tailscale` | `image_tag` | Mineur | Bridge HTTP/SOCKS5 |
| `trilium` | NAS | `triliumnext/trilium` | `image_tag` | Mineur | `En pause` (exclu des alertes actives) |
| `dsh-vps` | VPS | `@deepseek-ai/dsh` | `npm_registry` | Important | Build custom, version npm pinnée, patch binding `startup.js` |
| `dsh-vps-filebrowser` | VPS | `filebrowser/filebrowser` | `image_tag` | Mineur | Compagnon Web UI, entrypoint `/bin/filebrowser` |
---
## 4. Procédure de Test et Validation
1. **Test d'exécution manuelle sans alerte (tout à jour)** :
1. **Test d'exécution manuelle globale via webhook** :
```bash
curl -s http://192.168.100.33:5678/webhook/test-veille-versions
# Réponse attendue : {"no_alert": true, "message": "Aucun nouvel ecart"}
curl -s http://192.168.100.33:5678/webhook/test-veille-versions -H "Host: n8n.bolbol.tn"
# Réponse attendue si tout est à jour : {"no_alert": true, "message": "Aucun nouvel ecart"}
```
2. **Test d'interrogation SSH unitaire** :
2. **Test d'interrogation SSH unitaire NAS** :
```bash
ssh -p 22222 -i /volume1/docker/scripts/id_ed25519_n8n_versions -o BatchMode=yes n8n-versions-ro@127.0.0.1 "n8n"
# Réponse attendue : version exacte (ex: 2.36.5)
ssh -p 22222 -i /volume1/docker/scripts/id_ed25519_n8n_versions -o BatchMode=yes n8n-versions-ro@127.0.0.1 "all"
```
3. **Test d'interrogation SSH unitaire VPS** (depuis le conteneur `n8n`) :
```bash
docker exec n8n ssh -p 22223 -i /tmp/id_vps_n8n -o BatchMode=yes n8n-versions-ro@tailscale-nyora-bridge "all"
```
File diff suppressed because it is too large Load Diff