Services (.service)¶
Les unités de type .service sont le type le plus courant dans systemd. Elles représentent des processus ou daemons qui s'exécutent en arrière-plan.
Structure d'un fichier service¶
Un fichier .service typique contient trois sections principales :
[Unit]
Description=Mon Application Web
Documentation=https://example.com/docs
After=network.target
Requires=network.target
[Service]
Type=simple
User=webapp
Group=webapp
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/myapp --config /etc/myapp/config.yaml
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
Section [Unit]¶
La section [Unit] contient les métadonnées et dépendances.
Options courantes¶
- Description
-
Description lisible du service (affichée par
systemctl status)
- Documentation
-
URLs vers la documentation (man pages, sites web)
- After / Before
-
Ordre de démarrage (n'implique pas de dépendance forte)
- Requires
-
Dépendance stricte (si la dépendance échoue, ce service échoue aussi)
- Wants
-
Dépendance faible (recommandée mais pas obligatoire)
- Conflicts
-
Unités incompatibles (ne peuvent pas tourner simultanément)
- Condition / Assert
-
Conditions de démarrage
ConditionPathExists=/etc/myapp/config.yaml
ConditionFileNotEmpty=/etc/myapp/config.yaml
AssertPathExists=/usr/bin/myapp
Section [Service]¶
La section [Service] définit comment exécuter et gérer le processus.
Type de service¶
Le paramètre Type= définit comment systemd doit gérer le processus :
Type=simple (défaut)¶
Le processus démarré par ExecStart est le processus principal.
Utilisation : Pour les applications qui restent au premier plan.
Type=forking¶
Le processus fork() et le parent se termine, l'enfant continue.
Utilisation : Daemons traditionnels qui se mettent en arrière-plan.
Type=oneshot¶
Le processus s'exécute puis se termine (pas de daemon persistant).
Utilisation : Scripts de configuration, tâches ponctuelles.
Type=notify¶
Le service notifie systemd quand il est prêt via sd_notify().
Utilisation : Applications qui supportent la notification systemd (nginx, PostgreSQL...).
Type=dbus¶
Le service est considéré prêt quand il acquiert un nom D-Bus.
Utilisation : Services D-Bus.
Type=idle¶
Retarde le démarrage jusqu'à ce que tous les autres services soient lancés.
Utilisation : Rare, pour des services qui doivent démarrer en dernier.
Commandes d'exécution¶
- ExecStart
-
Commande principale de démarrage (obligatoire sauf pour Type=oneshot)
- ExecStartPre / ExecStartPost
-
Commandes à exécuter avant/après le démarrage
- ExecReload
-
Commande pour recharger la configuration sans redémarrer
- ExecStop
-
Commande pour arrêter proprement le service
- ExecStopPost
-
Commandes après l'arrêt (nettoyage)
Redémarrage automatique¶
- Restart
-
Politique de redémarrage automatique
Valeurs possibles :
no: Jamais redémarrer (défaut)always: Toujours redémarreron-success: Redémarrer si terminé avec succèson-failure: Redémarrer en cas d'échecon-abnormal: Redémarrer si terminé anormalementon-abort: Redémarrer si terminé par signalon-watchdog: Redémarrer si watchdog timeout
- RestartSec
-
Délai avant redémarrage
- StartLimitBurst / StartLimitIntervalSec
-
Protection contre les boucles de redémarrage
Identité et permissions¶
- User / Group
-
Utilisateur et groupe sous lesquels exécuter le service
- DynamicUser
-
Crée automatiquement un utilisateur temporaire
Répertoires de travail¶
- WorkingDirectory
-
Répertoire de travail du processus
- RootDirectory / RootImage
-
Changement de racine (chroot)
Variables d'environnement¶
- Environment
-
Définir des variables
- EnvironmentFile
-
Charger des variables depuis un fichier
Contenu de /etc/myapp/env :
Limites de ressources¶
- LimitNOFILE / LimitNPROC
-
Limites de descripteurs de fichiers et processus
- MemoryLimit / CPUQuota
-
Limites mémoire et CPU
Timeouts¶
- TimeoutStartSec
-
Timeout pour le démarrage
- TimeoutStopSec
-
Timeout pour l'arrêt
Section [Install]¶
Définit les liens de dépendances lors de l'activation.
- WantedBy
-
Target qui "veut" ce service
- RequiredBy
-
Target qui "requiert" ce service (dépendance forte)
- Alias
-
Noms alternatifs pour le service
Exemples complets¶
Service simple¶
# /etc/systemd/system/simple-webapp.service
[Unit]
Description=Simple Web Application
After=network.target
[Service]
Type=simple
User=webapp
WorkingDirectory=/opt/webapp
ExecStart=/usr/bin/python3 /opt/webapp/app.py
Restart=on-failure
[Install]
WantedBy=multi-user.target
Service avec préparation¶
# /etc/systemd/system/advanced-service.service
[Unit]
Description=Advanced Service with Setup
After=network-online.target
Wants=network-online.target
Requires=postgresql.service
After=postgresql.service
[Service]
Type=notify
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
# Préparation
ExecStartPre=/usr/bin/mkdir -p /var/run/myapp
ExecStartPre=/usr/bin/chown myapp:myapp /var/run/myapp
# Démarrage
ExecStart=/usr/bin/myapp --config /etc/myapp/config.yaml
# Rechargement
ExecReload=/bin/kill -HUP $MAINPID
# Arrêt propre
ExecStop=/usr/bin/myapp-shutdown
ExecStopPost=/usr/bin/rm -rf /var/run/myapp
# Redémarrage automatique
Restart=on-failure
RestartSec=10s
StartLimitBurst=5
StartLimitIntervalSec=120s
# Environnement
EnvironmentFile=/etc/myapp/environment
Environment="LOG_LEVEL=info"
# Ressources
LimitNOFILE=32768
MemoryLimit=4G
# Timeouts
TimeoutStartSec=60s
TimeoutStopSec=30s
[Install]
WantedBy=multi-user.target
Service avec isolation de sécurité¶
# /etc/systemd/system/secure-service.service
[Unit]
Description=Secure Isolated Service
After=network.target
[Service]
Type=simple
# Utilisateur dynamique
DynamicUser=yes
# Commande
ExecStart=/usr/bin/secure-app
# Isolation
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/secure-app
# Sécurité
NoNewPrivileges=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictRealtime=yes
RestrictNamespaces=yes
# Syscalls
SystemCallFilter=@system-service
SystemCallErrorNumber=EPERM
# Capacités
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
Service oneshot¶
# /etc/systemd/system/backup.service
[Unit]
Description=Daily Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backup
StandardOutput=journal
StandardError=journal
Utilisé avec un timer :
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily Backup Timer
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Bonnes pratiques¶
1. Toujours spécifier User/Group¶
Éviter de lancer des services en root sauf nécessaire :
2. Utiliser Restart=on-failure¶
Pour la résilience :
3. Définir des timeouts raisonnables¶
4. Utiliser Type=notify quand possible¶
Pour une détection précise de l'état "ready" :
5. Documenter le service¶
[Unit]
Description=Description claire et concise
Documentation=man:myapp(8)
Documentation=https://docs.example.com
6. Appliquer des restrictions de sécurité¶
7. Utiliser des fichiers d'environnement¶
Plutôt que d'encoder les secrets dans le fichier unité :
Débogage¶
Voir l'état détaillé¶
Voir les logs¶
journalctl -u myapp.service
journalctl -u myapp.service -f # Suivi temps réel
journalctl -u myapp.service --since "1 hour ago"
Vérifier la configuration¶
Voir la configuration effective¶
Recharger après modification¶
Variables spéciales¶
systemd fournit des variables utilisables dans les commandes :
%n: Nom complet de l'unité%N: Nom sans le suffixe de type%p: Nom préfixe (avant @)%i: Instance (après @)%I: Instance unescaped%u: Nom d'utilisateur%U: UID%h: Home directory%s: Shell de l'utilisateur%t: Runtime directory (/run)%S: State directory (/var/lib)
Exemple :
Les services sont le cœur de systemd. Maîtriser leur configuration est essentiel pour administrer efficacement un système Linux moderne.