Aller au contenu
Administration Linux medium

Comprendre systemd

20 min de lecture

systemctl vous permet de contrôler les services Linux depuis le terminal. En 5 commandes, vous saurez démarrer Nginx, l'activer au boot et comprendre pourquoi un service refuse de démarrer. Ce guide vous accompagne du premier systemctl status jusqu'à la création de vos propres services.

Niveau : Débutant · Durée : 20 minutes · Prérequis : accès root ou sudo

À la fin de ce guide, vous saurez :

  • Démarrer, arrêter et redémarrer un service
  • Activer un service au boot (et comprendre la différence avec "démarrer")
  • Diagnostiquer pourquoi un service ne démarre pas
  • Créer un service personnalisé pour votre application
  • Sécuriser un service avec les directives de hardening
Fenêtre de terminal
# 1. État complet d'un service (le "status" détaillé)
sudo systemctl status nginx --no-pager -l
# 2. Démarrer / Arrêter / Redémarrer
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# 3. Activer au boot (≠ démarrer maintenant !)
sudo systemctl enable nginx
sudo systemctl enable --now nginx # enable + start en une commande
# 4. Voir les logs d'un service
journalctl -xeu nginx
# 5. Vérifier si un service tourne / est activé au boot
systemctl is-active nginx
systemctl is-enabled nginx

Avant d'aller plus loin, clarifions 5 termes qui créent 90% de la confusion :

TermeDéfinitionCommande associée
UnitObjet géré par systemd (service, timer, socket, mount...)systemctl list-units
ServiceType d'unité .service — un processus qui tournesystemctl status nginx.service
ActiveLe service tourne maintenantsystemctl is-active nginx
EnabledLe service démarrera au bootsystemctl is-enabled nginx
Drop-inPetit fichier override sans toucher au fichier vendorsystemctl edit nginx

systemd distingue deux notions d'état — c'est la source #1 de confusion pour les débutants :

Les deux états systemd : runtime (is-active) et activation (is-enabled)

État runtime (le service tourne-t-il maintenant ?)

ÉtatSignification
active (running)Le processus tourne
active (exited)Le service s'est exécuté et terminé (normal pour certains oneshot)
inactiveLe service est arrêté
failedLe service a crashé ou n'a pas pu démarrer

État d'activation (démarre-t-il au boot ?)

ÉtatSignification
enabledDémarre automatiquement au boot
disabledNe démarre pas au boot
staticPas de section [Install] — ne peut pas être enable directement
maskedDésactivé de force — impossible à démarrer même manuellement

Scénario 1 : Démarrer, arrêter, redémarrer un service

Section intitulée « Scénario 1 : Démarrer, arrêter, redémarrer un service »
Fenêtre de terminal
sudo systemctl start nginx

Vérifiez qu'il tourne :

Fenêtre de terminal
systemctl is-active nginx
# active
Fenêtre de terminal
sudo systemctl stop nginx

Restart arrête puis redémarre le service (coupure de connexions) :

Fenêtre de terminal
sudo systemctl restart nginx

Reload recharge la configuration sans couper les connexions (si le service le supporte) :

Fenêtre de terminal
sudo systemctl reload nginx
Fenêtre de terminal
# Reload si possible, sinon restart — mais seulement si le service tourne déjà
sudo systemctl try-reload-or-restart nginx

Cette commande ne fait rien si le service est arrêté (évite de démarrer par accident un service désactivé).

Fenêtre de terminal
sudo systemctl enable nginx

Le service démarrera au prochain boot, mais ne démarre pas maintenant.

Fenêtre de terminal
sudo systemctl enable --now nginx
Fenêtre de terminal
sudo systemctl disable nginx # ne démarre plus au boot
sudo systemctl disable --now nginx # désactive ET arrête
Fenêtre de terminal
sudo systemctl mask nginx # impossible à démarrer, même manuellement
sudo systemctl unmask nginx # annule le mask

mask est utile pour s'assurer qu'un service dangereux ou obsolète ne puisse jamais être démarré par erreur.

Scénario 3 : Comprendre pourquoi ça ne démarre pas

Section intitulée « Scénario 3 : Comprendre pourquoi ça ne démarre pas »

Quand un service refuse de démarrer, suivez ce workflow de dépannage :

Workflow de dépannage systemd : status → journalctl → cat → show

  1. Voir l'état complet

    Fenêtre de terminal
    sudo systemctl status nginx --no-pager -l

    L'option --no-pager -l évite la troncature et affiche tout.

  2. Consulter les logs avec contexte

    Fenêtre de terminal
    journalctl -xeu nginx
    • -x : ajoute des explications
    • -e : va à la fin des logs
    • -u nginx : filtre sur l'unité nginx
  3. Voir le fichier unit et ses overrides

    Fenêtre de terminal
    systemctl cat nginx

    Cette commande affiche le fichier complet avec les drop-ins appliqués.

  4. Inspecter les propriétés clés

    Fenêtre de terminal
    systemctl show nginx -p ExecStart -p FragmentPath -p DropInPaths

    Vous verrez exactement quel fichier est utilisé et quelle commande est exécutée.

Fenêtre de terminal
# Logs du boot actuel
journalctl -u nginx -b
# Logs des dernières 30 minutes
journalctl -u nginx --since "30 min ago"
# Logs entre deux timestamps
journalctl -u nginx --since "2026-01-29 10:00" --until "2026-01-29 11:00"
# Uniquement les erreurs
journalctl -u nginx -p err

Vous avez un script Python ou une application que vous voulez lancer au boot ? Créez un fichier .service.

  1. Créer le fichier unit

    Fenêtre de terminal
    sudo systemctl edit --full --force mon-app.service

    Ou créez directement dans /etc/systemd/system/mon-app.service :

    Structure d'un fichier .service : sections Unit, Service et Install

    [Unit]
    Description=Mon application Python
    After=network.target
    [Service]
    Type=simple
    User=www-data
    Group=www-data
    WorkingDirectory=/opt/mon-app
    ExecStart=/opt/mon-app/venv/bin/python app.py
    Restart=on-failure
    RestartSec=5s
    [Install]
    WantedBy=multi-user.target
  2. Recharger la configuration systemd

    Fenêtre de terminal
    sudo systemctl daemon-reload

    Obligatoire après toute modification de fichier unit.

  3. Activer et démarrer

    Fenêtre de terminal
    sudo systemctl enable --now mon-app
  4. Vérifier

    Fenêtre de terminal
    systemctl status mon-app
    journalctl -u mon-app -f # suivre les logs en temps réel
DirectiveSectionDescription
Description=[Unit]Description lisible du service
After=[Unit]Démarrer après ces unités
Requires=[Unit]Dépendance forte (si l'autre échoue, celui-ci aussi)
Wants=[Unit]Dépendance faible (on essaie de démarrer l'autre)
Type=[Service]simple, forking, oneshot, notify
ExecStart=[Service]Commande de démarrage
ExecReload=[Service]Commande de reload (optionnel)
Restart=[Service]no, on-failure, always
RestartSec=[Service]Délai avant restart
User= / Group=[Service]Utilisateur d'exécution
WantedBy=[Install]Target qui "tire" ce service

Modifier un service existant (sans toucher au vendor)

Section intitulée « Modifier un service existant (sans toucher au vendor) »

Ne modifiez jamais les fichiers dans /usr/lib/systemd/system/ — ils seront écrasés à la prochaine mise à jour du paquet.

Utilisez plutôt les drop-ins :

Fenêtre de terminal
sudo systemctl edit nginx

Cela crée /etc/systemd/system/nginx.service.d/override.conf. Ajoutez uniquement ce que vous voulez changer :

[Service]
# Augmenter le nombre de fichiers ouverts
LimitNOFILE=65535

Puis rechargez :

Fenêtre de terminal
sudo systemctl daemon-reload
sudo systemctl restart nginx

Les chemins varient selon les distributions (Debian vs RHEL vs Arch), mais la règle d'or est de ne pas apprendre par chemin :

Fenêtre de terminal
# Voir le chemin exact d'une unité
systemctl cat nginx | head -1
# Ou avec show
systemctl show nginx -p FragmentPath
EmplacementUsage
/usr/lib/systemd/system/Units fournies par les paquets (ne pas modifier)
/lib/systemd/system/Idem (lié à /usr/lib sur certaines distros)
/etc/systemd/system/Vos units personnalisées et overrides
/run/systemd/system/Units runtime (temporaires)

Priorité : /etc/ > /run/ > /usr/lib/

Les timers (.timer) sont l'alternative moderne à cron. Avantages : logs centralisés, dépendances, pas de chevauchement.

Créez /etc/systemd/system/cleanup.service :

[Unit]
Description=Nettoyage des fichiers temporaires
[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh

Puis /etc/systemd/system/cleanup.timer :

[Unit]
Description=Lance le nettoyage tous les jours à 3h
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
[Install]
WantedBy=timers.target

Activez le timer (pas le service) :

Fenêtre de terminal
sudo systemctl enable --now cleanup.timer

Vérifiez les timers actifs :

Fenêtre de terminal
systemctl list-timers

systemd offre des directives de sandboxing puissantes. Voici un exemple de service durci :

[Service]
# Utilisateur non-root
User=mon-app
DynamicUser=yes
# Isolation filesystem
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ReadWritePaths=/var/lib/mon-app
# Isolation réseau et capabilities
NoNewPrivileges=yes
CapabilityBoundingSet=
RestrictAddressFamilies=AF_INET AF_INET6
# Restrictions système
ProtectKernelModules=yes
ProtectKernelTunables=yes
ProtectControlGroups=yes
Fenêtre de terminal
systemd-analyze security nginx

Cette commande donne un score de 0 à 10 (10 = le plus exposé) et suggère des améliorations :

→ Overall exposure level for nginx.service: 9.2 UNSAFE 😨
NAME DESCRIPTION EXPOSURE
✓ PrivateNetwork= Service has access to the host's network 0.5
✗ User=/DynamicUser= Service runs as root 0.4
✗ CapabilityBoundingSet=~CAP_... Service has dangerous capabilities 0.3
...

Appliquez les recommandations une par une et re-testez.

Ces commandes couvrent l'essentiel de l'administration quotidienne d'un service. Gardez-les sous la main : elles répondent à 90 % des besoins courants.

Voir si le service tourne, ses logs récents et son PID en un coup d'œil.

Fenêtre de terminal
sudo systemctl status SERVICE --no-pager -l
# Exemple
sudo systemctl status nginx --no-pager -l

SERVICE est le nom du service, avec ou sans le suffixe .service.

Activer au boot et démarrer immédiatement, en une seule commande.

Fenêtre de terminal
sudo systemctl enable --now SERVICE
# Exemple
sudo systemctl enable --now nginx

Recharger la configuration si le service le supporte, sinon le redémarrer.

Fenêtre de terminal
sudo systemctl reload-or-restart SERVICE
# Exemple
sudo systemctl reload-or-restart nginx

Afficher le fichier unit avec tous les drop-ins appliqués — la vraie configuration effective.

Fenêtre de terminal
systemctl cat SERVICE
# Exemple
systemctl cat nginx

Modifier un service sans toucher au fichier vendor, qui serait écrasé à la prochaine mise à jour.

Fenêtre de terminal
sudo systemctl edit SERVICE
# Exemple
sudo systemctl edit nginx

Voir les logs avec contexte et explications, pour comprendre un échec.

Fenêtre de terminal
journalctl -xeu SERVICE
# Exemple
journalctl -xeu nginx

L'équivalent de tail -f pour les logs systemd.

Fenêtre de terminal
journalctl -u SERVICE -f
# Exemple
journalctl -u nginx -f

Repérer immédiatement ce qui ne va pas sur le système.

Fenêtre de terminal
systemctl list-units --failed

Obligatoire après toute modification d'un fichier unit.

Fenêtre de terminal
sudo systemctl daemon-reload

Obtenir un score de sécurité et des recommandations concrètes.

Fenêtre de terminal
systemd-analyze security SERVICE
# Exemple
systemd-analyze security nginx

Identifier les services qui ralentissent le démarrage du système.

Fenêtre de terminal
systemd-analyze blame | head -10

Empêcher un service de démarrer, même manuellement.

Fenêtre de terminal
sudo systemctl mask SERVICE
# Exemple
sudo systemctl mask cups

Pour débloquer ensuite : sudo systemctl unmask SERVICE.

Ces erreurs reviennent constamment chez les débutants comme chez les opérateurs pressés. Les connaître évite des services qui « ne démarrent pas » sans raison apparente.

Fenêtre de terminal
sudo systemctl enable nginx

Symptôme : le service n'est toujours pas démarré après la commande.

Cause : enable configure le démarrage au boot, mais ne démarre rien maintenant.

Fenêtre de terminal
sudo systemctl enable --now nginx

Vous modifiez /etc/systemd/system/mon-app.service puis lancez directement un restart.

Symptôme : les modifications ne sont pas prises en compte.

Cause : systemd garde la configuration en cache — il faut explicitement la recharger.

Fenêtre de terminal
sudo systemctl daemon-reload && sudo systemctl restart mon-app
Fenêtre de terminal
sudo vim /usr/lib/systemd/system/nginx.service

Symptôme : les modifications disparaissent à la prochaine mise à jour du paquet.

Cause : les fichiers vendor sont écrasés par les mises à jour. Il faut passer par un drop-in.

Fenêtre de terminal
sudo systemctl edit nginx
Fenêtre de terminal
sudo systemctl reload mon-app

Symptôme : erreur Job failed, ou service qui n'applique pas la nouvelle configuration.

Cause : tous les services ne réagissent pas au signal de reload.

Fenêtre de terminal
sudo systemctl reload-or-restart mon-app
WorkingDirectory=/opt/mon-app

Symptôme : service en failed avec No such file or directory.

Cause : le dossier n'existe pas, ou n'est pas accessible par l'utilisateur d'exécution. Vérifiez que le dossier existe et porte les bonnes permissions avant de démarrer le service.

ExecStart=./app.py

Symptôme : service en failed avec Executable path is not absolute.

Cause : systemd exige des chemins absolus dans ExecStart.

ExecStart=/opt/mon-app/venv/bin/python /opt/mon-app/app.py

Vous créez un service sans directive WantedBy=.

Symptôme : systemctl enable retourne static — l'activation ne fait rien.

Cause : sans section [Install], systemd ne sait pas à quel moment du boot accrocher le service. Ajoutez une section [Install] avec WantedBy=multi-user.target.

Au-delà des services : les autres types d'unités

Section intitulée « Au-delà des services : les autres types d'unités »

systemd gère bien plus que des services. Voici les types d'unités les plus utiles :

TypeExtensionUsage
Service.serviceProcessus en arrière-plan
Timer.timerTâches planifiées (remplace cron)
Socket.socketActivation à la demande (le service démarre quand quelqu'un se connecte)
Mount.mountPoints de montage
Target.targetGroupes d'unités (comme multi-user.target)
Path.pathSurveillance de fichiers/dossiers

Lister toutes les unités d'un type :

Fenêtre de terminal
systemctl list-units --type=timer
systemctl list-units --type=socket

Analyser le temps de démarrage :

Fenêtre de terminal
# Temps total
systemd-analyze
# Services les plus lents
systemd-analyze blame | head -15
# Graphe des dépendances
systemd-analyze plot > boot.svg

enable ≠ start : enable configure le boot, start démarre maintenant. Utilisez enable --now pour les deux.

Ne modifiez jamais /usr/lib/ : utilisez systemctl edit pour créer des drop-ins propres.

daemon-reload obligatoire : après toute modification de fichier unit.

reload-or-restart : la commande robuste qui marche toujours.

Workflow de debug : status --no-pager -ljournalctl -xeusystemctl catsystemctl show.

Sécurité mesurable : systemd-analyze security donne un score et des recommandations.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn