Créer un service systemd sous Linux pour automatiser une tâche

Créer un service systemd sous Linux pour automatiser une tâche
Pour créer un service systemd, créez un fichier .service dans /etc/systemd/system/, définissez la commande à lancer avec ExecStart=, rechargez la configuration avec systemctl daemon-reload, puis activez et démarrez le service avec systemctl enable et systemctl start. Cette procédure convient à un script, une application ou un processus qui doit rester actif.
Un fichier service systemd permet de lancer une tâche dans un environnement contrôlé, de suivre son état et de consulter ses journaux. Le tutoriel ci-dessous part d’un script simple, montre les commandes à exécuter dans l’ordre, puis explique comment diagnostiquer un échec sans faire tourner votre application avec les droits administrateur.
Sommaire
En bref
🧩 Un service systemd est une unité qui décrit comment démarrer, arrêter et superviser un programme sous Linux.
📄 Le fichier personnalisé se place généralement dans /etc/systemd/system/ et comporte les sections [Unit], [Service] et [Install].
⚙️ Après chaque modification, lancez systemctl daemon-reload, puis vérifiez le résultat avec systemctl status et journalctl -u.
Qu’est-ce qu’un service systemd et où placer son fichier ?
Un service systemd est une unité de type .service qui indique à systemd quelle commande lancer, sous quel utilisateur, dans quel ordre et selon quelle politique de redémarrage. Systemd est le système d’initialisation et le gestionnaire de services par défaut de nombreuses distributions Linux modernes, mais la disponibilité exacte de certaines directives dépend de sa version.
Les fichiers d’unités fournis par les paquets sont habituellement stockés dans /usr/lib/systemd/system/ ou dans un répertoire équivalent selon la distribution. Un service créé par l’administrateur doit être placé dans /etc/systemd/system/, afin de ne pas être écrasé par une mise à jour de paquet. La documentation officielle de systemd.unit détaille l’ordre de recherche des unités.
/etc/systemd/system/: unités locales créées ou remplacées par l’administrateur ;/usr/lib/systemd/system/: unités installées par les logiciels, selon la distribution ;~/.config/systemd/user/: unités lancées pour un utilisateur, sans service système global.
Un fichier
.servicene lance pas un programme « par magie » : la commande, le chemin, les droits et les dépendances doivent déjà être cohérents hors de systemd.
Préparer le script ou l’application avant de créer une unité systemd
La préparation consiste à exécuter la commande manuellement avec le même utilisateur que celui prévu dans le service. Cette vérification isole les erreurs de script, de dépendance ou de permission avant d’ajouter la couche systemd. Un service systemd Linux ne corrige ni un chemin erroné ni un programme qui s’arrête immédiatement.

Créez par exemple un petit script de démonstration dans /opt/sauvegarde/. Le script ci-dessous ajoute une ligne horodatée à un fichier de journal ; son usage est volontairement simple pour rendre le mécanisme observable.
#!/bin/sh
date '+%Y-%m-%d %H:%M:%S : tâche exécutée' >> /var/log/sauvegarde-demo.log
Enregistrez ce fichier sous /opt/sauvegarde/tache.sh, puis rendez-le exécutable et testez-le. Le test manuel doit produire le résultat attendu avant la création du fichier service systemd. Adaptez le chemin de journal si l’utilisateur retenu n’a pas le droit d’écrire dans /var/log/.
sudo chmod 755 /opt/sauvegarde/tache.sh
sudo /opt/sauvegarde/tache.sh
Pour un script applicatif, évitez les chemins relatifs comme ./programme ou logs/app.log. Utilisez des chemins absolus et définissez éventuellement WorkingDirectory=. Une installation de distribution différente, par exemple après avoir choisi une distribution Linux adaptée, peut modifier l’emplacement d’un interpréteur, d’un binaire ou d’un fichier de configuration.
Comment créer un service systemd : les étapes à suivre
Pour créer une unité systemd exploitable, écrivez un fichier .service, rechargez le gestionnaire, lancez le service et contrôlez immédiatement son état. Les quatre étapes suivantes utilisent un exemple de tâche ponctuelle nommée sauvegarde-demo.service. Le principe reste identique pour lancer une application Python, Node.js, Java ou un binaire compilé.

Étape 1 : créer le fichier .service
Ouvrez un éditeur avec des droits administrateur et créez /etc/systemd/system/sauvegarde-demo.service. Le nom du fichier devient le nom de l’unité : sauvegarde-demo.service. Employez un nom court, sans espace, qui décrit la tâche plutôt que le serveur entier.
sudoedit /etc/systemd/system/sauvegarde-demo.service
Ajoutez ensuite la configuration suivante. La directive ExecStart= est le point central : elle doit contenir la commande absolue à exécuter.
[Unit]
Description=Tâche de démonstration exécutée une fois
[Service]
Type=oneshot
ExecStart=/opt/sauvegarde/tache.sh
[Install]
WantedBy=multi-user.target
La section [Unit] décrit l’unité et son ordre de démarrage. La section [Service] décrit l’exécution. La section [Install] définit le rattachement créé par enable ; ici, multi-user.target correspond à un mode système multiutilisateur courant. Les directives sont documentées dans les pages officielles systemd.service et systemd.unit.
Étape 2 : recharger la configuration de systemd
Systemd ne lit pas automatiquement un fichier que vous venez de créer ou de modifier. Rechargez sa configuration avant toute tentative de démarrage. Cette commande ne démarre pas le service ; elle met seulement à jour la liste et la définition des unités connues.
sudo systemctl daemon-reload
Vérifiez aussi la syntaxe de l’unité avant de poursuivre. La commande suivante signale les problèmes de structure qu’elle peut détecter, mais elle ne remplace pas un test réel de la commande définie par ExecStart=.
sudo systemd-analyze verify /etc/systemd/system/sauvegarde-demo.service
Étape 3 : démarrer le service immédiatement
Démarrez l’unité avec systemctl start. Pour un service Type=oneshot, le processus se termine après l’exécution du script ; un statut inactif après réussite peut donc être normal si vous n’avez pas défini RemainAfterExit=yes.
sudo systemctl start sauvegarde-demo.service
sudo systemctl status sauvegarde-demo.service
La commande status indique notamment si systemd a réussi à lancer le processus et le code de sortie associé. Consultez le fichier de journal produit par le script seulement après avoir vérifié l’état systemd : un fichier absent peut révéler une erreur de droit ou de chemin plutôt qu’un problème du journal lui-même.
Étape 4 : activer le lancement au démarrage
Activez le service si la tâche doit être disponible au démarrage de Linux. L’activation et le démarrage sont deux opérations distinctes : enable prépare le lancement futur, tandis que start lance l’unité maintenant.
sudo systemctl enable sauvegarde-demo.service
La forme suivante active l’unité et la démarre dans la même commande. Utilisez-la lorsque le fichier vient d’être validé et que le lancement immédiat est souhaité.
sudo systemctl enable --now sauvegarde-demo.service
Quels types de service systemd choisir selon la tâche ?
Le type de service définit ce que systemd considère comme un démarrage réussi et le moment où il poursuit les unités dépendantes. Pour un programme qui reste au premier plan, choisissez généralement Type=simple. Pour une commande qui se termine, choisissez Type=oneshot. Les types forking, notify et dbus répondent à des mécanismes plus spécifiques.
| Type | Comportement | Cas d’usage pertinent | Point de vigilance |
|---|---|---|---|
simple |
Type par défaut ; le processus principal est lancé directement. | Application qui reste au premier plan. | Ne faites pas passer l’application en arrière-plan elle-même. |
oneshot |
Systemd attend la fin de la commande. | Initialisation, script unique, action ponctuelle. | Ajoutez RemainAfterExit=yes seulement si l’état actif après sortie a un sens. |
forking |
Le processus parent se termine après avoir détaché un fils. | Ancien démon Unix qui se détache lui-même. | Évitez-le si le programme sait rester au premier plan. |
notify |
Le programme signale explicitement qu’il est prêt. | Application compatible avec le protocole de notification systemd. | Le logiciel doit réellement envoyer cette notification. |
Un script de maintenance ne devient pas plus fiable parce qu’il est déclaré en Type=simple. Le type doit décrire le comportement réel du processus, pas l’effet souhaité. Les détails de chaque type sont disponibles dans la documentation de Type= dans systemd.service.
Gérer un service systemd après son installation
Un service installé se pilote avec systemctl. Les commandes ci-dessous séparent volontairement les actions : cette distinction évite de croire qu’un service activé est déjà en cours d’exécution, ou qu’un service arrêté ne redémarrera plus lors du prochain démarrage.
sudo systemctl start nom.service: lance le service immédiatement ;sudo systemctl stop nom.service: demande son arrêt ;sudo systemctl restart nom.service: l’arrête puis le relance ;sudo systemctl enable nom.service: active le démarrage automatique ;sudo systemctl disable nom.service: retire cette activation ;sudo systemctl is-enabled nom.service: vérifie si l’unité est activée.
Après toute modification du fichier .service, exécutez daemon-reload avant restart. Un redémarrage sans rechargement utilise potentiellement l’ancienne définition déjà connue par systemd. La même logique s’applique lorsqu’une application de messagerie ou un composant de serveur doit rester disponible, à condition d’avoir d’abord vérifié ses propres paramètres, comme dans ce guide pour configurer une messagerie web.
Comment diagnostiquer un service systemd qui échoue ?
Un service systemd qui échoue se diagnostique dans cet ordre : vérifier le statut, lire les journaux associés, tester la commande hors de systemd, puis contrôler le fichier d’unité. Cette séquence sépare les erreurs de syntaxe, les permissions insuffisantes, les dépendances manquantes et les sorties applicatives non nulles.
Commencez par ces deux commandes. La première donne un résumé récent et le code d’échec ; la seconde affiche les entrées du journal liées à l’unité. Ajoutez -e pour atteindre directement les messages les plus récents.
sudo systemctl status sauvegarde-demo.service
sudo journalctl -u sauvegarde-demo.service -e
Le journal est une preuve de diagnostic ; le statut « failed » est un constat, pas l’explication de la panne.
Si le journal mentionne Permission denied, examinez l’utilisateur du service, le droit d’exécution du script et les répertoires parcourus. Si le journal indique No such file or directory, contrôlez le chemin absolu dans ExecStart=, y compris celui de l’interpréteur comme /bin/sh ou /usr/bin/python3.
Erreurs fréquentes lors de la création d’un service Linux
Les erreurs ci-dessous reviennent souvent parce qu’un service s’exécute dans un contexte plus réduit qu’un terminal interactif. Un shell personnel charge parfois des variables, des alias ou un répertoire courant qui n’existent pas dans l’environnement de systemd.
- Oublier
systemctl daemon-reload. Systemd ne connaît pas encore la nouvelle version du fichier. Rechargez le gestionnaire après chaque modification. - Utiliser une commande relative.
ExecStart=python script.pydépend d’un environnement implicite. Préférez le chemin complet de l’interpréteur et du script. - Lancer l’application avec root par défaut. Le compte administrateur augmente la portée d’une erreur applicative. Définissez
User=etGroup=lorsque le programme n’a pas besoin de privilèges élevés. - Choisir
Type=forkingpour un programme qui ne se détache pas. Systemd peut attendre un comportement qui ne se produit jamais. Utilisez souventsimplepour un processus au premier plan. - Confondre activation et planification.
enablelance une unité au démarrage, mais n’exécute pas automatiquement une tâche chaque jour ou chaque heure.
Timer systemd, cron et service utilisateur : quelle alternative choisir ?
Un service système convient à un processus permanent ou à une action liée au démarrage de la machine. Un timer systemd lance un service associé à une date ou à un intervalle défini. Cron reste une solution de planification répandue, tandis qu’un service utilisateur évite les droits administrateur pour un programme limité à une session ou à un compte précis.
| Option | Usage adapté | Avantage concret | Limite principale |
|---|---|---|---|
| Service système | Application ou démon lancé au démarrage. | État et journaux centralisés via systemd. | Demande des droits administrateur pour l’installation globale. |
| Timer systemd | Tâche périodique associée à un service oneshot. |
La tâche conserve les journaux et l’état de son service. | Deux unités, .timer et .service, sont à maintenir. |
| Cron | Planification simple déjà centralisée dans une crontab existante. | Format connu sur de nombreux systèmes Unix. | Le suivi applicatif doit être organisé séparément. |
| Service utilisateur | Outil propre à un compte non administrateur. | Réduit le périmètre de privilèges. | Le comportement hors session dépend de la configuration du compte. |
Un timer porte le même nom de base que le service qu’il déclenche. Pour exécuter chaque nuit le service sauvegarde-demo.service, créez donc /etc/systemd/system/sauvegarde-demo.timer. Le calendrier doit être adapté à votre besoin et validé avec la documentation officielle de systemd.timer.
[Unit]
Description=Exécute la tâche de démonstration chaque nuit
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target
Activez ensuite le timer, et non le service seul. Le fichier .timer planifie ; le fichier .service définit l’action réellement exécutée.
sudo systemctl daemon-reload
sudo systemctl enable --now sauvegarde-demo.timer
systemctl list-timers
Rendre le service plus robuste et moins privilégié
Un service robuste ne repose pas uniquement sur Restart=. Le redémarrage automatique traite certains échecs, mais il peut masquer une configuration défectueuse et provoquer des tentatives répétées. Corrigez d’abord la cause visible dans les journaux, puis ajoutez une stratégie de reprise cohérente.
Pour une application durable, les directives suivantes offrent une base prudente. Les options disponibles et leurs effets précis doivent être vérifiés dans la version de systemd de votre distribution, notamment dans la documentation de systemd.exec.
[Unit]
Description=Application exemple
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=monapp
Group=monapp
WorkingDirectory=/opt/monapp
ExecStart=/usr/local/bin/monapp
Restart=on-failure
RestartSec=5
PrivateTmp=true
NoNewPrivileges=true
MemoryMax=512M
[Install]
WantedBy=multi-user.target
User=etGroup=limitent l’exécution à un compte dédié ;After=network-online.targetordonne le démarrage après la disponibilité réseau, sans garantir à elle seule que le service distant répond ;Restart=on-failuredemande un redémarrage après un échec ;PrivateTmp=trueisole le répertoire temporaire du service ;NoNewPrivileges=trueempêche le processus et ses descendants d’acquérir de nouveaux privilèges ;MemoryMax=512Mfixe ici une limite de mémoire de 512 MiB, à ajuster après mesure réelle.
La valeur 512M dans cet exemple n’est pas une recommandation universelle. Mesurez la consommation de l’application, tenez compte des pointes de charge et contrôlez les effets avant de limiter une production. Les options de durcissement réduisent certains risques ; elles ne remplacent ni les mises à jour ni une configuration applicative correcte.
Modifier, désactiver ou supprimer proprement une unité
Pour modifier un fichier local placé dans /etc/systemd/system/, éditez-le, rechargez systemd puis redémarrez l’unité. Pour modifier une unité fournie par un paquet, privilégiez un fichier de surcharge créé avec systemctl edit nom.service : cette méthode évite d’éditer un fichier susceptible d’être remplacé lors d’une mise à jour.
Pour retirer un service local, arrêtez-le et désactivez-le avant de supprimer le fichier. Supprimer le fichier sans désactiver l’unité laisse une configuration de démarrage incohérente jusqu’au prochain rechargement.
sudo systemctl disable --now sauvegarde-demo.service
sudo rm /etc/systemd/system/sauvegarde-demo.service
sudo systemctl daemon-reload
Supprimez également le fichier .timer et désactivez-le si vous aviez planifié la tâche. Vérifiez enfin l’absence de l’unité avec systemctl status sauvegarde-demo.service : systemd doit indiquer qu’aucune unité n’a été trouvée.
Sources utiles à consulter
| Source | Information utile | Usage concret |
|---|---|---|
| Documentation systemd.service | Directives d’unité de type service et comportements de Type=. |
Vérifier ExecStart=, Restart= et le type choisi. |
| Documentation systemctl | Commandes de gestion des unités. | Contrôler les effets de start, enable, disable et status. |
| Documentation journalctl | Consultation et filtrage des journaux systemd. | Lire les messages liés à une unité avec journalctl -u. |
| Documentation systemd.timer | Définition des timers et des calendriers. | Planifier une tâche sans confondre le timer et le service exécuté. |
À retenir
- 🧩 Un fichier
.servicepersonnalisé se place généralement dans/etc/systemd/system/. - ⚙️ Rechargez toujours systemd après une création ou une modification d’unité.
- 🔍 Utilisez
statusetjournalctl -uavant de modifier la configuration. - 🔒 Préférez un utilisateur dédié aux droits administrateur pour une application ordinaire.
- ⏱️ Choisissez un timer pour une tâche planifiée, pas simplement
enable.
Questions fréquentes sur les services systemd
Comment lancer un script au démarrage de Linux ?
Créez un fichier .service qui pointe vers le script avec ExecStart=, puis ajoutez une section [Install] avec WantedBy=multi-user.target. Rechargez systemd et lancez sudo systemctl enable nom.service pour activer le démarrage automatique.
Quelle différence entre systemctl start et systemctl enable ?
systemctl start démarre un service immédiatement pour la session en cours. systemctl enable configure son lancement lors d’un prochain démarrage, sans le lancer tout de suite sauf avec l’option --now.
Pourquoi un service systemd affiche-t-il failed ?
Le statut failed signifie que la commande du service ou sa préparation a échoué. Exécutez systemctl status nom.service, puis journalctl -u nom.service -e pour identifier une erreur de chemin, de droit, de dépendance ou de programme.
Peut-on créer un service systemd sans droits administrateur ?
Un service utilisateur peut être créé dans ~/.config/systemd/user/ et contrôlé avec systemctl --user. Ce mode convient à un programme lié à un compte, mais il ne remplace pas un service système qui doit démarrer pour toute la machine.
Faut-il utiliser cron ou un timer systemd pour une tâche récurrente ?
Un timer systemd convient si vous souhaitez associer la planification à une unité et consulter ses journaux via systemd. Cron reste adapté lorsqu’une planification existante est déjà gérée par crontab ; le bon choix dépend surtout de l’environnement à maintenir.