Bootcode — Administration Système
ps, top, htop, kill, systemd, journalctl, cron
Utilisez les flèches, cliquez ou glissez pour naviguer
1. Lister et inspecter les processus
ps, top, htop — comprendre ce qui tourne
2. Envoyer des signaux aux processus
kill, SIGTERM, SIGKILL, SIGHUP
3. Gérer foreground/background
&, Ctrl+Z, bg, fg, nohup
4. Créer un service systemd
Unit file, start, stop, enable
5. Consulter les logs avec journalctl
Filtrage par service, date, priorité
6. Planifier avec cron
Tâches récurrentes, crontab
Les processus (PID, ps, top, htop)
Qu'est-ce qu'un processus, arbre, inspecter
Signaux Unix
SIGTERM, SIGKILL, SIGHUP — quand utiliser lequel
Foreground, Background, Jobs
&, Ctrl+Z, bg, fg, nohup
systemd — Le gestionnaire de services
Units, services, timers, créer un .service
journalctl — Les logs systemd
Consulter, filtrer par service, date, priorité
cron — Tâches planifiées
Syntaxe crontab, exemples concrets
Live Coding
Créer un service systemd pour une app Node.js
Hier on a scripté en Bash
Variables, conditions, boucles, fonctions — on sait écrire des scripts
Aujourd'hui : gérer ce qui tourne sur un serveur
Un script, ça s'exécute. Mais comment on le lance, on l'arrête, on le surveille, on le relance au boot ?
#!/bin/bash
# Mon script tourne... mais qui le gère ?
# Comment je l'arrête proprement ?
# Comment je le relance automatiquement ?
La réponse : processus + signaux + systemd + cron
Les processus
Un processus = un programme en cours d'exécution
Chaque processus a un PID unique (Process IDentifier)
PID (Process ID)
Identifiant unique du processus
PPID (Parent PID)
PID du parent qui a créé ce processus
systemd (PID 1)
└── sshd (PID 100)
└── bash (PID 200)
└── node app.js (PID 300)
// Chaque processus a un parent
// Sauf le PID 1 (systemd)
💡 pstree permet de visualiser l'arbre complet
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 9876 5432 ? Ss Jan01 0:02 /sbin/init
root 100 0.0 0.1 6543 2100 ? Ss Jan01 0:01 sshd: /usr/sbin/sshd
gili 200 0.0 0.0 4321 1234 pts/0 Ss 09:00 0:00 -bash
gili 300 0.5 1.2 50000 25000 pts/0 Sl 09:05 0:03 node app.js
USER
Propriétaire
PID
ID du processus
%CPU / %MEM
Utilisation CPU / RAM
COMMAND
La commande lancée
💡 ps aux | grep node — filtrer pour trouver un processus spécifique
VSZ
Mémoire virtuelle allouée (Ko)
RSS
Mémoire physique utilisée (Ko)
STAT
État : S (sleep), R (running), Z (zombie)
TTY
Terminal associé (? = daemon)
Variantes utiles :
ps ef — affichage complet avec arbre
ps aux --sort=-%mem — trié par mémoire
ps aux --sort=-%cpu — trié par CPU
$ top
top - 09:15:00 up 3 days, 1 user, load average: 0.08, 0.03, 0.01
Tasks: 123 total, 1 running, 122 sleeping
%Cpu(s): 2.5 us, 1.2 sy, 0.0 ni, 96.0 id
MiB Mem : 7800 total, 3200 free, 2000 used
MiB Swap: 2048 total, 2048 free, 0 used
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
300 gili 20 0 50000 25000 12000 S 0.5 1.2 0:03.45 node
Raccourcis top
q quitter
k tuer un processus
M trier par mémoire
P trier par CPU
Load average
Moyenne processus en attente
1 min / 5 min / 15 min
< nb cœurs = ok
Statuts CPU
us = utilisateur
sy = système
id = inactif
✅ Interface colorée
Barres de CPU par cœur
✅ Navigation avec les flèches
Sélectionner / tuer à la souris
✅ Arbre des processus (F5)
Visualisation hiérarchique
✅ Filtre (F4) et recherche (F3)
Trouver un processus rapidement
$ htop
1[████████████░░░░░░░] 45%
2[███████░░░░░░░░░░░░] 25%
Mem[████████████████░░░░] 2.0G/7.8G
Swp[░░░░░░░░░░░░░░░░░░░░] 0K/2.0G
PID USER PRI NI CPU% MEM% TIME+ COMMAND
300 gili 20 0 2.5 1.2 0:03 node app.js
💡 htop n'est pas installé par défaut — sudo apt install htop
Les signaux Unix
Un signal = un message envoyé à un processus
Pour lui demander de s'arrêter, se recharger, ou réagir
SIGTERM (15)
"Tu veux bien t'arrêter s'il te plaît ?" — Demande polie
Le processus peut nettoyer, fermer les fichiers, puis s'arrêter
kill 300
SIGKILL (9)
"TU MEURS. MAINTENANT." — Exécution immédiate
Le noyau tue le processus sans préavis. Aucun nettoyage possible.
kill -9 300
SIGHUP (1)
Déconnexion du terminal — ou "recharge ta config"
Beaucoup de daemons (nginx, sshd) rechargent leur config sur SIGHUP
kill -HUP $(cat /var/run/nginx.pid)
SIGINT (2)
Interruption — envoyé par Ctrl+C
SIGSTOP (19)
Pause forcée — envoyé par Ctrl+Z
SIGCONT (18)
Reprise après SIGSTOP — bg / fg
SIGUSR1 (10)
Signal utilisateur — chaque app décide de l'action
# Lister tous les signaux disponibles
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT ... 9) SIGKILL ... 15) SIGTERM
❌ Le réflexe kill -9
Beaucoup d'étudiants font kill -9 PID systématiquement
C'est comme débrancher la prise au lieu d'éteindre proprement
✅ La bonne pratique
1️⃣ kill PID → SIGTERM (demande polie)
← Attendre quelques secondes
2️⃣ kill -9 PID → SIGKILL (si le processus ne répond pas)
💡 Pourquoi c'est dangereux ?
Corruption de fichiers, données non sauvegardées, connexions fermées brutalement
Foreground / Background / Jobs
Un processus peut tourner au premier plan ou en arrière-plan
& — Lancer en arrière-plan
$ node server.js &
[1] 1234
Ctrl+Z — Mettre en pause (SIGSTOP)
Le processus est mis en pause — il ne consomme pas de CPU
bg
Reprendre en arrière-plan (SIGCONT)
fg
Reprendre au premier plan
# Workflow typique :
$ node server.js
Ctrl+Z
[1]+ Stopped node server.js
$ bg
[1]+ node server.js &
$ jobs
[1]+ Running node server.js &
jobs
Lister les processus du shell courant
$ jobs
[1] Running node server.js &
[2]- Running python app.py &
[3]+ Stopped vim main.js
+ = dernier job en bg | - = avant-dernier
nohup
Protège le processus contre le signal SIGHUP
🔹 Quand tu fermes un terminal, le shell envoie SIGHUP à tous ses enfants
🔹 Sans nohup → le processus meurt avec le terminal
🔹 Avec nohup → le processus continue même après fermeture
$ nohup node server.js &
nohup: ignoring input and appending output to 'nohup.out'
$ exit # ferme le terminal
# Le processus tourne toujours !
👉 nohup.out contient stdout / stderr
👉 Sinon : nohup ... > output.log 2>&1 &
💡 nohup + & = "lance et oublie" — idéal pour du dev, mais pour la prod on utilise systemd
systemd — Le gestionnaire de services
L'init system standard sur toutes les distributions modernes
Ubuntu, Debian, Fedora, Arch, Rocky Linux...
systemctl start mon-app
Démarrer le service maintenant
systemctl stop mon-app
Arrêter le service
systemctl restart mon-app
Redémarrer le service
systemctl status mon-app
Voir l'état du service (actif, échec...)
$ systemctl status mon-app
● mon-app.service - Mon Application Node.js
Loaded: loaded (/etc/systemd/system/mon-app.service; enabled)
Active: active (running) since Mon 2026-06-01 08:30:00 UTC
Main PID: 1234 (node)
Status: "Server is running on port 3000"
❌ Confusion fréquente
$ systemctl enable mon-app
// "Ça doit tourner non ?"
// Non ! Enable ≠ start
enable = démarrage automatique au boot
start = démarrage immédiat
✅ La bonne séquence
$ sudo systemctl enable mon-app
// Au démarrage de la machine
$ sudo systemctl start mon-app
// Tout de suite maintenant
👉 La plupart du temps on fait les deux :
sudo systemctl enable --now mon-app
Un fichier de déclaration — pas un script d'exécution
[Unit]
Description=Mon Application Node.js
After=network.target
[Service]
Type=simple
User=gili
WorkingDirectory=/home/gili/app
ExecStart=/usr/bin/node server.js
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Emplacement : /etc/systemd/system/mon-app.service
[Unit]
Description — Texte lisible par l'humain
After — Attendre que network.target soit prêt
[Service]
Type=simple — Le processus principal est lancé directement
User — Ne pas tourner en root !
ExecStart — La commande à exécuter (chemin absolu)
Restart=on-failure — Redémarrer automatiquement en cas de crash
RestartSec=5 — Attendre 5s avant de redémarrer
[Install]
WantedBy=multi-user.target — Démarrer au boot (runlevel 3-5)
💡 Restart=on-failure est le secret des services robustes en production
❌ Après avoir modifié un .service
$ sudo systemctl start mon-app
Failed to start mon-app.service: Unit not found
systemd ne sait pas que le fichier a changé
✅ La bonne séquence
1️⃣ sudo nano /etc/systemd/system/mon-app.service
2️⃣ sudo systemctl daemon-reload
← systemd relit tous les fichiers .service
3️⃣ sudo systemctl restart mon-app
journalctl — Les logs systemd
Le journal centralisé de systemd
Fini les fichiers /var/log/*.log éparpillés
journalctl
Tous les logs (depuis le boot)
journalctl -u mon-app
Logs d'un service spécifique
journalctl -f
Follow — mode live (comme tail -f)
journalctl -fu mon-app
🔴 La commande la plus utile en production
💡 journalctl -fu mon-app — suivi en direct des logs d'un service
Utile pour debugguer un crash, vérifier que tout va bien après un restart
Par date
journalctl --since "2026-06-01 08:00:00"
journalctl --since "today" --until "now"
journalctl --since "-1 hour"
Par priorité (niveau de log)
journalctl -u mon-app -p err
# Niveaux : emerg, alert, crit, err, warning, notice, info, debug
journalctl -u mon-app -p warning
Autres filtres
journalctl -u mon-app --no-pager
# Sans pagination
journalctl -u mon-app -n 50
# Dernières 50 lignes
journalctl --list-boots
# Liste les démarrages
# Le service crash au démarrage :
$ sudo journalctl -u mon-node-app -p err --since "5 min ago"
Jun 01 09:15:00 serveur node[1234]: Error: Cannot find module 'express'
Jun 01 09:15:00 serveur systemd[1]: mon-node-app.service: Main process exited, code=exited, status=1/FAILURE
Jun 01 09:15:00 serveur systemd[1]: mon-node-app.service: Failed with result 'exit-code'.
Jun 01 09:15:05 serveur systemd[1]: mon-node-app.service: Scheduled restart job, restart counter started at 1.
Jun 01 09:15:05 serveur systemd[1]: mon-node-app.service: Failed with result 'exit-code'.
👉 Immédiatement visible : "Cannot find module 'express'" — npm install manquant
On voit aussi que Restart=on-failure tente de relancer
cron — Planifier des tâches
Exécuter un script de façon récurrente
Toutes les heures, chaque jour à minuit, tous les lundis...
crontab -e
Éditer sa crontab personnelle
crontab -l
Lister ses tâches planifiées
crontab -r
Supprimer toutes ses tâches
/etc/crontab
Crontab système (pour root)
# Crontab exemple :
# m h dom mon dow command
0 2 * * * /home/gili/scripts/backup.sh
↑ Tous les jours à 2h du matin
*/5 * * * * /home/gili/scripts/healthcheck.sh
↑ Toutes les 5 minutes
* * * * * commande
min
0-59
heure
0-23
jour
1-31
mois
1-12
sem
0-7 (0=Dimanche)
*/5 — tous les 5 (pas de 5)
1,15 — à la 1ʳᵉ et 15ᵉ minute
9-17 — de 9h à 17h (inclus)
💡 Utilisez crontab.guru pour vérifier votre syntaxe !
0 2 * * * /scripts/backup.sh
Tous les jours à 2h — backup quotidien
*/5 * * * * /scripts/health.sh
Toutes les 5 min — vérification de santé
0 9 * * 1 /scripts/rapport.sh
Tous les lundis à 9h — rapport hebdomadaire
0 0 1 * * /scripts/cleanup.sh
Le 1er du mois à minuit — nettoyage mensuel
@reboot /scripts/startup.sh
Au démarrage — tâche spéciale cron
❌ Erreurs fréquentes
* 2 * * *
// "Toutes les 2 heures" ? Non, "à 2h (minute 0-59)"
0 * * * *
// "Toutes les heures" ? Oui ✅
* 9 * * *
// "À 9h" ? Oui... toutes les minutes de 9h à 9h59 !
→ 0 9 * * * = À 9h pile
✅ Le réflexe : crontab.guru
Avant d'ajouter une tâche, tapez votre syntaxe sur crontab.guru
Il vous dit en français à quand correspond votre expression
# Vérifier que cron tourne :
$ systemctl status cron
# Voir les logs des tâches cron :
$ journalctl -u cron -p info --since today
Live Coding
Créer un service systemd pour une app Node.js
De zéro à un service qui se relance tout seul
1️⃣ Créer une app Node.js
$ mkdir ~/mon-app && cd ~/mon-app
$ npm init -y
$ npm install express
2️⃣ Créer server.js
const express = require('express');
const app = express();
const PORT = 3000;
app.get('/', (req, res) => {
res.send('Hello from systemd!');
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
3️⃣ Créer le fichier .service
$ sudo nano /etc/systemd/system/mon-node-app.service
[Unit]
Description=Mon App Node.js boostée par systemd
After=network.target
[Service]
Type=simple
User=gili
WorkingDirectory=/home/gili/mon-app
ExecStart=/usr/bin/node /home/gili/mon-app/server.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
4️⃣ Recharger, activer, démarrer
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mon-node-app
5️⃣ Vérifier
$ sudo systemctl status mon-node-app
● mon-node-app.service - Mon App Node.js boostée par systemd
Active: active (running)
$ curl http://localhost:3000
Hello from systemd!
6️⃣ Tester le redémarrage automatique
$ sudo kill -9 $(pgrep -f server.js)
// Attendre 5 secondes (RestartSec=5)
$ sudo systemctl status mon-node-app
Active: active (running) — redémarré !
# Créer un script de vérification
$ nano ~/scripts/healthcheck.sh
#!/bin/bash
if curl -sf http://localhost:3000 > /dev/null; then
echo "$(date) - OK" >> /var/log/healthcheck.log
else
echo "$(date) - DOWN!" >> /var/log/healthcheck.log
sudo systemctl restart mon-node-app
fi
# Ajouter dans crontab :
$ crontab -e
*/5 * * * * /home/gili/scripts/healthcheck.sh
// Vérifier toutes les 5 minutes
ps aux — voir les processus
PID, %CPU, %MEM, COMMAND
SIGTERM avant SIGKILL
kill PID puis kill -9 PID si nécessaire
nohup + & = lance et oublie
Mais pour la prod → systemd
systemd = le standard
start ≠ enable, daemon-reload obligatoire
journalctl -fu <service>
La commande de debug en production
crontab.guru pour cron
Vérifiez toujours votre syntaxe
Processus
ps aux, top, htop
kill, SIGTERM, SIGKILL
systemd
service start/stop/enable
journalctl -fu service
cron
crontab -e
Syntaxe : m h dom mon dow
La gestion des processus, systemd et cron sont les 3 piliers
de l'administration serveur en production
Processus, signaux, systemd, journalctl, cron
Prochaine étape : Mettre en production avec Docker
ps → systemd → Docker → Kubernetes