Systemd
Quand le bootloader (Grub, systemd-boot, efistub…) a chargé le noyau en mémoire, le noyau doit lancer le premier processus du système - le PID 1. Ce processus, c’est le gestionnaire d’initialisation (ou init), et il a un rôle central : démarrer et superviser tout le système depuis le boot jusqu’à l’extinction.
La grande majorité des distributions Linux utilisent systemd comme init. Il en existe d’autres - SysVinit, OpenRC, Runit - mais systemd est devenu le standard de facto, pour le meilleur et pour le débat.
Les units - le concept central
Section intitulée « Les units - le concept central »Tout dans systemd est une unit. Une unit est un fichier de configuration qui décrit une ressource que systemd doit gérer. Chaque type d’unit a son extension :
| Extension | Rôle |
|---|---|
.service | Un service (daemon, programme) |
.socket | Un socket réseau ou UNIX |
.mount | Un point de montage |
.timer | Un planificateur (alternative à cron) |
.target | Un groupe d’units (remplace les runlevels) |
.path | Surveillance d’un fichier/dossier |
Au quotidien, on touche surtout des .service et parfois des .timer.
Où vivent les units ?
Section intitulée « Où vivent les units ? »/lib/systemd/system/ # units du système (installés avec les paquets)/etc/systemd/system/ # tes units custom ou tes overrides (prioritaire)~/.config/systemd/user/ # units utilisateur (systemd --user)On ne touche jamais aux fichiers dans /lib/systemd/system/. Pour personnaliser un service système, il suffit de créer un fichier dans /etc/systemd/system/ - il sera prioritaire.
Les targets - les états du système
Section intitulée « Les targets - les états du système »Les targets regroupent des units ensemble. Elles remplacent le concept de runlevels de SysVinit.
| Target | Équivalent SysV | Description |
|---|---|---|
poweroff.target | runlevel 0 | Extinction |
rescue.target | runlevel 1 | Mode maintenance (root seul) |
multi-user.target | runlevel 3 | Multi-utilisateur sans GUI |
graphical.target | runlevel 5 | Multi-utilisateur avec GUI |
reboot.target | runlevel 6 | Reboot |
Pour voir et changer la target par défaut (le “runlevel” au boot) :
systemctl get-defaultsystemctl set-default multi-user.targetAnatomie d’un fichier .service
Section intitulée « Anatomie d’un fichier .service »Un fichier .service est un fichier INI avec trois sections principales :
[Unit]Description=Mon appDocumentation=https://example.comAfter=network.target # démarre après network.targetRequires=postgresql.service # a besoin de postgres (bloquant)Wants=redis.service # veut redis, mais pas bloquant si absent
[Service]Type=simpleUser=www-dataWorkingDirectory=/opt/appExecStart=/opt/app/bin/start --config /etc/app/config.tomlRestart=on-failureRestartSec=5s
[Install]WantedBy=multi-user.targetgraph TD app["Mon app"] app -->|Requires| pg["postgresql.service"] app -->|Wants| redis["redis.service"] app -->|After| net["network.target"] target["multi-user.target"] -->|WantedBy| appLe champ Type=
Section intitulée « Le champ Type= »Il définit comment systemd sait que le service est prêt :
simple(défaut) - le processus lancé parExecStartest le serviceforking- le processus se fork en arrière-plan (vieux daemons style Apache)oneshot- s’exécute une fois puis se termine (scripts d’init)notify- le service envoie une notification à systemd quand il est prêt
Restart policy
Section intitulée « Restart policy »Restart=on-failure # redémarrage si exit code != 0 ou signalRestart=always # redémarrage dans tous les casRestart=no # jamais (défaut)systemctl - les commandes du quotidien
Section intitulée « systemctl - les commandes du quotidien »systemctl start nginxsystemctl stop nginxsystemctl restart nginxsystemctl reload nginx # recharge la config sans coupure (si le service le supporte)systemctl status nginxPour activer/désactiver au boot :
systemctl enable nginx # activer au démarragesystemctl disable nginx # désactiversystemctl enable --now nginx # activer ET démarrer maintenantsystemctl disable --now nginx # désactiver ET arrêter maintenantPour interroger l’état :
systemctl is-active nginx # active / inactivesystemctl is-enabled nginx # enabled / disabledsystemctl is-failed nginx # failed / activePour lister les units :
systemctl list-units # units activessystemctl list-units --type=service # services uniquementsystemctl list-units --state=failed # ce qui a crashésystemctl list-unit-files # toutes les units + leur étatAprès avoir modifié un fichier unit, toujours faire :
systemctl daemon-reloadsystemd met en cache les fichiers unit. Sans daemon-reload, il ignore les modifications.
journalctl - lire les logs
Section intitulée « journalctl - lire les logs »systemd centralise tous les logs dans le journal (journald), accessibles via journalctl.
journalctl -u nginx # logs du service nginxjournalctl -u nginx -f # suivi en temps réeljournalctl -u nginx --since "1h ago" # dernière heurejournalctl -u nginx -b # depuis le dernier bootjournalctl -u nginx -b -1 # boot d'avantjournalctl -p err # erreurs uniquementCréer son propre service
Section intitulée « Créer son propre service »Faire tourner une app Node.js en permanence, par exemple. On crée le fichier unit :
sudo nano /etc/systemd/system/monapp.service[Unit]Description=Mon app Node.jsAfter=network.target
[Service]Type=simpleUser=timWorkingDirectory=/home/tim/monappExecStart=/usr/bin/node server.jsRestart=on-failureRestartSec=3sEnvironment=NODE_ENV=production PORT=3000
[Install]WantedBy=multi-user.targetPuis on recharge, active et démarre en une commande :
sudo systemctl daemon-reloadsudo systemctl enable --now monappPour vérifier que tout tourne :
systemctl status monappjournalctl -u monapp -fL’app redémarre si elle crash et se relance au boot. Plus besoin de screen ou de nohup.
Les timers - alternative à cron
Section intitulée « Les timers - alternative à cron »Les .timer permettent de planifier des tâches. Les logs passent dans journald et le contrôle sur les dépendances est bien plus fin qu’avec cron.
Un script de backup toutes les heures :
[Unit]Description=Backup toutes les heures
[Timer]OnCalendar=hourlyPersistent=true # rattrape les exécutions manquées si la machine était éteinte
[Install]WantedBy=timers.target[Unit]Description=Script de backup
[Service]Type=oneshotExecStart=/usr/local/bin/backup.shsudo systemctl enable --now backup.timersystemctl list-timers # voir tous les timers actifs et leur prochaine exécutionCe que j’en retiens
Section intitulée « Ce que j’en retiens »systemd est bavard au premier abord, mais la logique est cohérente une fois qu’on a saisi le concept d’unit. Dans mon setup Arch + i3, je l’utilise surtout pour gérer mes services perso (syncthing, pipewire, des scripts de démarrage) et les timers pour quelques tâches récurrentes. journalctl -u <service> -f est probablement la commande que j’utilise le plus quand quelque chose ne démarre pas comme prévu.