Prendre en main systemd et gérer un service Linux
Apprenez à créer, activer et diagnostiquer un service systemd sous Linux avec une méthode pas à pas, des commandes utiles et des conseils pratiques.

systemd est aujourd’hui le système d’initialisation et de gestion des services le plus répandu sur de nombreuses distributions Linux. Si vous administrez un serveur, déployez une application maison ou souhaitez simplement automatiser le lancement d’un programme au démarrage, savoir manipuler un service systemd est une compétence fondamentale.
Dans ce tutoriel, vous allez apprendre à créer un service systemd, à le démarrer, à l’activer au boot, puis à diagnostiquer ses pannes avec les bons outils. L’objectif est de comprendre la logique générale de systemd plutôt que d’empiler des commandes sans contexte.
Le guide s’appuie sur un exemple simple et pédagogique : un petit script lancé comme un service. Vous pourrez ensuite transposer la méthode à un binaire, un agent, un worker, une API interne ou un démon applicatif.
Prérequis
- Disposer d’une machine Linux utilisant
systemd. - Avoir un accès à un compte autorisé à utiliser
sudoou à administrer le système. - Connaître les bases de la ligne de commande : navigation, édition de fichier texte, exécution de commandes.
- Utiliser un éditeur en terminal comme
nano,vimouvi.
Remarque : selon la distribution, certains chemins ou outils secondaires peuvent varier, mais les principes présentés ici restent les mêmes.
Matériel nécessaire
- Machine Linux avec systemd
- Accès administrateur avec sudo
- Éditeur de texte en terminal
- Un script ou programme à lancer comme service
Étapes
Comprendre le rôle de systemd et la notion d’unité



Avant de créer quoi que ce soit, il faut comprendre ce que gère
systemd. Son rôle ne se limite pas au démarrage de la machine : il orchestre aussi les services, dépendances, journaux associés, redémarrages, cibles de démarrage et certains comportements d’exécution.Dans
systemd, un objet administré est représenté par une unité (unit). Il existe plusieurs types d’unités, par exemple :.servicepour un service,.socketpour une activation par socket,.timerpour une exécution planifiée,.targetpour un regroupement logique d’unités.
Dans ce tutoriel, nous allons travailler avec une unité de type
.service. Un service est défini dans un fichier texte, souvent appelé fichier d’unité. Ce fichier indique notamment :- la description du service,
- les dépendances éventuelles,
- la commande à lancer,
- la manière de redémarrer le processus en cas d’échec,
- l’utilisateur système à utiliser,
- la cible dans laquelle le service doit être activé.
Pour vérifier que votre machine utilise bien
systemd, vous pouvez exécuter :bashps -p 1 -o comm=Si la sortie affiche
systemd, vous êtes dans le bon environnement. Vous pouvez aussi interroger l’état global du gestionnaire avec :bashsystemctl --versionLa commande
systemctlest l’interface principale d’administration desystemd. C’est elle que vous utiliserez pour démarrer, arrêter, activer, désactiver et inspecter les services.Préparer un exemple simple de programme à exécuter
Pour apprendre sans complexité inutile, le plus simple est de partir d’un petit script shell. Le but n’est pas de produire un démon sophistiqué, mais de disposer d’un programme durable que
systemdpourra superviser.Créez par exemple un répertoire dédié :
bashsudo mkdir -p /opt/demo-systemdCréez ensuite un script :
bashsudo nano /opt/demo-systemd/mon-service.shPlacez-y le contenu suivant :
bash#!/bin/sh while true do echo "$(date) : service actif" sleep 30 doneRendez le script exécutable :
bashsudo chmod +x /opt/demo-systemd/mon-service.shCe script écrit périodiquement un message sur la sortie standard. Lorsqu’il sera lancé par
systemd, ces messages pourront être consultés dans le journal viajournalctl.Vous pouvez le tester manuellement avant de l’intégrer à
systemd:bash/opt/demo-systemd/mon-service.shInterrompez-le ensuite avec
Ctrl+C. Cette étape permet de vérifier que le programme fonctionne seul avant d’ajouter une couche d’orchestration. C’est une bonne habitude : si un script échoue déjà en exécution directe, le problème ne vient pas desystemd.Créer le fichier d’unité systemd
Les fichiers d’unité locaux sont généralement placés dans
/etc/systemd/system/. C’est l’emplacement habituel pour vos propres services administrés localement.Créez le fichier :
bashsudo nano /etc/systemd/system/mon-service.serviceAjoutez cette configuration de base :
bash[Unit] Description=Service de démonstration systemd After=network.target [Service] Type=simple ExecStart=/opt/demo-systemd/mon-service.sh Restart=on-failure RestartSec=5 User=root WorkingDirectory=/opt/demo-systemd [Install] WantedBy=multi-user.targetVoici le rôle de chaque section :
[Unit]: métadonnées et dépendances générales du service.[Service]: comportement d’exécution du processus.[Install]: informations utilisées lors de l’activation automatique.
Détaillons maintenant les directives importantes :
Description=fournit un libellé lisible.After=network.targetindique que le service doit être démarré après la cible réseau. Cela n’implique pas forcément que le réseau soit pleinement opérationnel dans tous les scénarios, mais exprime un ordre de démarrage.Type=simpleconvient à un programme lancé au premier plan, qui ne se détache pas lui-même.ExecStart=indique le chemin exact de la commande à lancer.Restart=on-failuredemande un redémarrage si le programme se termine en erreur.RestartSec=5fixe un délai d’attente avant tentative de redémarrage.User=définit l’utilisateur d’exécution. Ici,rootest utilisé pour la démonstration, mais ce n’est pas toujours le meilleur choix en production.WorkingDirectory=définit le répertoire de travail.WantedBy=multi-user.targetpermet d’activer le service dans une cible classique de fonctionnement système multi-utilisateur.
Point important : utilisez toujours des chemins absolus dans les directives comme
ExecStart=. Évitez de supposer que lePATHinteractif de votre shell sera identique dans le contexte du service.Recharger la configuration systemd après création ou modification
Après avoir créé ou modifié un fichier d’unité, il faut demander à
systemdde relire sa configuration. Sinon, le gestionnaire peut continuer à utiliser l’ancienne version connue.Exécutez :
bashsudo systemctl daemon-reloadCette commande ne démarre pas le service. Elle recharge simplement les définitions d’unités. C’est une étape indispensable après chaque modification du fichier
.service.Vous pouvez ensuite vérifier que l’unité est bien connue :
bashsystemctl status mon-service.serviceSi le service n’a pas encore été lancé, il peut apparaître comme
inactive, ce qui est normal à ce stade. L’essentiel est que le nom d’unité soit reconnu et qu’aucune erreur de syntaxe bloquante n’empêche sa prise en compte.Démarrer et arrêter le service manuellement
Commençons par une gestion manuelle simple. Démarrez le service :
bashsudo systemctl start mon-service.serviceVérifiez immédiatement son état :
bashsystemctl status mon-service.serviceSi tout fonctionne, vous devriez voir un état de type
active (running). Cette commande affiche aussi plusieurs informations utiles : heure de démarrage, PID principal, extraits de journal récents, et parfois le code de sortie en cas d’échec.Pour arrêter le service :
bashsudo systemctl stop mon-service.servicePuis pour le redémarrer :
bashsudo systemctl restart mon-service.serviceEt pour relancer uniquement si déjà actif :
bashsudo systemctl try-restart mon-service.serviceCes opérations sont au cœur de l’administration quotidienne. La commande
statusest généralement votre premier réflexe en cas de doute.Vous pouvez aussi interroger uniquement l’état synthétique :
bashsystemctl is-active mon-service.serviceEt savoir si le service est prévu pour démarrer automatiquement :
bashsystemctl is-enabled mon-service.serviceActiver le service au démarrage du système
Un service peut être démarré manuellement sans être automatiquement lancé au prochain boot. Pour demander son activation permanente, utilisez :
bashsudo systemctl enable mon-service.serviceCette opération crée les liens nécessaires pour rattacher l’unité à la cible mentionnée dans
WantedBy=, icimulti-user.target.Si vous souhaitez à la fois l’activer et le démarrer immédiatement, vous pouvez utiliser :
bashsudo systemctl enable --now mon-service.servicePour vérifier l’activation :
bashsystemctl is-enabled mon-service.servicePour désactiver le démarrage automatique :
bashsudo systemctl disable mon-service.serviceRetenez bien la différence :
startagit sur l’exécution courante,enableagit sur le comportement au démarrage futur.
Un service peut donc être :
- démarré mais non activé,
- activé mais actuellement arrêté,
- activé et démarré,
- ni activé ni démarré.
Cette distinction évite beaucoup de malentendus lors de l’administration.
Lire les journaux avec journalctl pour diagnostiquer
L’un des grands avantages de
systemdest son intégration avec le journal système. Lorsqu’un service échoue, la commandejournalctldevient votre meilleur allié.Pour afficher les journaux du service :
bashjournalctl -u mon-service.servicePour voir uniquement les entrées récentes :
bashjournalctl -u mon-service.service -n 50Pour suivre les nouveaux messages en temps réel :
bashjournalctl -u mon-service.service -fPour limiter au démarrage courant de la machine :
bashjournalctl -u mon-service.service -bCes commandes sont très utiles pour repérer :
- un chemin incorrect dans
ExecStart=, - une permission manquante,
- un interpréteur absent,
- une variable d’environnement non définie,
- un code de retour applicatif en erreur.
Comme notre script écrit sur la sortie standard, ses messages sont visibles dans le journal. C’est très pratique pour les services simples. Pour des applications plus évoluées, il peut être pertinent de gérer explicitement les sorties standard et erreur, mais pour débuter, le comportement par défaut est souvent suffisant.
- un chemin incorrect dans
Comprendre les causes classiques d’échec d’un service
Quand un service refuse de démarrer, le problème provient souvent de quelques causes récurrentes. Les connaître permet de gagner un temps précieux.
1. Chemin invalide dans ExecStart
Si le binaire ou le script n’existe pas à l’emplacement indiqué, le service échouera immédiatement. Vérifiez :
bashls -l /opt/demo-systemd/mon-service.sh2. Fichier non exécutable
Un script présent mais sans droit d’exécution ne pourra pas être lancé :
bashchmod +x /opt/demo-systemd/mon-service.sh3. Shebang incorrect
La première ligne d’un script, par exemple
#!/bin/sh, doit pointer vers un interpréteur existant.4. Mauvais type de service
Un programme qui se lance au premier plan s’accommode souvent de
Type=simple. Si l’application se comporte différemment, le type choisi peut ne pas correspondre à sa logique. Dans un premier apprentissage, il est judicieux de commencer par un cas simple et non daemonisé manuellement.5. Problèmes de permissions
Le compte défini par
User=doit avoir accès au binaire, au répertoire de travail et aux éventuels fichiers utilisés.6. Oubli de daemon-reload
Après modification du fichier d’unité, oublier :
bashsudo systemctl daemon-reloadest une cause extrêmement fréquente d’incompréhension.
7. Environnement différent du shell interactif
Un service
systemdne s’exécute pas dans le même contexte que votre session shell. Une commande qui fonctionne à la main peut échouer en service si elle dépend d’un alias, d’une variable interactive ou d’un répertoire implicite.Tester une panne volontaire pour apprendre le diagnostic
Une très bonne manière de progresser consiste à provoquer une petite erreur contrôlée, puis à la diagnostiquer. Par exemple, modifiez temporairement la directive
ExecStart=avec un chemin faux :bashExecStart=/opt/demo-systemd/inexistant.shEnsuite, rechargez la configuration :
bashsudo systemctl daemon-reloadPuis tentez un redémarrage :
bashsudo systemctl restart mon-service.serviceConsultez l’état :
bashsystemctl status mon-service.servicePuis le journal :
bashjournalctl -u mon-service.service -n 20Vous verrez alors comment
systemdexpose les indices utiles. Cette pratique est excellente pour apprendre à lire les messages réels plutôt que de chercher immédiatement une solution générique sur internet.Remettez ensuite le bon chemin, rechargez à nouveau avec
daemon-reloadet redémarrez le service.Utiliser un utilisateur dédié plutôt que root
Dans un contexte réel, faire tourner un service applicatif en tant que
rootn’est pas toujours souhaitable. Une bonne pratique consiste à exécuter le processus avec un compte de service dédié, doté du minimum de privilèges nécessaires.Par exemple, vous pouvez créer un utilisateur système :
bashsudo useradd --system --no-create-home --shell /usr/sbin/nologin monservicePuis adapter les permissions du répertoire si besoin :
bashsudo chown -R monservice:monservice /opt/demo-systemdEnsuite, modifiez l’unité :
bash[Service] Type=simple ExecStart=/opt/demo-systemd/mon-service.sh Restart=on-failure RestartSec=5 User=monservice WorkingDirectory=/opt/demo-systemdRechargez puis redémarrez :
bashsudo systemctl daemon-reload sudo systemctl restart mon-service.serviceCette approche réduit l’impact potentiel d’un dysfonctionnement ou d’un comportement inattendu du programme. Elle s’inscrit dans le principe du moindre privilège.
Inspecter plus finement l’unité et ses propriétés
Au-delà de
status,systemctlpermet d’inspecter de nombreuses propriétés. Par exemple :bashsystemctl show mon-service.serviceLa sortie est très détaillée. Pour cibler quelques champs utiles :
bashsystemctl show mon-service.service -p ActiveState -p SubState -p ExecStart -p UserVous pouvez aussi afficher le contenu de l’unité tel qu’il est pris en compte :
bashsystemctl cat mon-service.serviceC’est très pratique pour confirmer la version actuellement chargée et repérer d’éventuels ajouts complémentaires si vous utilisez une configuration fragmentée.
Enfin, pour lister les services actifs :
bashsystemctl list-units --type=serviceEt pour lister les fichiers d’unités installés :
bashsystemctl list-unit-files --type=serviceCes vues aident à se repérer sur une machine où de nombreux services coexistent.
Modifier le service proprement au fil du temps
Dans la vie d’un serveur, un service évolue : nouvelle commande, nouveaux arguments, changement de répertoire, compte d’exécution différent, politique de redémarrage revue. La méthode correcte reste toujours la même :
- modifier le fichier d’unité,
- recharger la définition avec
daemon-reload, - redémarrer le service si nécessaire,
- contrôler l’état avec
status, - lire les journaux si un problème apparaît.
Exemple de séquence complète :
bashsudo nano /etc/systemd/system/mon-service.service sudo systemctl daemon-reload sudo systemctl restart mon-service.service systemctl status mon-service.service journalctl -u mon-service.service -n 30Cette discipline simple évite la majorité des erreurs de manipulation.
Désactiver, supprimer ou nettoyer un service
Si vous n’avez plus besoin du service, commencez par l’arrêter :
bashsudo systemctl stop mon-service.serviceDésactivez ensuite son lancement automatique :
bashsudo systemctl disable mon-service.serviceSupprimez le fichier d’unité si nécessaire :
bashsudo rm /etc/systemd/system/mon-service.servicePuis rechargez les définitions :
bashsudo systemctl daemon-reloadSelon le contexte, vous pouvez également supprimer le script associé :
bashsudo rm -f /opt/demo-systemd/mon-service.shCette procédure garantit que le service ne sera plus lancé automatiquement et que
systemdne tentera plus d’utiliser une définition obsolète.Résumé pratique des commandes essentielles
Voici un pense-bête des commandes les plus utiles vues dans ce tutoriel :
bashsudo systemctl daemon-reload sudo systemctl start mon-service.service sudo systemctl stop mon-service.service sudo systemctl restart mon-service.service systemctl status mon-service.service systemctl is-active mon-service.service sudo systemctl enable mon-service.service sudo systemctl enable --now mon-service.service sudo systemctl disable mon-service.service systemctl is-enabled mon-service.service journalctl -u mon-service.service journalctl -u mon-service.service -f systemctl show mon-service.service systemctl cat mon-service.serviceSi vous deviez retenir une méthode universelle de dépannage, ce serait :
- vérifier le fichier d’unité,
- faire
daemon-reload, - tenter un démarrage,
- lire
status, - compléter avec
journalctl.
Erreurs fréquentes & dépannage
- Oublier
daemon-reload: après toute modification d’un fichier.service, rechargez la configuration. - Utiliser un chemin relatif : dans
ExecStart=, préférez toujours un chemin absolu. - Confondre
startetenable: l’un agit maintenant, l’autre au démarrage futur. - Lancer un script non exécutable : vérifiez les permissions avec
chmod +x. - Ignorer le journal : beaucoup d’utilisateurs relancent plusieurs fois un service sans lire
journalctl, alors que la cause y est souvent clairement visible. - Exécuter inutilement en root : utilisez un utilisateur dédié quand cela est possible.
- Supposer que l’environnement est identique au terminal : un service ne bénéficie pas automatiquement de vos alias, variables ou habitudes de session interactive.
Astuces & pour aller plus loin
- Testez d’abord votre programme à la main avant de l’encapsuler dans
systemd. - Commencez simple avec
Type=simpleet un programme au premier plan. - Consultez toujours
statuspuisjournalctlavant de modifier plusieurs paramètres au hasard. - Conservez des chemins explicites pour les scripts, exécutables et répertoires.
- Ajoutez un
WorkingDirectory=si votre programme dépend du répertoire courant. - Utilisez
enable --nowpour gagner du temps lors d’un déploiement initial. - Apprenez à lire un échec contrôlé en introduisant volontairement une petite erreur dans un environnement de test.
Questions fréquentes
Quelle est la différence entre systemctl start et systemctl enable ?
La commande start lance le service immédiatement dans la session système en cours. La commande enable configure son démarrage automatique lors des prochains boots, sans forcément le lancer tout de suite.
Pourquoi mon service fonctionne en ligne de commande mais pas avec systemd ?
Le contexte d’exécution est souvent différent : utilisateur, permissions, répertoire courant, variables d’environnement, chemins implicites ou dépendances non disponibles. Vérifiez le fichier d’unité, puis consultez systemctl status et journalctl -u nom.service.
À quoi sert journalctl avec un service systemd ?
journalctl permet de consulter les messages liés au service, y compris sa sortie standard et ses erreurs dans de nombreux cas. C’est l’outil principal pour comprendre pourquoi un service démarre, redémarre ou échoue.
Dois-je toujours utiliser root pour un service ?
Non. Pour un service applicatif, il est souvent préférable d’utiliser un utilisateur dédié avec des droits limités. Cela réduit les risques et respecte le principe du moindre privilège.
Pourquoi faut-il lancer systemctl daemon-reload ?
Parce que systemd doit relire les fichiers d’unité après leur création ou leur modification. Sans cela, vos changements peuvent ne pas être pris en compte.
Où placer mon fichier .service ?
Pour un service local administré sur la machine, l’emplacement couramment utilisé est /etc/systemd/system/. C’est là que vous pouvez créer vos propres unités de service.
Conclusion
Vous savez maintenant prendre en main systemd pour administrer un service Linux de bout en bout : création du fichier d’unité, rechargement de la configuration, démarrage manuel, activation au boot et diagnostic des erreurs avec systemctl et journalctl.
La compétence la plus importante n’est pas seulement de mémoriser quelques commandes, mais de comprendre la méthode : définir proprement l’unité, tester, observer l’état, lire le journal et corriger itérativement. Avec cette approche, vous pourrez gérer non seulement un script shell simple, mais aussi des applications plus réelles déployées sur un serveur Linux.
Une fois à l’aise avec ces bases, vous pourrez aller plus loin en explorant d’autres types d’unités comme les .timer, les services liés à des sockets, ou encore des options plus avancées d’isolation et de supervision offertes par systemd.