Créer un service systemd pour lancer une application au démarrage
systemd est le chef d'orchestre des services Linux. Voici comment transformer votre application en service qui démarre au boot, redémarre après un crash et se surveille facilement.
Service systemd : pourquoi l’utiliser ?
Un service systemd permet de lancer automatiquement une application au démarrage du VPS, de la superviser et de centraliser ses journaux. Il évite de laisser un programme attaché à une session SSH ou de le relancer manuellement après chaque redémarrage.
systemd est le gestionnaire de système et de services utilisé par de nombreuses distributions Linux, notamment Debian et Ubuntu. Il démarre les services, applique leurs dépendances et surveille leurs processus.
Transformer une application en service apporte plusieurs avantages :
- démarrage automatique avec le VPS ;
- exécution en arrière-plan ;
- redémarrage après certains crashs ;
- lancement sous un utilisateur non-root ;
- gestion centralisée avec
systemctl; - consultation des logs avec
journalctl; - arrêt propre pendant l’extinction du serveur.
PM2 propose des fonctions similaires pour les applications Node.js. systemd reste toutefois plus général : il peut lancer une application Node.js, Python, Go, Java ou un binaire compilé.
| Méthode | Usage |
|---|---|
node index.js ou python app.py | Test manuel dans un terminal |
| PM2 | Gestion simplifiée de processus Node.js |
| systemd | Service Linux natif pour tout type d’application |
Avant de commencer, connectez-vous au serveur avec un utilisateur disposant de sudo. Consultez le guide pour vous connecter à un VPS en SSH si nécessaire.
Comprendre l’anatomie d’un fichier .service
Un service est défini dans un fichier portant l’extension :
.service
Pour une unité créée par l’administrateur, utilisez généralement :
/etc/systemd/system/
Un fichier de service contient trois sections principales.
Section [Unit]
Elle décrit le service et son ordre de démarrage :
[Unit]
Description=Application web interne
Wants=network-online.target
After=network-online.target
Les directives courantes sont :
| Directive | Fonction |
|---|---|
Description= | Description lisible du service |
After= | Démarre l’unité après une autre |
Wants= | Ajoute une dépendance souhaitée |
Requires= | Ajoute une dépendance plus stricte |
Utilisez network-online.target uniquement lorsque l’application a réellement besoin d’un réseau opérationnel dès son démarrage.
Section [Service]
Elle définit le programme, son utilisateur et son comportement :
[Service]
Type=simple
User=monapp
Group=monapp
WorkingDirectory=/opt/mon-app
ExecStart=/usr/bin/node /opt/mon-app/index.js
Restart=on-failure
RestartSec=5s
Les directives importantes sont :
| Directive | Fonction |
|---|---|
Type=simple | Le processus lancé reste le processus principal |
User= | Compte Linux utilisé pour exécuter l’application |
Group= | Groupe Linux utilisé |
WorkingDirectory= | Dossier de travail de l’application |
ExecStart= | Commande exacte de démarrage |
Restart= | Définit les conditions de redémarrage |
RestartSec= | Délai avant une nouvelle tentative |
EnvironmentFile= | Charge des variables depuis un fichier |
Section [Install]
Elle indique à quelle cible rattacher le service lorsqu’il est activé :
[Install]
WantedBy=multi-user.target
multi-user.target correspond à un environnement système normal, adapté à la plupart des applications serveur.
Créer un service sous un utilisateur non-root
Ne lancez pas votre application avec root si elle n’a pas besoin de privilèges administrateur. Créez plutôt un utilisateur système dédié :
sudo useradd \
--system \
--user-group \
--home-dir /opt/mon-app \
--shell /usr/sbin/nologin \
monapp
Créez les dossiers nécessaires :
sudo mkdir -p /opt/mon-app
sudo mkdir -p /etc/mon-app
Déposez le code dans /opt/mon-app, puis attribuez-le au compte dédié :
sudo chown -R monapp:monapp /opt/mon-app
Vérifiez ensuite le chemin du programme utilisé dans ExecStart.
Pour Node.js :
command -v node
Le résultat peut être :
/usr/bin/node
Pour Python avec un environnement virtuel, le chemin peut être :
/opt/mon-app/.venv/bin/python
Créez maintenant le fichier :
sudo nano /etc/systemd/system/mon-app.service
Ajoutez cette configuration pour une application Node.js :
[Unit]
Description=Application Node.js mon-app
Wants=network-online.target
After=network-online.target
[Service]
Type=simple
User=monapp
Group=monapp
WorkingDirectory=/opt/mon-app
EnvironmentFile=/etc/mon-app/mon-app.env
ExecStart=/usr/bin/node /opt/mon-app/index.js
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
Pour une application Python, adaptez uniquement ExecStart :
ExecStart=/opt/mon-app/.venv/bin/python /opt/mon-app/app.py
Utilisez des chemins absolus dans
ExecStart. systemd ne charge pas automatiquement votre profil Bash, vos alias ou la configuration NVM d’une session interactive.
Testez aussi la commande sous l’utilisateur du service :
sudo -u monapp \
/usr/bin/node /opt/mon-app/index.js
Arrêtez le test avec Ctrl + C avant de démarrer le service.
Protéger les variables d’environnement et les secrets
Ne placez jamais un token, un mot de passe ou une clé API directement dans le fichier .service.
Évitez :
Environment=DISCORD_TOKEN=VOTRE_VRAI_TOKEN
Même si cette syntaxe est valide, le secret devient plus facile à exposer pendant une copie, une relecture ou un partage du fichier de service.
Créez plutôt :
sudo nano /etc/mon-app/mon-app.env
Ajoutez les variables sans utiliser export :
NODE_ENV=production
PORT=3000
DISCORD_TOKEN=VOTRE_TOKEN
DATABASE_URL=VOTRE_CHAINE_DE_CONNEXION
Protégez le fichier :
sudo chown root:root /etc/mon-app/mon-app.env
sudo chmod 600 /etc/mon-app/mon-app.env
Le service le charge grâce à :
EnvironmentFile=/etc/mon-app/mon-app.env
Ne publiez jamais ce fichier dans Git, un ticket de support ou une capture d’écran.
Le compte applicatif doit rester non-root. Les secrets doivent être conservés dans un
EnvironmentFileprotégé, jamais écrits directement dans le code ou le fichier.service.
Pour renforcer les comptes, les accès SSH et le pare-feu, consultez le guide pour sécuriser votre serveur Linux.
Activer et démarrer le service
Après la création ou la modification d’un fichier d’unité, rechargez la configuration de systemd :
sudo systemctl daemon-reload
Activez le service au démarrage et lancez-le immédiatement :
sudo systemctl enable --now mon-app.service
Vérifiez son état :
sudo systemctl status mon-app.service
Le statut attendu est :
Active: active (running)
Vous pouvez vérifier séparément son activation au démarrage :
sudo systemctl is-enabled mon-app.service
Le résultat attendu est :
enabled
Pour vérifier si le service fonctionne actuellement :
sudo systemctl is-active mon-app.service
Après une modification du code, redémarrez l’application :
sudo systemctl restart mon-app.service
Après une modification du fichier .service, utilisez d’abord :
sudo systemctl daemon-reload
sudo systemctl restart mon-app.service
Consulter les logs avec journalctl
Les sorties standard et les erreurs de l’application sont normalement envoyées au journal systemd.
Affichez tous les logs du service :
sudo journalctl -u mon-app.service
Affichez les 100 dernières lignes :
sudo journalctl \
-u mon-app.service \
-n 100 \
--no-pager
Suivez les nouveaux messages en direct :
sudo journalctl -u mon-app.service -f
Affichez uniquement les événements récents :
sudo journalctl \
-u mon-app.service \
--since "1 hour ago"
Pour les événements du démarrage actuel :
sudo journalctl \
-u mon-app.service \
-b
Lorsqu’un service ne démarre pas, utilisez cette séquence :
sudo systemctl status mon-app.service
sudo journalctl -u mon-app.service -n 100 --no-pager
Les erreurs fréquentes comprennent :
No such file or directory
Permission denied
Failed at step USER
Failed to load environment files
status=203/EXEC
Vérifiez alors :
- le chemin de
ExecStart; - l’existence de
WorkingDirectory; - l’utilisateur défini dans
User=; - les permissions du code ;
- la présence de l’
EnvironmentFile; - les dépendances de l’application.
Commandes systemd utiles au quotidien
| Commande | Action |
|---|---|
systemctl start mon-app | Démarrer le service |
systemctl stop mon-app | Arrêter le service |
systemctl restart mon-app | Arrêter puis redémarrer |
systemctl reload mon-app | Demander un rechargement si le service le prend en charge |
systemctl enable mon-app | Activer au démarrage |
systemctl disable mon-app | Désactiver au démarrage |
systemctl enable --now mon-app | Activer et démarrer immédiatement |
systemctl status mon-app | Afficher l’état et les erreurs récentes |
systemctl is-active mon-app | Vérifier si le service fonctionne |
systemctl is-enabled mon-app | Vérifier s’il démarre au boot |
systemctl daemon-reload | Recharger les fichiers d’unités |
journalctl -u mon-app -f | Suivre les logs en direct |
La commande reload ne fonctionne que si l’application et le fichier d’unité définissent une méthode de rechargement, généralement avec ExecReload=. Dans le cas contraire, utilisez restart.
Pour retirer complètement le service :
sudo systemctl disable --now mon-app.service
sudo rm /etc/systemd/system/mon-app.service
sudo systemctl daemon-reload
Des sauvegardes automatiques sont incluses pour vous aider à restaurer. Conservez aussi vos propres exports réguliers : vous restez responsable de vos données.
En résumé
- Un service systemd lance une application au démarrage et peut la redémarrer après un crash.
- Placez les unités administrateur dans
/etc/systemd/system/. - Utilisez les sections
[Unit],[Service]et[Install]. - Définissez un utilisateur système non-root avec
User=. - Utilisez des chemins absolus pour
WorkingDirectoryetExecStart. - Choisissez
Restart=on-failurepour relancer l’application après un échec. - Conservez les secrets dans un
EnvironmentFileprotégé. - Appliquez
chown root:rootetchmod 600au fichier de secrets. - Exécutez
systemctl daemon-reloadaprès chaque modification de l’unité. - Utilisez
systemctl enable --now mon-apppour activer et démarrer le service. - Vérifiez son état avec
systemctl status mon-app. - Consultez ses journaux avec
journalctl -u mon-app. - Pour créer un service systemd sur un VPS hébergé en France avec stockage NVMe, Anti-DDoS L3/L4/L7 inclus, panel de gestion et support francophone, découvrez les offres VPS TalCloud.