09 - systemd : gerer tes services comme un pro
Ce que tu vas apprendre
- Ce qu'est systemd et pourquoi il a remplace les anciens init systems
- Utiliser systemctl pour gerer les services
- Écrire un fichier unit pour déployer une app Node ou Bun
- Lire les logs avec journalctl
- Remplacer cron par des timers systemd
Prerequisites
Savoir gerer les processus Linux. Avoir un acces root ou sudo sur une machine Linux (pas macOS, systemd n'existe pas sur Mac).
J'ai longtemps déployé mes apps avec nohup node server.js & et un script de démarrage bricolé. Ca marchait... jusqu'au jour ou le serveur rebootait et plus rien ne tournait. systemd resout ce problème et bien d'autres.
systemd en deux mots
systemd est le système d'initialisation et de gestion de services de la plupart des distributions Linux modernes (Debian, Ubuntu, Fedora, Arch). Il démarré en PID 1, lance les services au boot, les surveille, les redémarre s'ils plantent, et collecte leurs logs.
Il a ses detracteurs -- certains trouvent qu'il fait trop de choses. Mais en tant que dev, c'est un outil puissant et tu vas le croiser partout.
systemctl : la telecommande
bash# Voir le statut d'un service
sudo systemctl status nginx
# Demarrer / arreter / redemarrer
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
# Recharger la config sans redemarrer (si le service le supporte)
sudo systemctl reload nginx
# Activer au demarrage / desactiver
sudo systemctl enable nginx
sudo systemctl disable nginx
# Les deux en meme temps
sudo systemctl enable --now nginx
# Lister tous les services actifs
systemctl list-units --type=service --state=running
La sortie de status est riche : elle te donne l'état du service, le PID, la mémoire utilisee, et les dernières lignes de logs. C'est souvent la première commande que je tape quand quelque chose ne marche pas.
Écrire un fichier unit pour ton app
Sur paltemps.fr, j'utilise un fichier unit systemd pour faire tourner l'application. Voici un exemple pour une app Node/Bun :
ini# /etc/systemd/system/mon-app.service
[Unit]
Description=Mon application web
After=network.target
[Service]
Type=simple
User=deploy
Group=deploy
WorkingDirectory=/opt/mon-app
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
Environment=PORT=3000
# Securite
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/mon-app/data
# Logs
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mon-app
[Install]
WantedBy=multi-user.target
Decortiquons les sections :
[Unit] decrit le service. After=network.target dit a systemd d'attendre que le réseau soit disponible avant de lancer le service.
[Service] definit comment lancer et surveiller le processus. Restart=on-failure relance automatiquement si le processus plante (code de sortie non nul). RestartSec=5 attend 5 secondes avant de relancer, pour éviter une boucle infernale.
[Install] definit quand le service démarré. WantedBy=multi-user.target signifie "au boot, quand le système est en mode multi-utilisateur" (le cas normal).
bash# Apres avoir cree ou modifie le fichier
sudo systemctl daemon-reload
# Demarrer et activer
sudo systemctl enable --now mon-app
# Verifier
sudo systemctl status mon-app
Pour Bun, remplace juste la ligne ExecStart :
iniExecStart=/usr/local/bin/bun run server.ts
journalctl : les logs centralises
systemd collecte tous les logs de tous les services dans le journal. Plus besoin de chercher dans dix fichiers différents :
bash# Logs d'un service precis
journalctl -u mon-app
# Suivre en temps reel (comme tail -f)
journalctl -u mon-app -f
# Depuis une date
journalctl -u mon-app --since "2026-03-29 10:00:00"
# Les 30 dernieres minutes
journalctl -u mon-app --since "30 min ago"
# Uniquement les erreurs
journalctl -u mon-app -p err
# Combiner : erreurs du dernier jour, en temps reel
journalctl -u mon-app -p err --since today -f
# Espace disque utilise par les logs
journalctl --disk-usage
# Nettoyer les vieux logs (garder 500 Mo max)
sudo journalctl --vacuum-size=500M
Le flag -p accepte les niveaux syslog : emerg, alert, crit, err, warning, notice, info, debug. Tres pratique pour filtrer le bruit.
Les timers systemd : le cron moderne
systemd propose une alternative a cron avec les timers. L'avantage : les logs sont dans journalctl, tu peux voir l'historique des executions, et la syntaxe est plus lisible.
Un timer a besoin de deux fichiers : un .service qui definit quoi lancer, et un .timer qui definit quand.
ini# /etc/systemd/system/backup-db.service
[Unit]
Description=Backup de la base de donnees
[Service]
Type=oneshot
User=deploy
ExecStart=/opt/scripts/backup-db.sh
ini# /etc/systemd/system/backup-db.timer
[Unit]
Description=Backup quotidien de la base de donnees
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
bash# Activer le timer
sudo systemctl enable --now backup-db.timer
# Verifier les timers actifs
systemctl list-timers --all
# Voir quand le prochain declenchement aura lieu
systemctl status backup-db.timer
Persistent=true est une perle : si la machine etait eteinte au moment prevu, le timer s'exécuté des que possible apres le redemarrage. Cron ne fait pas ca.
La syntaxe OnCalendar est flexible :
OnCalendar=hourly # Toutes les heures
OnCalendar=daily # Tous les jours a minuit
OnCalendar=weekly # Toutes les semaines
OnCalendar=Mon *-*-* 09:00 # Chaque lundi a 9h
OnCalendar=*-*-01 00:00:00 # Le premier de chaque mois
Résumé
systemctl status/start/stop/restart/enablepour gerer les services- Un fichier
.servicedans/etc/systemd/system/pour déployer ton app Restart=on-failurepour la resilience automatiquejournalctl -u service -fpour suivre les logs en temps réel- Les timers systemd remplacent cron avec plus de contrôle et de visibilité
Article précédent : Les processus Article suivant : Le réseau