Aller au contenu
Administration Linux medium

systemd et systemctl : gérer les services Linux

15 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 recettes couvrent les cas d'usage les plus fréquents. Cliquez sur un pattern pour voir la formule complète et un exemple prêt à copier.

État complet d'un service Base

Voir si le service tourne, ses logs récents et son PID

sudo systemctl status nginx --no-pager -l
Formule sudo systemctl status SERVICE --no-pager -l
Exemple
sudo systemctl status nginx --no-pager -l
Paramètres
  • SERVICE — Nom du service (avec ou sans .service)
Activer ET démarrer Base

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

sudo systemctl enable --now nginx
Formule sudo systemctl enable --now SERVICE
Exemple
sudo systemctl enable --now nginx
Reload ou restart (robuste) Base

Recharger la config si possible, sinon redémarrer

sudo systemctl reload-or-restart nginx
Formule sudo systemctl reload-or-restart SERVICE
Exemple
sudo systemctl reload-or-restart nginx
Voir le fichier unit complet Base

Afficher le fichier unit avec tous les drop-ins appliqués

systemctl cat nginx
Formule systemctl cat SERVICE
Exemple
systemctl cat nginx
Override propre (drop-in) Base

Modifier un service sans toucher au fichier vendor

sudo systemctl edit nginx
Formule sudo systemctl edit SERVICE
Exemple
sudo systemctl edit nginx
Logs d'un service Base

Voir les logs avec contexte et explications

journalctl -xeu nginx
Formule journalctl -xeu SERVICE
Exemple
journalctl -xeu nginx
Suivre les logs en temps réel Base

Équivalent de tail -f pour les logs systemd

journalctl -u nginx -f
Formule journalctl -u SERVICE -f
Exemple
journalctl -u nginx -f
Lister les services en échec Base

Voir rapidement ce qui ne va pas sur le système

systemctl list-units --failed
Formule systemctl list-units --failed
Exemple
systemctl list-units --failed
Recharger la config systemd Base

Obligatoire après modification d'un fichier unit

sudo systemctl daemon-reload
Formule sudo systemctl daemon-reload
Exemple
sudo systemctl daemon-reload
Auditer la sécurité d'un service Base

Obtenir un score de sécurité et des recommandations

systemd-analyze security nginx
Formule systemd-analyze security SERVICE
Exemple
systemd-analyze security nginx
Services les plus lents au boot Base

Identifier les services qui ralentissent le démarrage

systemd-analyze blame | head -10
Formule systemd-analyze blame
Exemple
systemd-analyze blame | head -10
Bloquer un service Base

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

sudo systemctl mask cups
Formule sudo systemctl mask SERVICE
Exemple
sudo systemctl mask cups
Alternative : sudo systemctl unmask SERVICE pour débloquer

Ces erreurs courantes peuvent faire perdre du temps ou causer des dégâts. Les pièges les plus critiques sont affichés en premier.

Modifier le fichier vendor

sudo vim /usr/lib/systemd/system/nginx.service

Danger
Le piège : sudo vim /usr/lib/systemd/system/nginx.service
Symptôme : Modifications perdues à la prochaine mise à jour du paquet
Cause : Les fichiers vendor sont écrasés par les mises à jour
Correction : Utiliser systemctl edit pour créer un drop-in
sudo systemctl edit nginx
Confondre enable et start

sudo systemctl enable nginx

Attention
Le piège : sudo systemctl enable nginx
Symptôme : Le service n'est pas démarré après la commande
Cause : enable configure le boot, mais ne démarre pas maintenant
Correction : Utiliser enable --now pour les deux en une commande
sudo systemctl enable --now nginx
Oublier daemon-reload

Modifier /etc/systemd/system/mon-app.service puis restart

Attention
Le piège : Modifier /etc/systemd/system/mon-app.service puis restart
Symptôme : Les modifications ne sont pas prises en compte
Cause : systemd garde en cache la config — il faut recharger
Correction : Toujours faire daemon-reload après modification d'un fichier unit
sudo systemctl daemon-reload && sudo systemctl restart mon-app
Reload sur un service qui ne le supporte pas

sudo systemctl reload mon-app

Attention
Le piège : sudo systemctl reload mon-app
Symptôme : Erreur 'Job failed' ou service qui ne prend pas la config
Cause : Tous les services ne supportent pas le signal de reload
Correction : Utiliser reload-or-restart qui fait un restart si reload échoue
sudo systemctl reload-or-restart mon-app
WorkingDirectory inexistant

WorkingDirectory=/opt/mon-app dans le fichier unit

Attention
Le piège : WorkingDirectory=/opt/mon-app dans le fichier unit
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
Correction : Vérifier que le dossier existe et a les bonnes permissions
Chemin relatif dans ExecStart

ExecStart=./app.py

Attention
Le piège : ExecStart=./app.py
Symptôme : Service en failed avec 'Executable path is not absolute'
Cause : systemd exige des chemins absolus dans ExecStart
Correction : Utiliser le chemin complet
ExecStart=/opt/mon-app/venv/bin/python /opt/mon-app/app.py
Pas de section [Install]

Service sans WantedBy=multi-user.target

Info
Le piège : Service sans WantedBy=multi-user.target
Symptôme : systemctl enable retourne 'static' — rien ne se passe
Cause : Sans [Install], systemd ne sait pas quand démarrer le service
Correction : Ajouter [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.