📍 Article principal du cluster : Automatisation pour PME ouest-africaines : le guide complet 2026
Ce tutoriel fait partie du cluster « Automatisation ». Pour la vue d’ensemble (no-code, n8n, scripts, IA agents), commencer par le pilier.
Introduction
Une PME sénégalaise héberge son site WordPress et son outil de facturation sur un VPS Hetzner à Helsinki. Chaque nuit, la base MySQL doit être sauvegardée vers un Storage Box, les logs de la veille doivent être archivés, le certificat Let’s Encrypt doit être vérifié, et un rapport doit être envoyé par email à l’admin. Faire tout cela manuellement n’a aucun sens — c’est exactement le terrain de chasse de cron et des timers systemd.
Ce tutoriel pas-à-pas couvre les deux mécanismes que tout sysadmin Linux doit maîtriser pour planifier des tâches récurrentes en 2026 : cron, le grand classique disponible depuis les années 70, et systemd timers, le remplaçant moderne livré avec systemd qui équipe la majorité des distributions Linux actuelles. À la fin, vous saurez choisir l’un ou l’autre selon le contexte, écrire vos premières unités, debugger les échecs et surveiller l’exécution.
Prérequis
- Un serveur Linux (Ubuntu 22.04 ou 24.04 LTS, Debian 12, AlmaLinux 9, ou équivalent) — VPS Hetzner CX22 idéal
- Accès SSH avec un utilisateur ayant les droits sudo
- Notions de base de la ligne de commande Linux (
cd,cat,nano,chmod) - Un script ou une commande à automatiser pour s’exercer (un simple
echodans un fichier suffit pour démarrer) - Temps estimé : 1 h 30 pour parcourir le tutoriel, 3 h pour mettre en place vos premières tâches en production
Étape 1 — Comprendre la différence entre cron et systemd timers
Avant d’écrire la première ligne, il faut comprendre pourquoi on a deux outils qui font apparemment la même chose. Cron a été inventé en 1975 et n’a quasiment pas bougé depuis. Sa simplicité est sa force : une ligne dans un fichier, et la tâche est planifiée. systemd timers, arrivé en 2013 avec systemd 197, propose une approche plus verbeuse mais beaucoup plus puissante : journalisation centralisée dans journalctl, gestion des dépendances entre services, exécution rattrapée en cas de coupure (Persistent=true), randomisation pour éviter les pics de charge.
En pratique, en 2026, cron reste parfait pour les tâches simples, isolées, qu’on veut écrire vite et oublier. systemd timers devient le bon choix dès qu’on veut de la traçabilité, qu’on est dans un environnement avec des coupures électriques fréquentes (cas typique au Sénégal ou au Mali, même sur VPS européen — pour les jobs qui dépendent d’un service local en panne), ou qu’on a besoin d’orchestrer une tâche avec d’autres unités systemd. Sur un serveur cloud moderne, beaucoup d’admins migrent progressivement vers systemd timers pour bénéficier de la consolidation des logs.
Étape 2 — Premiers pas avec cron
Cron lit deux types de fichiers : les crontabs personnelles (une par utilisateur, éditées via crontab -e) et les fichiers système dans /etc/cron.d/, /etc/cron.daily/, etc. Pour un usage PME, on travaille presque toujours en crontab personnelle de l’utilisateur applicatif (jamais root sauf strict besoin), avec une syntaxe qui n’a pas changé depuis quarante ans.
Lancez l’éditeur de votre crontab utilisateur :
crontab -e
# La première fois, choisir nano (option 1) si proposé
Au-dessus du fichier, vous voyez un rappel commenté de la syntaxe à 5 champs : minute, heure, jour-du-mois, mois, jour-de-la-semaine. Ajoutez à la fin du fichier une première tâche de test qui écrit l’heure dans un fichier toutes les minutes :
# Test : écrire l'heure dans /tmp/cron-test.log toutes les minutes
* * * * * date >> /tmp/cron-test.log 2>&1
Sauvegardez (Ctrl+O puis Entrée dans nano) et quittez (Ctrl+X). Cron prend en compte la modification immédiatement, sans rechargement nécessaire. Attendez deux minutes puis vérifiez :
cat /tmp/cron-test.log
# Devrait afficher 1 ou 2 lignes avec la date courante
Si vous voyez des lignes apparaître, votre cron fonctionne. La redirection 2>&1 capture aussi les erreurs — sans elle, cron envoie les erreurs par email local, ce qui finit en silence si /var/spool/mail/ n’est pas surveillé. Une fois validé, retirez cette ligne de test (crontab -e, supprimer la ligne, sauvegarder).
Étape 3 — Écrire un vrai job cron de sauvegarde
Le cas typique d’usage en PME : une sauvegarde nocturne de la base MySQL d’un site WordPress. On écrit d’abord le script qui fait le travail, puis on le planifie. Créez le fichier /home/admin/scripts/backup-mysql.sh avec le contenu suivant (adaptez le nom de la base et l’utilisateur MySQL) :
#!/bin/bash
set -euo pipefail
DB_NAME="wordpress"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=14
mkdir -p "$BACKUP_DIR"
mysqldump --single-transaction --quick \
-u backup_user -p"$MYSQL_BACKUP_PASS" "$DB_NAME" \
| gzip > "$BACKUP_DIR/${DB_NAME}-${DATE}.sql.gz"
# Suppression des sauvegardes anciennes
find "$BACKUP_DIR" -name "${DB_NAME}-*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "$(date) — backup OK : ${DB_NAME}-${DATE}.sql.gz"
Cette routine fait trois choses : elle exporte la base avec mysqldump en mode transactionnel (sans verrouiller les tables, important pour ne pas couper le site pendant le dump), elle compresse à la volée pour économiser l’espace, et elle purge les sauvegardes de plus de 14 jours pour éviter de saturer le disque. La variable $MYSQL_BACKUP_PASS doit être positionnée dans l’environnement — jamais en dur dans le script. Rendez le script exécutable et planifiez-le :
chmod +x /home/admin/scripts/backup-mysql.sh
crontab -e
# Ajouter à la fin :
MYSQL_BACKUP_PASS=votre-mot-de-passe-base
30 2 * * * /home/admin/scripts/backup-mysql.sh >> /var/log/backup-mysql.log 2>&1
La tâche s’exécute désormais chaque nuit à 2 h 30, et les logs s’accumulent dans /var/log/backup-mysql.log. Au matin, un tail -n 5 /var/log/backup-mysql.log confirme que tout s’est bien passé. Pour aller plus loin sur le scripting Bash de production (gestion d’erreurs, notifications, monitoring), voir le tutoriel frère à venir Bash scripting pour sysadmin.
Étape 4 — Migrer vers un systemd timer
Reprenons exactement le même besoin avec systemd timers, pour comparer. Un timer systemd se compose de deux fichiers : une unit service qui décrit la tâche à exécuter, et un unit timer qui décrit quand l’exécuter. Cette séparation, qui paraît verbeuse au premier abord, devient un atout : on peut déclencher manuellement le service avec systemctl start mysql-backup.service sans dépendre de l’horaire planifié.
Créez d’abord le fichier de service /etc/systemd/system/mysql-backup.service :
[Unit]
Description=Sauvegarde nocturne de la base MySQL WordPress
After=mysql.service network-online.target
Wants=network-online.target
[Service]
Type=oneshot
User=admin
EnvironmentFile=/etc/default/mysql-backup
ExecStart=/home/admin/scripts/backup-mysql.sh
[Install]
WantedBy=multi-user.target
Le bloc [Service] précise que la tâche est ponctuelle (oneshot), exécutée par l’utilisateur admin non-root, et qu’elle lit ses variables d’environnement depuis /etc/default/mysql-backup — un fichier protégé en chmod 600 que vous créez avec MYSQL_BACKUP_PASS=.... Cette séparation des secrets est plus propre que de coller le mot de passe dans la crontab.
Créez ensuite le fichier timer /etc/systemd/system/mysql-backup.timer :
[Unit]
Description=Lance mysql-backup.service chaque nuit à 2h30
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
Trois directives clés ici. OnCalendar utilise une syntaxe plus lisible que cron — voir man systemd.time pour toutes les variantes (daily, weekly, expressions complexes). Persistent=true rattrape l’exécution si le serveur était éteint au moment prévu — comportement précieux pour un serveur sujet aux coupures. RandomizedDelaySec=300 ajoute jusqu’à 5 minutes de délai aléatoire, utile pour éviter qu’une flotte de serveurs se synchronise sur la même seconde et sature un service partagé.
Activez et démarrez le timer :
sudo systemctl daemon-reload
sudo systemctl enable --now mysql-backup.timer
systemctl status mysql-backup.timer
systemctl list-timers --all | grep mysql-backup
La dernière commande affiche la prochaine exécution prévue. Le timer est désormais actif et survit aux redémarrages. Pour tester manuellement le service sans attendre 2 h 30 : sudo systemctl start mysql-backup.service, puis consultez les logs avec journalctl -u mysql-backup.service -n 50.
Étape 5 — Surveiller, débugger, alerter
Un job qui tourne et qui échoue silencieusement est pire qu’un job qui ne tourne pas — la PME croit être protégée alors qu’elle ne l’est pas. Trois mécanismes simples mettent à l’abri.
Logs centralisés. Pour systemd, journalctl -u mysql-backup.service --since "yesterday" donne tout l’historique. Pour cron, redirigez systématiquement >> /var/log/votre-job.log 2>&1 et faites tourner logrotate pour ne pas saturer le disque. Sur un VPS modeste, ajoutez dans /etc/logrotate.d/votre-job une rotation hebdomadaire avec compression.
Alertes en cas d’échec. Avec systemd, on peut chaîner un OnFailure=alert@%n.service qui exécute un script d’alerte (envoi d’email, message Telegram, ping vers un endpoint n8n) seulement si le service échoue. Avec cron, on encapsule l’appel dans un wrapper qui teste le code de retour et notifie en cas de non-zéro. C’est précisément le type de glue que le pilier automatisation recommande de mettre en place dès le premier job critique.
Monitoring de présence. Pour les jobs vraiment critiques (sauvegardes, paiements), un dead man’s switch comme Healthchecks.io (existe en version self-hosted, gratuite) permet de recevoir une alerte si le job n’a pas tourné dans la fenêtre attendue. Le job appelle une URL en fin d’exécution ; l’absence d’appel déclenche l’alerte. C’est la garantie que vous saurez que la sauvegarde a échoué même si le serveur est totalement éteint.
Étape 6 — Vérification finale
Une fois cron ou systemd timer en place, vérifiez systématiquement avec ce protocole en 4 points avant de considérer le job comme « en production » :
- Exécution manuelle réussie — lancez le job à la main, vérifiez le résultat (fichier de sauvegarde présent, taille cohérente, contenu lisible si on décompresse).
- Exécution planifiée observée — laissez passer un cycle planifié, vérifiez les logs (
journalctloutailsur le fichier log). - Restauration testée — un backup non testé est un backup absent. Restaurez l’archive sur un serveur de test ou un dossier temporaire et vérifiez l’intégrité.
- Alerte d’échec testée — provoquez délibérément un échec (mauvais mot de passe, fichier inaccessible) et confirmez que l’alerte arrive bien.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| Le job tourne en CLI mais pas en cron | Cron a un PATH minimaliste (/usr/bin:/bin) |
Mettre en haut de crontab : PATH=/usr/local/bin:/usr/bin:/bin |
| Variables d’environnement manquantes | Cron ne charge pas .bashrc ni .profile |
Définir explicitement les variables dans la crontab ou dans le script |
| Mot de passe en clair dans la crontab | Praticité immédiate | Utiliser un fichier EnvironmentFile en chmod 600 avec systemd, ou un fichier .env sourcé par le script |
| Sauvegardes qui saturent le disque | Pas de purge des anciennes archives | Ajouter une commande find ... -mtime +N -delete dans le script |
| Le timer systemd ne se déclenche pas | Oubli de systemctl enable --now ou de daemon-reload après modification |
Toujours faire systemctl daemon-reload après édition d’unit, et enable+now |
| Échec silencieux d’un cron | Sortie redirigée vers /dev/null sans surveillance |
Logger explicitement, ajouter alerte en cas de code de retour non-zéro, monitoring externe |
Adaptation au contexte ouest-africain
Le serveur d’automatisation d’une PME sénégalaise ou ivoirienne devrait toujours tourner dans un datacenter européen (Hetzner Allemagne, OVH France, Scaleway Paris) plutôt que sur un poste local soumis aux coupures Senelec, CIE ou Energie du Mali. Pour les rares jobs qui ne peuvent tourner qu’en local (intégration matérielle, latence critique vers une caisse ou un terminal de paiement), le couple systemd timer + Persistent=true est indispensable : il rattrape l’exécution dès que le serveur redémarre après une coupure, ce que cron ne fait pas par défaut.
Côté budget, ce socle ne coûte rien en logiciels — cron et systemd sont fournis avec toute distribution Linux. La seule dépense est le VPS d’hébergement (à partir de 5,90 EUR/mois sur Hetzner CX22) et éventuellement un Storage Box pour externaliser les sauvegardes (à partir de 3,80 EUR/mois pour 1 To). À comparer avec un service de sauvegarde managé qui facture vite 30-50 USD par mois pour le même volume.
Tutoriels frères du cluster automatisation
- n8n self-hosted 2026 : guide complet (automation alternative à Zapier) — pour orchestrer des workflows visuels au-delà des simples tâches récurrentes.
- Python pour PME : guide pratique data, scripting, automatisation — quand Bash montre ses limites pour les traitements de données.
- Restic 2026 : guide complet (backup chiffré dédupliqué) — outil idéal à coupler avec un timer systemd pour des sauvegardes incrémentales chiffrées.
- VPS mises à jour sécurité automatiques : tutoriel 2026 — autre cas d’usage typique de cron/systemd timer.
FAQ
Faut-il choisir cron ou systemd timer pour une PME ?
Cron pour les tâches simples et isolées (3 lignes de configuration suffisent). systemd timer dès qu’on veut une journalisation centralisée via journalctl, des alertes en cas d’échec via OnFailure, ou le rattrapage automatique d’une exécution manquée (Persistent=true). Sur un nouveau serveur en 2026, par défaut on commence en systemd timers.
Comment savoir si mon job cron a bien tourné cette nuit ?
Trois sources : grep CRON /var/log/syslog sur Ubuntu/Debian (ou journalctl _COMM=cron sur les distributions à systemd), le fichier de log que vous avez configuré dans la redirection >> /var/log/...log, et la présence physique du résultat attendu (le fichier de sauvegarde existe-t-il avec une taille cohérente ?).
Mon timer systemd ne se déclenche pas, pourquoi ?
Trois causes courantes : oubli de sudo systemctl daemon-reload après création/modification du fichier .timer, oubli d’activer le timer avec sudo systemctl enable --now nom.timer, ou faute de syntaxe dans la directive OnCalendar. Diagnostic : systemctl list-timers --all doit afficher votre timer avec une « Next » datée du futur. Si la ligne est absente, le timer n’est pas chargé.
Comment éviter de mettre les mots de passe en clair dans la crontab ?
Pour cron : créer un fichier ~/.env-job en chmod 600 contenant les variables, et le sourcer en début de script avec source ~/.env-job. Pour systemd : utiliser la directive EnvironmentFile=/etc/default/votre-job dans la section [Service], le fichier étant lui aussi en chmod 600 avec propriétaire restreint. Pour des secrets plus sensibles, intégrer un gestionnaire dédié comme HashiCorp Vault.
Cron est-il vraiment fiable en 2026 ?
Oui, cron est rock-solid depuis cinquante ans. Les implémentations modernes (Vixie cron, cronie sur Red Hat, busybox cron sur Alpine) sont matures et stables. Le « problème » de cron n’est pas sa fiabilité mais ses limites fonctionnelles : pas de rattrapage automatique en cas de coupure, logs dispersés, pas de gestion native des dépendances. systemd timers règle ces points sans sacrifier la fiabilité.
Sources et références
- Documentation systemd timers — freedesktop.org : systemd.timer et systemd.time (syntaxe OnCalendar).
- Manuel cron —
man 5 crontabetman 8 cronsur tout système Linux. - Cronie (implémentation cron de Red Hat/Fedora) — github.com/cronie-crond/cronie.
- Healthchecks.io (dead man’s switch self-hostable) — github.com/healthchecks/healthchecks.
- Hetzner Cloud (VPS européen abordable) — hetzner.com/cloud et hetzner.com/storage/storage-box.
- Documentation Ubuntu sur cron — help.ubuntu.com/community/CronHowto.
- Arch Wiki (référence systemd détaillée) — wiki.archlinux.org/title/Systemd/Timers.
Pour aller plus loin
- 🔝 Retour au pilier : Automatisation pour PME ouest-africaines : le guide complet 2026
- Tutoriel suivant recommandé du cluster : Bash scripting pour sysadmin — pour transformer ces simples redirections en scripts robustes avec gestion d’erreurs et notifications.
- Documentation officielle systemd : freedesktop.org/wiki/Software/systemd.
Mots-clés secondaires : cron Linux, systemd timer tutoriel, planification tâches Linux, sauvegarde automatique cron, OnCalendar systemd, journalctl, crontab, automatisation serveur PME.