vps-systemd-services
Patrons systemd user services pour VPS — Type=simple/oneshot/forking, vérification, unités persistantes. Tmux, Camofox et autres services système utilisateur.
Quand l'utiliser (Trigger)
Déclenchement standard selon le contexte de l'écosystème Hermès.
Mode d'emploi (Usage)
Mode d'emploi standard via l'agent Hermès. VPS Systemd Services — Patrons pour services utilisateur
Guide pour créer, diagnostiquer et maintenir des services systemd en mode
user (systemctl --user) sur un VPS Linux. Couvre les trois types de
services systemd et leurs pièges spécifiques.
Contexte
Sur ce VPS, les services système comme Hermes Gateway, Camofox et tmux fonctionnent sous forme d’unités systemd. Les unités user (vs système) permettent de gérer des services sans sudo.
Services concernés :
tmux-main.service— session tmux persistante (Type=oneshot)camofox.service— navigateur anti-détection (Type=simple)hermes-gateway.service— passerelle de messagerie (Type=simple)
Les 3 patterns Type et leur sélection
1. Type=simple (processus long)
Quand : Le programme reste en avant-plan et ne fork pas.
Exemples : serveur Node.js (Camofox, gateway), sleep infinity, watchers.
[Service]
Type=simple
ExecStart=/usr/bin/node server.js
Restart=always
RestartSec=5
Vérification : systemctl --user status doit montrer active (running).
2. Type=oneshot + RemainAfterExit=yes (lance-et-quitte)
Quand : Le programme crée une ressource puis quitte immédiatement,
mais la ressource doit rester considérée comme « active » par systemd.
Exemples : tmux new-session -d, touch /tmp/flag, configuration unique.
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/tmux new-session -d -s main
ExecStop=/usr/bin/tmux kill-session -t main
Restart=on-failure
⚠️ Piège : Ne PAS utiliser Type=forking avec tmux new-session -d.
tmux crée la session et quitte (code 0). systemd voit le process parent sortir,
exécute ExecStop et tue la session immédiatement.
Vérification : systemctl --user status montre active (exited). C’est
normal — exited ici signifie « le service a fini de s’exécuter avec succès
et est considéré actif grâce à RemainAfterExit ».
3. Type=forking (legacy — à éviter)
Quand : Le programme fork, le parent sort, l’enfant continue.
Problème : Difficile à configurer correctement sans PIDFile. tmux,
sshd, et autres programmes qui daemonizent posent problème.
Recommandation : Préférer Type=simple (si possible) ou
Type=oneshot+RemainAfterExit à Type=forking. Sur ce VPS, Type=forking
a causé la perte de la session tmux 3 fois avant d’être remplacé par
oneshot.
Structure standard d’une unité user
[Unit]
Description=Description claire du service
After=network.target
[Service]
Type=<simple|oneshot|exec>
ExecStart=<commande>
ExecStop=<commande de nettoyage> # Optionnel mais recommandé
Restart=on-failure # ou always selon le besoin
[Install]
WantedBy=default.target # Pour un user service
Activation et vérification
# Recharger systemd après modification
systemctl --user daemon-reload
# Démarrer
systemctl --user enable --now mon-service.service
# Vérifier le statut
systemctl --user status mon-service.service
# Voir les logs
journalctl --user -u mon-service.service -f --since "5 minutes ago"
# Vérifier que le service survive à un redémarrage
# 1. Linger doit être activé
loginctl show-user bf | grep Linger
# Attendu : Linger=yes
# 2. Service enabled
systemctl --user is-enabled mon-service.service
La vérification checklist
Pattern de script de vérification bash (cf. scripts/verify-service.sh) :
#!/usr/bin/env bash
PASS=0; TOTAL=0
check() { TOTAL=$((TOTAL+1)); if [ "$1" = "0" ]; then PASS=$((PASS+1)); else echo "🔴 $2 → $3"; fi; }
# 1. Binaire installé
which tmux &>/dev/null; check $? "tmux installé" "binary missing"
# 2. Fichier de config présent
[ -f ~/.tmux.conf ]; check $? "Config présente" "fichier manquant"
# 3. Service unit défini
[ -f ~/.config/systemd/user/tmux-main.service ]; check $? "Service unit défini" "fichier manquant"
# 4. Service enabled
systemctl --user is-enabled tmux-main.service &>/dev/null; check $? "Enabled" ""
# 5. Ressource active (selon le type de service)
tmux has-session -t main 2>/dev/null; check $? "Session active" "session absente"
# 6. Linger
[ "$(loginctl show-user $USER 2>/dev/null | grep Linger | cut -d= -f2)" = "yes" ]; check $? "Linger" ""
echo "Résultat : $PASS / $TOTAL OK"
Références utiles
references/tmux-persistent-session.md— setup complet de la session tmux en systemd, fixType=oneshot, runbook opérationnel, troubleshootingreferences/hermes-interactive-cli-workflow.md— workflow interactif Hermes dans tmux : aliash, combo mosh+tmux, quotidien SSH, recovery après déconnexionreferences/verification-script.sh— script de vérification complet (14 points) pour la stack tmux + mosh + systemd
Pitfalls
❌ Type=forking avec tmux new-session -d
Type=forking ne fonctionne PAS avec tmux new-session -d. tmux quitte
immédiatement après avoir créé la session. Le processus parent sort avec
code 0. systemd voit le parent sortir et exécute ExecStop, tuant la session.
Correctif : Utiliser Type=oneshot + RemainAfterExit=yes.
❌ Linger désactivé = service ne survit pas au logout
Même avec [Install] WantedBy=default.target, un user service ne démarre
pas au boot si Linger est désactivé.
loginctl enable-linger bf
systemctl --user enable mon-service.service
❌ Restart=on-failure vs Restart=always
on-failure: redémarre seulement si le service crash (non-zero exit)always: redémarre TOUJOURS, même si le service sort normalement
Pour Type=oneshot, utiliser on-failure. Pour Type=simple, utiliser
always.
❌ ExecStop tuant la session au démarrage
Si le service est Type=forking et que le process parent sort immédiatement,
systemd exécute ExecStop en pensant que le service s’est arrêté. Solution :
changer le Type.
Absorbed: Camofox Systemd Integration
references/camofox-systemd.md — Specific systemd integration for Camofox browser automation: BindsTo/After directives for Hermes Gateway dependency, cookie backup/restore scripts. Deployed and active since 2026-06-11. Previously a standalone skill (camofox-systemd).
- references/camofox-deployment-example.md — Deployment example with exact unit file contents and verification steps.