Aller au contenu

Lancer une appli comme service

Une appli lancée à la main (nohup npm start &, screen, tmux…) ne redémarre pas après un reboot de la CT ou de l'hôte, ni après un plantage. On l'a déjà vécu : une API restée arrêtée des jours après un redémarrage, sans que personne ne s'en rende compte. La règle : toute appli tourne en service systemd.

Le fichier de service

/etc/systemd/system/<appli>.service :

[Unit]
Description=<appli> (<à quoi elle sert>)
After=network-online.target
Wants=network-online.target
# au-delà de 5 échecs en 5 minutes, on arrête d'insister
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Type=simple
WorkingDirectory=/opt/<projet>
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
# variables et secrets : dans un fichier hors du repo, lisible par root seulement
EnvironmentFile=-/etc/<projet>/env
# idéalement un utilisateur dédié plutôt que root
User=<utilisateur>

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now <appli>
systemctl status <appli>
journalctl -u <appli> -f        # logs en direct

Pièges

npm/node installés avec nvm
systemd ne charge pas le profil du shell : il ne trouve pas node. Mettre le chemin complet dans ExecStart (/root/.nvm/versions/node/v<version>/bin/node), ou mieux, installer Node pour tout le système.
Restart=always sur une appli qui ne peut pas démarrer
Elle sera relancée sans fin, avec un nouveau fichier de log à chaque essai. On a déjà eu une CT bloquée parce que ses fichiers de log avaient épuisé tous les inodes du disque. StartLimitBurst évite ça.
Le fichier .env du projet
Il ne doit pas être dans git (.gitignore). Le mettre dans /etc/<projet>/env en chmod 600 et le charger avec EnvironmentFile.

Vérifier

pct reboot <CTID>    # depuis l'hôte
# puis, une minute plus tard :
pct exec <CTID> -- systemctl is-active <appli>