systemd — systemctl, journalctl, unités, timers
Référence rapide pour gérer des services, lire des logs et configurer des tâches planifiées sous systemd.
systemctl — commandes principales
# Démarrer / arrêter / redémarrer / recharger la config
systemctl start mon-service
systemctl stop mon-service
systemctl restart mon-service
systemctl reload mon-service # relecture de la config (pas de redémarrage)
# État d'un service
systemctl status mon-service
systemctl is-active mon-service
systemctl is-enabled mon-service
# Activer au démarrage (permanent)
systemctl enable mon-service
systemctl disable mon-service
systemctl enable --now mon-service # active ET démarre d'un coup
# Voir les dépendances (les services lancés AVANT celui-ci)
systemctl list-dependencies mon-service
# Liste toutes les unités
systemctl list-units --type=service
systemctl list-unit-files --type=service
systemctl list-units --all # inclut les unités échouées/activées
# Redémarrer le démon systemd (après modification de fichiers unit)
systemctl daemon-reloadBon à savoir :
systemctl daemon-reloadest indispensable après toute modification d’un fichier.service,.timerou.socketdans/etc/systemd/system/. Sans cela, systemd garde l’ancienne configuration en mémoire.
Fichier unité (.service) — structure minimale
[Unit]
Description=Mon service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/mon-app --port 8080
Restart=on-failure
RestartSec=5
User=appuser
Group=appuser
WorkingDirectory=/opt/mon-app
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.targetTypes de service
| Type | Quand l’utiliser |
|---|---|
simple (défaut) | Le processus principal reste en premier plan (ex. Node, Python) |
forking | Le daemon se détache (ex. nginx, crond) — Type=forking |
oneshot | Exécution unique puis arrêt (ex. scripts d’initialisation) |
notify | Le processus notifie systemd quand il est prêt via sd_notify |
journalctl — lecture des logs
# Logs d'un service spécifique
journalctl -u mon-service
# Suivi en temps réel (comme tail -f)
journalctl -f -u mon-service
# Logs de la session courante
journalctl -b
# Dernières 50 lignes
journalctl -n 50 -u mon-service
# Période spécifique
journalctl --since "2024-01-15 08:00:00" --until "2024-01-15 09:00:00"
journalctl --since yesterday --until today
# Filtre par niveau de sévérité (0=emerg .. 7=debug)
journalctl -p err -u mon-service
journalctl -p warning -u mon-service
# Sortie JSON (utile pour du parsing)
journalctl -o json -u mon-service
# Supprimer les logs anciens (irréversible sans sauvegarde)
sudo journalctl --vacuum-size=100M # garder les 100 Mo les plus récentsPiège : par défaut, journalctl conserve 4 Go de données. Sur un serveur peu stocké, nettoyer régulièrement avec
--vacuum-sizeou configurerSystemMaxUse=dansjournal.conf.
systemd timers — tâches planifiées
Un timer remplace cron pour les tâches critiques (journaling natif, récupération après panne, pas de problème de PATH).
Exemple : tous les jours à 3h du matin
Fichier /etc/systemd/system/backup.timer :
[Unit]
Description=Backup quotidien à 3h
[Timer]
OnCalendar=*-*-* 03:00:00
Persistent=true
AccuracySec=1min
[Install]
WantedBy=timers.targetFichier /etc/systemd/system/backup.service :
[Unit]
Description=Exécution du backup
[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh# Activer et lancer le timer
systemctl enable --now backup.timer
# Vérifier le prochain lancement
systemctl list-timers
# Déclencher manuellement sans attendre
systemctl start backup.serviceSyntaxe OnCalendar
| Syntaxe | Sens |
|---|---|
*-*-* 03:00:00 | Tous les jours à 3h |
Mon *-*-* 08:00:00 | Lundi à 8h |
*-*-01 00:00:00 | 1er de chaque mois |
weekly | Semaine prochaine, à minuit (défaut) |
hourly | Chaque heure à la XXe minute (défaut : XX:00) |
daily | Quotidien à minuit |
monthly | 1er du mois à minuit |
OnBootSec=5min | 5 minutes après le démarrage |
OnUnitActiveSec=1h | 1h après chaque exécution terminée |
Persistent=true: si le timer a manqué son créneau (machine éteinte), systemd exécute la tâche au prochain démarrage. Sans ce paramètre, le créneau est perdu.
Socket activation — service à la demande
systemd peut lancer un service uniquement quand une requête arrive sur un port, au lieu de le garder en mémoire 24/7.
# /etc/systemd/system/mon-sock.service
[Unit]
Description=Mon service
[Service]
ExecStart=/usr/local/bin/mon-app
# /etc/systemd/system/mon-sock.socket
[Unit]
Description=Socket pour mon service
[Socket]
ListenStream=8080
Accept=no
[Install]
WantedBy=sockets.targetsystemctl enable --now mon-sock.socket
# Le service se lance à la première connexion sur le port 8080Avantage : pas de process en attente inutile. Idéal pour des services qui ne reçoivent que peu de trafic ou dont le démarrage est long.
Pièges courants
| Piège | Symptôme | Solution |
|---|---|---|
| Variable d’environnement manquante | Script fonctionne en SSH, échoue comme service | Utiliser EnvironmentFile=/etc/default/mon-service ou Environment=VAR=valeur dans le fichier unité |
| Non-reload après édition | Modifications ignorées | systemctl daemon-reload puis systemctl restart mon-service |
| Journal qui grossit | Espace disque saturé | journalctl --vacuum-size=200M ou configurer SystemMaxUse=200M dans /etc/systemd/journald.conf |
Service en état activating | Le service ne démarre jamais | Consulter journalctl -u mon-service --no-pager pour le détail de l’erreur |
| Dépendance circulaire | Boot bloqué | systemctl list-dependencies --reverse mon-service et revoir l’ordre dans After= / Before= |
| Permissions utilisateur | Permission denied | Vérifier User= et Group= dans [Service], et les droits sur WorkingDirectory= |
Type=simple avec daemon qui fork | systemd considère que le service est arrêté immédiatement | Passer à Type=forking ou utiliser ExecStartPre= pour fork via daemonize |
| Logs en anglais | Difficiles à comprendre | Vérifier que le service utilise bien l’environnement LANG attendu ; certains langages ignorent les variables système |
Quick Reference
| Besoin | Commande |
|---|---|
| Relancer un service | systemctl restart <nom> |
| Activer au démarrage | systemctl enable <nom> |
| Activer + démarrer | systemctl enable --now <nom> |
| Voir les logs en direct | journalctl -f -u <nom> |
| Dernières erreurs d’un service | journalctl -p err -u <nom> --no-pager |
| Vérifier qu’un timer est actif | systemctl list-timers |
| Déclencher un timer manuellement | systemctl start <timer>.timer |
| Service au démarrage après le réseau | After=network.target |
| Arrêter le démon systemd (reload) | systemctl daemon-reload |
| Rediriger les logs vers un fichier | ExecStartPost=/bin/sh -c "exec >> /var/log/mon.log 2>&1" |
Consulté chaque fois qu’on oublie le lien entre systemctl et journalctl — parce que restart sans vérifier le journal, c’est comme piloter aveugle.