Vous avez modifié /lib/systemd/system/something.service à 2 h du matin, le service « fonctionnait », puis une mise à jour de paquet a discrètement annulé votre correctif.
Maintenant vous êtes face à une boucle de redémarrage, en vous demandant quelle partie de votre mémoire vous trahit.
Ubuntu 24.04 est l’univers systemd. La bonne décision n’est presque jamais « éditer le fichier d’unité du fournisseur ». La bonne décision, ce sont les overrides : drop-ins,
clairs, traçables, réversibles. Vous obtenez le correctif sans fragilité — et vous arrêtez de perdre des batailles contre dpkg.
Le modèle mental : ce que systemd lit, et dans quel ordre
systemd est un assembleur de configuration. Il ne « charge pas un fichier d’unité » isolément. Il construit la configuration finale de l’unité à partir de plusieurs couches, puis l’exécute.
Si vous le traitez comme un fichier unique, vous continuerez à être surpris.
Où proviennent les fichiers d’unité (Ubuntu 24.04)
Sur Ubuntu, vous verrez couramment :
/lib/systemd/system/: fichiers d’unité fournis par les paquets. Vous ne possédez pas ceux-ci./etc/systemd/system/: overrides administratifs et unités personnalisées. Vous les possédez./run/systemd/system/: unités runtime et drop-ins transitoires. Éphémère ; survit jusqu’au reboot.
La priorité est effectivement : /etc prime sur /run prime sur /lib (avec quelques nuances), plus les drop-ins appliqués par ordre lexical.
La règle pratique reste utile : si vous voulez un correctif stable, placez-le dans /etc.
Drop-ins : le scalpel propre
Le mécanisme d’override canonique est un fichier drop-in :
/etc/systemd/system/<unit>.d/override.conf.
Il contient uniquement les deltas que vous voulez, pas une copie complète de l’unité. Cela compte car c’est lisible, révocable et résistant à l’évolution du fichier fournisseur.
Vous pouvez aussi placer plusieurs drop-ins (par ex. 10-limits.conf, 20-env.conf). systemd les charge dans l’ordre.
Cela rend la question « qui a changé quoi » beaucoup plus facile à répondre que « quelqu’un a édité le fichier d’unité en place et maintenant c’est une pièce unique sur mesure ».
La différence entre éditer et override (et pourquoi ça compte)
Éditer le fichier d’unité fournisseur est une nuisance attrayante. C’est rapide, et cela crée de la dette technique en une seule frappe.
À la minute où le paquet se met à jour, dpkg va :
- écraser l’unité (si vous ne l’avez pas marquée comme conffile), ou
- demander des actions qui seront « résolues » pendant une urgence, ou
- laisser un bazar .dpkg-dist/.dpkg-old que personne ne pense à concilier.
Les overrides évitent tout cela. Le paquet peut faire ce qu’il veut. Votre intention s’applique toujours.
Une citation pour rester honnête
« Les bugs subtils sont ceux qui apparaissent après des changements que vous aviez oubliés. » — idée paraphrasée souvent attribuée à des ingénieurs opérationnels chevronnés
Gardez vos modifications là où vous pouvez les voir. Les overrides sont exactement ça.
Huit faits et un peu d’histoire (pourquoi les overrides existent)
- systemd a été lancé en 2010 (Lennart Poettering et Kay Sievers) et a remplacé un zoo de scripts init par des fichiers d’unité déclaratifs.
- Ubuntu a adopté systemd par défaut en 15.04 ; en 24.04 ce n’est pas « nouveau », c’est l’hypothèse de travail derrière la plupart des paquets de service.
- Les drop-ins ont été conçus pour le packaging des distributions : les fournisseurs livrent des valeurs sûres ; les opérateurs ajoutent la politique du site sans forker l’unité.
- Les chemins de recherche des fichiers d’unité font partie de l’interface ; systemd est volontairement construit pour fusionner la configuration depuis plusieurs emplacements, pas seulement « lire un fichier ».
systemctl editest le workflow recommandé ; il crée les répertoires et gère l’éditeur en toute sécurité, y compris les « changements à sec puis reload ».- Remplacer
ExecStart=demande d’abord de le vider ; systemd le considère comme une liste, pas comme une chaîne. Si vous oubliez la ligne de réinitialisation, vous lancerez deux starts (ou aucun). - Il existe une couche runtime dans
/run; des outils et generators peuvent créer des unités transitoires, utiles pour la logique de démarrage mais délicats pour le debug. - systemd offre une forte introspection :
systemctl cat,systemd-analyze,journalctl -uetsystemctl showvous permettent de voir ce qu’il a effectivement décidé.
Blague #1 : Éditer /lib/systemd/system en production, c’est comme « juste tester en prod » — rapide, grisant, et seulement parfois limitant pour la carrière.
Cas n°8 : un override propre qui survit aux mises à jour
Voici la situation que je vois constamment sur Ubuntu 24.04 :
un service fournisseur démarre bien la plupart du temps, mais sous charge il atteint des limites (descripteurs de fichiers, processus, verrouillage mémoire), ou il a besoin d’une variable d’environnement supplémentaire,
ou le répertoire de travail est incorrect, ou il devrait attendre un point de montage. La tentation est d’éditer le fichier d’unité là où il se trouve. Ne le faites pas.
Votre objectif est : (1) identifier le changement minimal, (2) l’implémenter dans /etc/systemd/system en tant que drop-in, et
(3) prouver que systemd exécute la configuration fusionnée que vous souhaitez.
Patrons d’override typiques « sûrs et routiniers »
- Limites de ressources :
LimitNOFILE=,TasksMax=,MemoryMax=— stables et peu dramatiques. - Ordonnancement au démarrage :
After=,Requires=,Wants=— évitez les conditions de course avec les montages et les réseaux. - Environnement :
Environment=,EnvironmentFile=— gardez les secrets hors des fichiers d’unité ; utilisez des fichiers avec permissions. - Comportement de redémarrage :
Restart=on-failure,RestartSec=,StartLimitIntervalSec=— ajustez, mais ne cachez pas les fautes réelles. - Modifications d’ExecStart : faisable, mais ça mérite des précautions supplémentaires et un plan de rollback.
Quand ne pas override
Si le service est cassé parce que le binaire est défaillant, le fichier de configuration est mauvais, ou une dépendance manque, un override ne vous sauvera pas.
Les overrides servent à changer la manière dont systemd exécute un programme correct, pas à patcher le programme lui‑même.
Blague #2 : Si vous « réparez » un segfault avec Restart=always, félicitations — vous venez d’inventer un générateur de logs très rapide.
Playbook de diagnostic rapide : trouver le goulot vite
Quand un service est malsain, vous pouvez passer 30 minutes à lire des fichiers d’unité… ou passer 3 minutes à regarder les bonnes sorties.
Voilà l’ordre que j’utilise en production.
1) Établir le symptôme : état, code de sortie et dernière erreur
- Vérifier le statut : est-il
failed,activating, ou en cours d’exécution mais dégradé ? - Vérifier le code de sortie :
status=203/EXECvsstatus=1/FAILUREvs kill OOM sont des univers différents. - Vérifier les dernières lignes de logs : ne faites pas défiler ; demandez à journald les 50 dernières lignes avec horodatages.
2) Confirmer ce que systemd exécute réellement
- Afficher l’unité fusionnée :
systemctl catmontre le fournisseur + les drop-ins. - Inspecter les propriétés :
systemctl show -p ExecStart,Environment,LimitNOFILEpour confirmer les valeurs effectives. - Vérifier si un generator a créé quelque chose dans /run : si oui, vos changements persistants peuvent être battus ou complétés.
3) N’éditer qu’après : changement minimal, rollback prévisible
- Créer un drop-in avec
systemctl edit. - Exécuter
systemd-analyze verifysi vous avez touché des parties sensibles en syntaxe. daemon-reload, puis redémarrer, puis valider.
Tâches pratiques (commandes, sens des sorties, décisions)
Ci‑dessous des tâches réelles que vous pouvez exécuter sur Ubuntu 24.04. Chacune inclut ce que la sortie signifie et quelle décision prendre ensuite.
J’utiliserai nginx.service comme exemple parce que c’est courant, mais le workflow est identique pour bases de données, agents, exporters et démons personnalisés.
Tâche 1 : Trouver où se trouve le fichier d’unité
cr0x@server:~$ systemctl show -p FragmentPath -p DropInPaths nginx.service
FragmentPath=/lib/systemd/system/nginx.service
DropInPaths=/etc/systemd/system/nginx.service.d/override.conf
Sens : FragmentPath est le fichier d’unité principal utilisé par systemd. DropInPaths liste les overrides appliqués.
Décision : Si votre changement est dans /lib, vous tenez une grenade. Déplacez-le dans un drop-in sous /etc.
Tâche 2 : Lire l’unité fusionnée, pas seulement le fragment fournisseur
cr0x@server:~$ systemctl cat nginx.service
# /lib/systemd/system/nginx.service
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
PIDFile=/run/nginx.pid
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
Sens : Voilà ce que systemd appliquera. C’est la vérité. Tout le reste n’est que commentaire.
Décision : Si l’unité fusionnée ne montre pas votre changement, vous éditez le mauvais emplacement ou avez oublié daemon-reload.
Tâche 3 : Vérifier l’état en direct et la dernière raison de sortie
cr0x@server:~$ systemctl status nginx.service --no-pager
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Drop-In: /etc/systemd/system/nginx.service.d
└─override.conf
Active: failed (Result: exit-code) since Mon 2025-12-30 10:12:07 UTC; 15s ago
Docs: man:nginx(8)
Process: 2197 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
CPU: 45ms
Sens : status=1/FAILURE indique que nginx s’est exécuté et a retourné une erreur (souvent une erreur de config), pas un problème d’exec.
Décision : Allez voir les logs ensuite ; ne réécrivez pas ExecStart avant de savoir que c’est nécessaire.
Tâche 4 : Récupérer les logs récents de l’unité, avec horodatages
cr0x@server:~$ journalctl -u nginx.service -n 50 --no-pager -o short-iso
2025-12-30T10:12:07+00:00 server nginx[2197]: nginx: [emerg] invalid number of arguments in "worker_connections" directive in /etc/nginx/nginx.conf:12
2025-12-30T10:12:07+00:00 server systemd[1]: nginx.service: Main process exited, code=exited, status=1/FAILURE
2025-12-30T10:12:07+00:00 server systemd[1]: nginx.service: Failed with result 'exit-code'.
Sens : Le service a échoué à cause d’une config d’application. systemd n’est pas le problème aujourd’hui.
Décision : Corrigez la config nginx. Les overrides n’aideront pas. Si votre changement visait à corriger un chemin de config, validez cette hypothèse.
Tâche 5 : Confirmer si un drop-in existe et ce qu’il contient
cr0x@server:~$ systemctl edit nginx.service --full
# (editor opens the full unit)
Sens : --full crée une copie entière de l’unité dans /etc/systemd/system. C’est un gros marteau.
Décision : Préférez systemctl edit nginx.service (drop-in). Utilisez --full uniquement si vous devez remplacer l’unité en totalité.
Tâche 6 : Créer un drop-in propre (recommandé)
cr0x@server:~$ systemctl edit nginx.service
# (editor opens /etc/systemd/system/nginx.service.d/override.conf)
Ajoutez quelque chose comme :
cr0x@server:~$ sudo cat /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
TasksMax=4096
Sens : Vous ne forkez pas l’unité. Vous superposez de la politique.
Décision : Gardez les overrides petits. Si votre override.conf est plus long que le fichier fournisseur, vous écrivez votre propre unité — possédez‑la explicitement.
Tâche 7 : Reload systemd après avoir changé des fichiers d’unité
cr0x@server:~$ sudo systemctl daemon-reload
Sens : systemd relit les définitions d’unité. Sans cela, il peut garder d’anciennes versions.
Décision : Si les changements « ne s’appliquent pas », suspectez d’abord que vous avez oublié le reload. Second suspect : vous avez édité un fichier que systemd n’utilise pas.
Tâche 8 : Vérifier les valeurs effectives que systemd appliquera
cr0x@server:~$ systemctl show nginx.service -p LimitNOFILE -p TasksMax -p Environment
LimitNOFILE=65536
TasksMax=4096
Environment=
Sens : C’est la config effective après la fusion de tous les fragments et drop-ins.
Décision : Si vous attendiez une valeur et qu’elle n’est pas là, trouvez ce qui vous override (ordre des drop-ins, unité complète dans /etc, ou unité transitoire).
Tâche 9 : Overrider ExecStart correctement (vider d’abord)
C’est là que les gens se trompent. Dans systemd, beaucoup d’instructions sont de type liste. ExecStart= en fait partie.
Pour le remplacer, vous devez d’abord réinitialiser la liste.
cr0x@server:~$ sudo cat /etc/systemd/system/nginx.service.d/10-execstart.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' -c /etc/nginx/nginx.conf
Sens : La ligne vide ExecStart= réinitialise la liste ; la ligne suivante devient le seul ExecStart.
Décision : Si vous ne réinitialisez pas, vous risquez d’avoir plusieurs lignes ExecStart. Au mieux : le démarrage échoue. Au pire : ça « marche » jusqu’à ce que ça ne marche plus.
Tâche 10 : Détecter une tempête de redémarrages et l’arrêter en sécurité
cr0x@server:~$ systemctl show nginx.service -p NRestarts -p Restart -p RestartUSec
NRestarts=27
Restart=on-failure
RestartUSec=100ms
Sens : Le service clignote rapidement. Cela peut inonder les logs et cacher la première défaillance.
Décision : Arrêtez et masquezt temporairement pendant le debug (si c’est sûr), ou augmentez RestartSec= via un drop-in pour ralentir la boucle.
Tâche 11 : Vérifier si vous êtes en train de vous battre contre un remplacement complet d’unité dans /etc
cr0x@server:~$ systemctl show nginx.service -p FragmentPath
FragmentPath=/etc/systemd/system/nginx.service
Sens : Quelqu’un a créé une unité complète dans /etc, ce qui remplace complètement l’unité fournisseur.
Décision : Si vous ne vouliez pas posséder toute l’unité, retirez l’unité complète et remplacez‑la par des drop-ins. C’est un vieux réflexe fréquent après un usage ponctuel de --full.
Tâche 12 : Identifier les problèmes d’ordonnancement/dépendance (montages, réseau, etc.)
cr0x@server:~$ systemctl list-dependencies --reverse nginx.service
nginx.service
● multi-user.target
Sens : Les dépendances inverses montrent qui veut ce service. C’est « qui cassera si nginx est down ».
Décision : Si des targets critiques dépendent de lui, planifiez les changements avec prudence et utilisez des reloads ou fenêtres de maintenance.
Tâche 13 : Vérifier la syntaxe d’unité avant de redémarrer des services critiques
cr0x@server:~$ systemd-analyze verify /etc/systemd/system/nginx.service.d/10-execstart.conf
Sens : L’absence de sortie signifie typiquement « aucun problème trouvé ». Si erreur de syntaxe il y a, vous la verrez avant de lancer la production.
Décision : Utilisez verify quand vous touchez des directives délicates (ExecStart, dépendances, sandboxing). C’est moins coûteux qu’une avalanche de pages.
Tâche 14 : Revenir proprement en arrière sur des overrides
cr0x@server:~$ sudo systemctl revert nginx.service
Removed "/etc/systemd/system/nginx.service.d/override.conf".
Removed "/etc/systemd/system/nginx.service.d/10-execstart.conf".
Sens : revert supprime les drop-ins et ramène l’unité à l’état fournisseur (ou à ce qui reste).
Décision : Utilisez‑le quand votre override a empiré les choses et que vous avez besoin d’un bouton « retour à la baseline connue ».
Tâche 15 : Confirmer quels overrides sont appliqués actuellement (avec l’ordre des fichiers)
cr0x@server:~$ systemctl show nginx.service -p DropInPaths
DropInPaths=/etc/systemd/system/nginx.service.d/10-execstart.conf /etc/systemd/system/nginx.service.d/override.conf
Sens : L’ordre compte. L’ordre lexical compte. Votre fichier 90-* l’emportera sur votre 10-*.
Décision : Si vous superposez plusieurs changements, nommez‑les intentionnellement. Ne laissez pas « override.conf » devenir un tiroir à bazar.
Tâche 16 : Prouver que le processus en cours a bien les limites que vous avez définies
cr0x@server:~$ systemctl show nginx.service -p MainPID
MainPID=2418
cr0x@server:~$ cat /proc/2418/limits | head -n 8
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 4096 4096 processes
Sens : Cela montre ce que le noyau applique réellement au processus.
Décision : Si les limites dans /proc ne correspondent pas, vous pouvez avoir plusieurs processus (master/worker), ou le service fork et applique les limites différemment. Vérifiez le bon PID.
Trois mini-récits d’entreprise depuis le terrain
Mini-récit 1 : Un incident causé par une mauvaise hypothèse
Une entreprise SaaS de taille moyenne exploitait une flotte de serveurs Ubuntu exécutant un forwarder de logs comme service systemd.
Le forwarder a commencé à échouer après une mise à jour de sécurité routinière. Les ingénieurs ont vu que le service utilisait
un fichier d’unité dans /lib/systemd/system et ont supposé « c’est stable, ça ne changera pas beaucoup ».
Quelques mois plus tôt, quelqu’un avait « temporairement » édité l’unité fournisseur en place pour ajouter une variable d’environnement :
Environment=HTTP_PROXY=.... C’était non documenté, non revu, et invisible pour la gestion de configuration parce que ce n’était pas dans /etc.
La mise à jour de sécurité a remplacé le paquet, et le proxy a disparu. Le forwarder n’a plus pu joindre le collecteur, et les logs ont cessé de circuler.
L’alerte déclenchée n’était pas « forwarder de logs down ». C’était en aval : un tableau de bord est devenu silencieux,
puis un job d’export compliance a échoué parce qu’il attendait des logs. Les gens ont cherché au mauvais endroit pendant une heure.
Le premier indice était dans journald : des erreurs de connexion répétées après l’heure de la mise à jour du paquet.
Le correctif fut ennuyeux : un drop-in sous /etc/systemd/system pour définir le proxy, plus une note dans le runbook.
La recommandation du postmortem fut plus tranchante : ne jamais modifier directement les unités fournisseurs, et construire une vérification d’audit d’unités
dans leur détection de dérive de configuration.
Mini-récit 2 : Une optimisation qui a mal tourné
Une autre entreprise exécutait un service sensible à la latence avec des paramètres de redémarrage agressifs.
Quelqu’un a constaté qu’après un crash, le temps de récupération était trop lent à son goût.
Ils ont réduit RestartSec à 100 ms et augmenté StartLimitBurst « pour le garder disponible ».
Cela a effectivement réduit le temps entre les crashes et les redémarrages. C’est précisément le problème.
Un bug latent de configuration a commencé à provoquer des échecs occasionnels. Au lieu d’un crash propre et d’un redémarrage stable,
le service est entré dans une boucle de crash rapide. Le CPU a grimpé, les logs ont explosé, et d’autres services sur la même machine
ont commencé à manquer leurs deadlines à cause de la pression I/O.
Puis le retour de flamme : la limitation de débit de journald s’est déclenchée. Les logs nécessaires au debug du défaut initial sont devenus
incomplets. Pendant ce temps, le système de monitoring voyait « service up » de façon intermittente et n’a pas immédiatement escaladé.
Tout le monde a perdu du temps parce que les symptômes étaient étalés sur toute la machine.
La récupération a consisté à arrêter l’unité, revenir sur l’override, puis réintroduire des valeurs sensées :
Restart=on-failure, RestartSec=2s, et une limite de démarrage modérée.
La véritable optimisation fut de changer le healthcheck pour détecter les « redémarrages rapides » comme une défaillance et avertir plus tôt.
Mini-récit 3 : Une pratique ennuyeuse mais correcte qui a sauvé la situation
Une grande entreprise avait pour politique : toutes les modifications systemd doivent être des drop-ins, nommés avec un préfixe et un numéro de ticket,
et chaque override doit être visible dans un rapport d’inventaire unique extrait par systemctl show sur chaque hôte.
Ça ressemblait à de la bureaucratie jusqu’au jour où ce ne l’était plus.
Un fournisseur a livré une unité mise à jour pour un agent critique, changeant les options de sandboxing par défaut.
Sur un sous-ensemble de serveurs, l’agent a cessé d’accéder à un répertoire dont il avait besoin. L’incident aurait pu devenir une
chasse multi-jours « ça marche sur mon nœud » parce que différentes équipes possédaient différents environnements.
Au lieu de ça, l’ingénieur de garde a extrait le rapport d’inventaire et a immédiatement vu quels serveurs avaient un override touchant
l’accès au système de fichiers (par ex. ReadWritePaths) et lesquels n’en avaient pas. La convention de nommage rendait la recherche possible.
Ils ont déployé un drop-in d’une ligne pour aligner le comportement, redémarré l’agent en sécurité, et sont passés à autre chose.
La pratique n’a pas empêché le changement du fournisseur. Elle a évité la confusion. En production, la clarté est une fonctionnalité.
Erreurs courantes : symptôme → cause racine → correctif
1) « Mon override ne s’applique pas »
Symptôme : Vous avez édité un drop-in, redémarré le service, et rien n’a changé.
Cause racine : Oubli de systemctl daemon-reload, ou édition d’un fichier au mauvais endroit, ou une unité complète dans /etc supprime fournisseur + drop-ins.
Correctif : Exécutez systemctl show -p FragmentPath -p DropInPaths unit ; puis daemon-reload ; puis systemctl cat unit pour confirmer la configuration fusionnée.
2) « J’ai overridé ExecStart et maintenant il ne démarre plus »
Symptôme : Le service échoue avec des messages bizarres, ou essaie d’exécuter plusieurs commandes.
Cause racine : Vous avez ajouté ExecStart=... sans vider la liste existante.
Correctif : Dans votre drop-in : ajoutez une ligne vide ExecStart= avant le nouveau ExecStart=.... Reload et redémarrage.
3) « La mise à jour du paquet a annulé mon correctif »
Symptôme : Le comportement du service change juste après apt upgrade.
Cause racine : Vous avez édité /lib/systemd/system/*.service directement (territoire fournisseur).
Correctif : Réappliquez le changement en tant que drop-in sous /etc/systemd/system/<unit>.d/. Envisagez systemctl revert pour nettoyer des copies d’unité complètes accidentelles.
4) « Il démarre manuellement mais pas via systemd »
Symptôme : Lancer le binaire dans un shell fonctionne ; systemd start échoue.
Cause racine : Variables d’environnement manquantes, répertoire de travail différent, ou sandboxing plus strict dans le contexte systemd.
Correctif : Comparez systemctl show -p Environment -p WorkingDirectory ; ajoutez EnvironmentFile= ou WorkingDirectory= dans un drop-in ; vérifiez les logs.
5) « Le service clignote et met la machine à genoux »
Symptôme : CPU élevé, logs massifs, « service redémarre sans cesse ».
Cause racine : Politique de redémarrage trop agressive (Restart=always, RestartSec minuscule), ou une boucle de crash réelle masquée par l’auto-restart.
Correctif : Ralentissez : Restart=on-failure, RestartSec=2s. Arrêtez l’unité, capturez les logs, corrigez la cause racine, puis redémarrez.
6) « Mon override a cassé après avoir ajouté plusieurs drop-ins »
Symptôme : Les paramètres semblent « changer aléatoirement » selon l’hôte.
Cause racine : L’ordre des fichiers drop-in diffère ou un autre fichier override la même directive plus tard.
Correctif : Utilisez un numérotage explicite (10-, 20-, 90-). Vérifiez DropInPaths. Consolidez les directives conflictuelles.
7) « Il ne voit pas un répertoire monté au boot »
Symptôme : Le service échoue au démarrage, mais fonctionne après un redémarrage manuel.
Cause racine : Dépendances d’ordonnancement sur l’unité de montage manquantes ; le service démarre avant que le système de fichiers soit prêt.
Correctif : Ajoutez un drop-in avec RequiresMountsFor=/path ou les bons After=/Requires=. Reload et testez le comportement au reboot.
Checklists / plan pas à pas
Checklist A : Faire un override sûr (approche par défaut)
- Récupérez la vérité actuelle :
systemctl cat unitetsystemctl show -p FragmentPath -p DropInPaths unit. - Décidez du plus petit changement possible (limites, env, ordonnancement, politique de redémarrage).
- Créez le drop-in :
sudo systemctl edit unit. - Ajoutez seulement les directives nécessaires. Évitez de copier le fichier fournisseur.
- Validez la syntaxe si vous avez touché des éléments délicats :
systemd-analyze verify .... sudo systemctl daemon-reload.- Redémarrez et vérifiez :
sudo systemctl restart unitpuissystemctl status unit. - Prouvez la configuration effective :
systemctl show -p ... unit. - Prouvez l’effet en runtime (limites/env) via
/procou des diagnostics spécifiques au service.
Checklist B : Vous devez remplacer ExecStart (changement à haut risque)
- Capturez l’ExecStart actuel :
systemctl show -p ExecStart unit. - Créez un fichier drop-in dédié (ne l’enterrez pas) :
/etc/systemd/system/unit.d/10-execstart.conf. - Réinitialisez la liste d’abord : incluez une ligne vide
ExecStart=. - Incluez tout
ExecStartPre=,WorkingDirectory=et fichiers d’environnement nécessaires. - Vérifiez :
systemd-analyze verify. - Reload et redémarrage.
- Ayez un rollback prêt :
systemctl revert unit(ou supprimez le drop-in) et redémarrez.
Checklist C : Rollback et retour à la baseline
- Arrêtez le service s’il clignote :
sudo systemctl stop unit. - Snapshot de l’unité fusionnée actuelle :
systemctl cat unitdans vos notes d’incident. - Revenez sur les overrides :
sudo systemctl revert unit. - Reload :
sudo systemctl daemon-reload. - Start :
sudo systemctl start unit. - Confirmez les logs :
journalctl -u unit -n 50.
FAQ
1) Dois‑je jamais éditer les fichiers dans /lib/systemd/system ?
Non, pas en pratique. Traitez‑les comme du firmware fournisseur : lisibles, pas modifiables. Utilisez des drop-ins dans /etc/systemd/system.
Si vous devez expérimenter, faites‑le sur un hôte jetable et traduisez le résultat en override.
2) Quelle est la différence entre systemctl edit et éditer un fichier manuellement ?
systemctl edit crée la structure de répertoire correcte, ouvre le bon fichier, et s’aligne sur le modèle de systemd.
Les éditions manuelles sont correctes si vous connaissez les chemins, mais systemctl edit réduit les erreurs de « mauvais emplacement ».
3) Pourquoi mon override ExecStart= n’a‑t‑il pas remplacé l’ancien ?
Parce que ExecStart est de type liste. Ajoutez une ligne vide ExecStart= pour vider la liste d’abord, puis ajoutez votre nouveau ExecStart=....
4) Comment voir l’unité finale que systemd utilise ?
Utilisez systemctl cat unit pour la configuration fusionnée et systemctl show -p FragmentPath -p DropInPaths unit pour voir les sources et les drop-ins appliqués.
5) Ai‑je besoin de daemon-reload à chaque fois ?
Si vous avez changé des fichiers d’unité ou des drop-ins, oui. Redémarrer un service n’implique pas de relire la définition d’unité de manière fiable.
daemon-reload est peu coûteux ; les pannes ne le sont pas.
6) Quelle est la façon la plus propre de supprimer un override ?
sudo systemctl revert unit. Cela supprime les drop-ins et revient aux valeurs fournisseur. Puis exécutez daemon-reload.
7) Puis‑je utiliser des drop-ins pour changer des dépendances comme After= et Requires= ?
Oui, et c’est l’un des meilleurs usages. Si un service dépend d’un montage, envisagez RequiresMountsFor=/path.
Pour les dépendances réseau, soyez prudent : « réseau up » n’est pas la même chose que « dépendance distante joignable ».
8) Mon override fonctionne sur un serveur mais pas sur un autre. Pourquoi ?
Les raisons les plus courantes : un autre drop-in vous override plus tard ; il y a une unité complète dans /etc sur un hôte ; ou un generator a produit quelque chose dans /run.
Comparez systemctl show -p FragmentPath -p DropInPaths entre les hôtes.
9) Est‑il mieux de tout mettre dans un seul override.conf ?
Pas toujours. Un seul fichier est simple tant qu’il ne devient pas un tiroir à bazar. Pour des changements plus larges, séparez les drop-ins par but avec numérotation :
10-limits.conf, 20-env.conf, 90-hardening.conf. L’ordre devient explicite.
10) Comment confirmer que mes changements de limites s’appliquent réellement au processus ?
Obtenez le PID avec systemctl show -p MainPID et vérifiez /proc/<pid>/limits. C’est ce que le noyau applique.
Conclusion : prochaines étapes à faire aujourd’hui
Sur Ubuntu 24.04, les overrides systemd sont la manière mature de corriger des services. Ils survivent aux mises à jour, séparent votre intention des valeurs fournisseur,
et rendent la réponse aux incidents plus rapide parce que la question « qu’est‑ce qui a changé » trouve une réponse en secondes.
Prochaines étapes pratiques :
- Choisissez un service que vous avez déjà « tweaké ». Exécutez
systemctl show -p FragmentPath -p DropInPathset vérifiez si des éditions résident dans/lib. - S’ils y sont, migrez‑les vers un drop-in sous
/etc/systemd/system/<unit>.d/. - Standardisez le nommage des drop-ins (numérotés, par but). Votre futur vous est une autre personne qui dort différemment.
- Apprenez à votre équipe deux commandes :
systemctl catetsystemctl revert. L’une trouve la vérité ; l’autre vous achète un rollback.
Faites cela quelques fois et vous cesserez de traiter systemd comme une boîte noire. Ce n’est pas de la magie. C’est juste très pointilleux sur l’endroit où vous placez vos modifications.