← Sommaire SkyLinux

Leçon 55 : systemctl et les fichiers Unit

Introduction

Dans la leçon 21, nous avons vu comment gérer les services avec systemctl basique. Ici, nous allons plus loin : comprendre les fichiers unit, les créer, les modifier et maîtriser les options avancées.

systemd est le système d'initialisation utilisé par la plupart des distributions Linux modernes (Ubuntu, Debian, Fedora, Arch...). Il gère le démarrage, les services, les sockets, les timers et bien plus.

Rappels : commandes systemctl de base

# Lancer / arrêter / redémarrer un service
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# Activer au démarrage / désactiver
sudo systemctl enable nginx
sudo systemctl disable nginx
# Vérifier le statut
systemctl status nginx

Les types de fichiers Unit

Un fichier unit définit une unité de travail pour systemd. Il existe plusieurs types :

TypeExtensionDescription
Service.serviceDémarre un processus (nginx, apache, mysql...)
Socket.socketUn socket AF_UNIX ou réseau, déclenche un service à la connexion
Timer.timerPlanification temporelle (comme cron, voir leçon 41)
Path.pathSurveille un fichier/répertoire et déclenche un service
Mount.mountMonte un système de fichiers
Target.targetGroupe d'unités (comme runlevels, ex: multi-user.target)

Où se trouvent les fichiers Unit ?

# Unités système (globales)
/etc/systemd/system/ # Créées par l'administrateur
/usr/lib/systemd/system/ # Installées par les paquets
/run/systemd/system/ # Runtime (temporaire)

Pour un service utilisateur, c'est dans ~/.config/systemd/user/.

Examiner un fichier Unit existant

Regardons un exemple concret. affiche son contenu :

cat /lib/systemd/system/sshd.service
[Unit]
Description=OpenSSH server daemon
After=network.target
[Service]
Type=notify
ExecStart=/usr/sbin/sshd -D $SSHD_OPTIONS
Restart=always
KillMode=mixed
[Install]
WantedBy=multi-user.target

Structure d'un fichier Unit

[Unit] — Métadonnées et dépendances

[Unit]
Description=Mon service personnalisé # Description lisible
Documentation=https://monsite.com # Docs (optionnel)
After=network.target mysql.service # Démarre APRÈS ces unités
Before=nginx.service # Démarre AVANT cette unité
Requires=mysql.service # Dépendance stricte (échoue si absent)
Wants=redis.service # Dépendance souple (démarre même si absent)

[Service] — Configuration du processus

[Service]
Type=simple # Le programme ne fait pas de fork (defaut)
# Type=forking # Le programme fait un fork (PID attendu)
# Type=oneshot # Une seule exécution puis s'arrête
# Type=notify # Le programme notifie systemd quand prêt
# Type=dbus # Le service apparaît sur D-Bus
ExecStart=/usr/bin/mon_script.sh # Commande de démarrage
ExecStop=/usr/bin/mon_script.sh --stop # Commande d'arrêt (optionnel)
ExecReload=/bin/kill -HUP $MAINPID # Commande de reload
Restart=always # Redémarre en cas d'échec
# Restart=on-failure # Redémarre uniquement en cas d'erreur
# Restart=no # Ne redémarre jamais
RestartSec=5 # Pause de 5 secondes avant redémarrage
TimeoutStartSec=30 # Temps max pour démarrer
TimeoutStopSec=10 # Temps max pour arrêter
User=www-data # Utilisateur qui exécute le processus
Group=www-data # Groupe du processus
WorkingDirectory=/var/www # Répertoire de travail
Environment="PORT=8080" "ENV=prod" # Variables d'environnement
EnvironmentFile=/etc/monapp.env # Fichier variables
PIDFile=/run/monapp.pid # Fichier PID (pour Type=forking)
StandardOutput=journal # Sortie vers les logs
StandardError=journal # Erreurs vers les logs

[Install] — Comportement au démarrage

[Install]
WantedBy=multi-user.target # S'active au boot en mode multi-utilisateur
# WantedBy=graphical.target # Pour un environnement graphique
# WantedBy=default.target # Pour les services utilisateur
Also=autre-service.service # Active/désactive aussi cette unité

Créer son propre service

Exemple : un script Python qui tourne en continu

Crée d'abord ton script :

#!/bin/bash
# /opt/monapp/mon_script.sh
while true; do
echo "Mon app tourne..."
sleep 10
done
chmod +x /opt/monapp/mon_script.sh

Crée le fichier unit :

sudo nano /etc/systemd/system/monapp.service
[Unit]
Description=Mon application personnalisée
After=network.target
[Service]
Type=simple
ExecStart=/opt/monapp/mon_script.sh
Restart=always
RestartSec=5
User=root
[Install]
WantedBy=multi-user.target

Active le service :

sudo systemctl daemon-reload # Recharger systemd après modification
sudo systemctl enable --now monapp # Activer et démarrer
systemctl status monapp # Vérifier

Commandes avancées systemctl

Lister et filtrer

# Lister toutes les unités actives
systemctl list-units --type=service --state=running
# Lister tous les services (actifs et inactifs)
systemctl list-unit-files --type=service
# Lister les services activés au boot
systemctl list-dependencies multi-user.target
# Voir les services qui ont échoué
systemctl --failed --type=service

Manipuler les unités

# Relancer (stop + start)
sudo systemctl try-restart nginx
# Recharger la config sans redémarrer
sudo systemctl reload nginx
# Forcer l'arrêt (kill)
sudo systemctl kill -s SIGTERM monapp
# Masquer (rend impossible à démarrer)
sudo systemctl mask nginx
# Démasquer
sudo systemctl unmask nginx

Vérifications

# Voir si activé au boot
systemctl is-enabled nginx
# Voir si actif (en cours d'exécution)
systemctl is-active nginx
# Voir les dépendances d'un service
systemctl list-dependencies nginx
# Voir les propriétés d'une unité
systemctl show nginx | grep -E "MainPID|ExecStart|LoadState"

Les Targets (cibles)

Les targets regroupent des unités. Les plus courantes :

TargetUsage
basic.targetConfiguration de base
sysinit.targetInitialisation du système
local-fs.targetMontage des systèmes de fichiers locaux
network.targetRéseau disponible
multi-user.targetMode multi-utilisateur (sans GUI)
graphical.targetMode graphique (avec GUI)
poweroff.targetArrêt de la machine
reboot.targetRedémarrage
# Changer de target
sudo systemctl isolate multi-user.target
# Définir le target par défaut
sudo systemctl set-default multi-user.target
# Voir le target actuel
systemctl get-default

Bonnes pratiques

Dépanner un service qui ne démarre pas

# 1. Statut détaillé
systemctl status monapp
# 2. Logs du service
journalctl -u monapp -e # logs depuis le début
journalctl -u monapp --since today # logs du jour
# 3. Tester la commande ExecStart manuellement
/opt/monapp/mon_script.sh
# 4. Valider la syntaxe du fichier unit
systemd-analyze verify /etc/systemd/system/monapp.service

Résumé des options principales

OptionDescription
Type=simpleProcessus principal sans fork
Type=forkingProcessus qui fait un fork
Type=oneshotExécution unique puis arrêt
ExecStartCommande de démarrage
ExecStopCommande d'arrêt
Restart=alwaysRedémarre toujours
Restart=on-failureRedémarre en cas d'erreur
After=Démarre après ces unités
Wants=Démarre aussi si ces unités sont présentes
User=Utilisateur qui exécute le service
Environment=Variables d'environnement
WantedBy=Target qui déclenche l'activation