Organisation, validation et guide d’exploitation
/srv accueille les services
Placez chaque service dans son propre répertoire. Pour un nouveau projet, examinez d’abord /srv et confirmez que le répertoire prévu n’existe pas :
ls -ld /srv
sudo find /srv -mindepth 1 -maxdepth 2 -printf '%M %u:%g %p\n'
# Créer uniquement un chemin absent, sans lien symbolique ni montage.
sudo mkdir -- /srv/example-api &&
sudo chown -- "$VPS_USER:$VPS_USER" /srv/example-api
L’absence volontaire de -p fait échouer mkdir si le chemin existe ; && empêche alors le changement de propriétaire. Vérifiez que $VPS_USER désigne le compte de déploiement prévu et que son groupe homonyme existe. Sur un hôte partagé, il faut aussi empêcher les modifications concurrentes entre la vérification et la création.
N’exécutez jamais chown -R sur tout /srv. Un changement récursif de propriétaire touche les données des services autant que leur configuration : les volumes des conteneurs peuvent exiger des UID/GID numériques particuliers, et les sauvegardes un accès réservé à root. Pour un projet existant, vérifiez les exigences du service avant de modifier un chemin explicitement désigné. Un répertoire /srv/backups vide n’est pas un système de sauvegarde : il faut encore un calendrier, des versions, des copies hors site et des essais de restauration.
Trois questions courantes sur systemd
systemctl is-active docker # État actuel de l’unité
systemctl is-enabled docker # État d’activation du fichier d’unité
systemctl status docker --no-pager
systemctl is-active indique l’état actuel de l’unité ; systemctl is-enabled indique l’état d’activation du fichier d’unité. Cet état ne garantit pas que le service fonctionnera correctement au démarrage du système. Les dépendances ou l’activation par socket peuvent également lancer un service. En cas de panne, utilisez :
sudo journalctl -u docker --since today --no-pager
sudo journalctl -u tailscaled --since today --no-pager
sudo journalctl -u ssh --since today --no-pager
systemctl --failed --no-pager
Les journaux peuvent contenir des adresses IP, des noms d’utilisateur, des chemins ou des données d’application. Masquez les informations sensibles avant de les partager.
Mises à jour régulières
sudo apt update
apt list --upgradable
sudo apt upgrade
Lisez d’abord le résumé de la mise à niveau. Si vous devez automatiser les modifications, simulez-les avec apt-get -s avant de les appliquer, surtout si elles présentent un risque. Les mises à jour progressives d’Ubuntu peuvent différer volontairement certaines mises à jour ordinaires : il s’agit d’un déploiement par étapes, pas d’un conflit de dépendances.
Vérifiez si un redémarrage est nécessaire :
if [ -f /var/run/reboot-required ]; then
cat /var/run/reboot-required
else
echo "No reboot required"
fi
Si un redémarrage est nécessaire, vérifiez l’accès OpenSSH via Tailscale, gardez la session ouverte et exécutez sudo reboot. Une fois la machine revenue, reconnectez-vous et vérifiez de nouveau le noyau et les services en échec.
Liste de contrôle de validation
hostnamectl
timedatectl
nproc
free -h
df -h /
ip -brief addr
ip route
tailscale status
tailscale ip -4
systemctl is-active tailscaled
sudo ufw status verbose
sudo ufw status numbered
sudo sshd -t
sudo sshd -T | grep -E \
'^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|authenticationmethods) '
docker --version
docker compose version
systemctl is-active docker
docker info --format \
'ServerVersion={{.ServerVersion}} Driver={{.Driver}} CgroupDriver={{.CgroupDriver}}'
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}'
docker compose -f /srv/caddy/compose.yaml ps
docker compose -f /srv/uptime-kuma/compose.yaml ps
docker compose -f /srv/rsshub/compose.yaml ps
docker network inspect infra-edge
systemctl --failed --no-pager
find /srv -maxdepth 2 -printf '%M %u:%g %p\n' | sort
Comparez les valeurs SSH effectives avec la politique d’accès par clé seule, en vérifiant aussi les conditions des blocs Match applicables. Testez ensuite les accès depuis WSL2 :
# Doit réussir
ssh -o ConnectTimeout=10 "$VPS_USER@$TAILSCALE_IPV4"
# Doit échouer
ssh -o ConnectionAttempts=1 -o ConnectTimeout=5 \
"$VPS_USER@$VPS_PUBLIC_IPV4"
# Les deux contrôles de santé HTTPS publics doivent réussir
curl --fail https://infra.example.com/healthz
curl --fail https://rss.example.com/healthz
# Le port 1200 de RSSHub ne doit être accessible directement par aucune adresse de l’hôte
curl --connect-timeout 5 --max-time 7 \
"http://$VPS_PUBLIC_IPV4:1200/"
curl --connect-timeout 5 --max-time 7 \
"http://$TAILSCALE_IPV4:1200/"
Les deux contrôles de santé HTTPS publics doivent réussir avec une validation normale des certificats. La connexion SSH via Tailscale doit réussir, la tentative par l’adresse publique doit échouer, et les requêtes directes vers le port 1200 de RSSHub doivent échouer par l’adresse publique comme par l’adresse Tailscale.
Une simple mention 1200/tcp dans docker ps indique un port interne à l’image. Une publication sur l’hôte ressemble à 0.0.0.0:1200->1200/tcp et ne respecte pas cette configuration. L’état attendu est le suivant : Caddy publie les ports 80/443 de l’hôte, Kuma écoute exactement sur 127.0.0.1:3001, et RSSHub ne publie aucun port sur l’hôte.
Fréquence des vérifications
Priorités en cas d’incident
- Préserver l’accès : ne fermez pas la dernière session fonctionnelle.
- Ne pas multiplier les modifications : n’enchaînez pas des « correctifs » qui s’annulent mutuellement.
- Identifier la couche en cause : vérifiez successivement le routage, les ports, le pare-feu, le démon et l’authentification.
- Recueillir des éléments sans données sensibles : relevez l’état, les codes de sortie, les horodatages et les journaux récents.
- Rétablir le dernier état sûr : privilégiez le rétablissement d’un accès temporaire plutôt qu’une réinitialisation du système.
- Vérifier le rétablissement : utilisez une nouvelle connexion ou une requête complète.
Utilisez Tmux pour les opérations longues, afin qu’une interruption du réseau local ne vous prive pas du terminal pendant une mise à niveau ou un diagnostic. Tmux maintient les processus du shell distant lors d’une déconnexion SSH, mais pas lors d’un redémarrage de l’hôte. Il ne remplace pas un second chemin d’accès SSH.
Périmètre des opérations sur les services actuels
Les trois projets Compose actuels — Caddy, Uptime Kuma et RSSHub — ont des cycles de vie indépendants. Intervenez depuis le répertoire /srv/<service> correspondant, examinez d’abord docker compose ps et les journaux, puis décidez si un redémarrage est nécessaire. Ne redémarrez pas tous les conteneurs pour diagnostiquer une seule application et n’utilisez pas de nettoyage global Docker (prune).
Le déploiement miroir de RSSHub en production rassemble les mises à jour d’image, ACCESS_KEY, la validation des routes réelles, les vérifications canari et les étapes de retour arrière. Le consommateur de flux existant, ses données persistantes et son planificateur n’ont pas encore été migrés. La bascule du consommateur ainsi que la sauvegarde et la restauration de ses données persistantes restent à faire. Un RSSHub sain sur le VPS ne signifie pas que le consommateur en aval a été migré.