Systemd

systemd timers : remplacer cron proprement en 2026

Découvrez les timers systemd pour planifier des tâches Linux avec logs, reprise après arrêt et contrôle fiable des services.

Par Julien Martel 9 min de lecture
systemd timers : remplacer cron proprement en 2026

Pourquoi cron montre ses limites sur les serveurs Linux modernes

Cron reste un outil simple, disponible sur la plupart des distributions Linux et parfaitement adapté à de nombreuses tâches courtes : vider un répertoire temporaire, lancer un rapport quotidien ou exécuter un script local. Il n’est donc pas question de le considérer comme obsolète par principe.

En revanche, pour les tâches importantes d’un serveur, cron sépare souvent trop d’éléments : le calendrier est dans une crontab, la commande dans un script, les sorties dans un fichier de redirection ou un courriel local, et l’état réel de l’exécution doit être reconstitué après coup. Sur une machine administrée avec systemd, les timers systemd rapprochent la planification, l’exécution et les journaux du même cadre d’exploitation.

Le problème le plus classique concerne les heures de maintenance, les redémarrages ou les périodes d’arrêt. Une entrée cron prévue à 02:30 ne s’exécute généralement pas si la machine est arrêtée à ce moment-là. Selon le besoin métier, cette absence peut être acceptable, ou au contraire laisser une sauvegarde, une synchronisation ou une rotation sans exécution pendant plusieurs jours.

Un timer fondé sur un calendrier peut utiliser l’option Persistent=true. systemd mémorise alors la dernière occurrence et déclenche le service après le prochain démarrage ou la prochaine activation du timer si une exécution a été manquée. Il ne s’agit pas de « rejouer » toutes les occurrences ratées : systemd lance le service une fois pour rattraper le retard constaté.

Les timers apportent aussi des bénéfices opérationnels concrets :

  • le processus peut être supervisé comme n’importe quel service systemd ;
  • les sorties standard et d’erreur sont consultables dans le journal avec journalctl ;
  • l’état, la prochaine échéance et la dernière exécution sont visibles avec systemctl ;
  • les dépendances, conditions d’exécution et limites de ressources peuvent être définies dans des unités déclaratives ;
  • la configuration peut être versionnée dans des fichiers distincts, plutôt que mélangée à une crontab utilisateur.

Ce modèle est particulièrement cohérent lorsque la tâche appelle déjà un service, dépend du réseau, nécessite des droits spécifiques ou doit laisser une trace exploitable lors d’un incident. Il complète utilement les pratiques décrites dans notre guide sur la planification fiable avec crontab, sans imposer une migration totale et immédiate.

Comprendre le duo fichiers .service et .timer

Un timer systemd ne contient pas la commande métier. Il sert à déterminer quand une unité doit être activée. Dans le cas courant, cette unité est un service qui détermine quoi exécuter. On utilise donc au minimum deux fichiers portant le même préfixe :

  • nom-de-tache.service pour définir la commande, son utilisateur éventuel, son répertoire de travail et ses règles d’exécution ;
  • nom-de-tache.timer pour définir le calendrier ou le délai.

Par convention, un fichier sauvegarde.service est associé à sauvegarde.timer. Lorsqu’aucune directive Unit= n’est présente dans la section [Timer], systemd active automatiquement le service du même nom. Cette convention rend les unités faciles à relire.

Les unités système personnalisées sont habituellement placées dans /etc/systemd/system/. Elles concernent la machine entière et sont en général administrées avec les privilèges root. Les unités fournies par les paquets sont souvent installées dans un autre répertoire géré par la distribution ; il est préférable de ne pas les modifier directement.

Il existe aussi des timers utilisateur, utiles pour automatiser une tâche sans privilèges administrateur. Ils sont alors chargés dans l’instance systemd de l’utilisateur avec systemctl --user. Pour une sauvegarde de données système, une maintenance de serveur ou une tâche devant fonctionner indépendamment de la session SSH d’un utilisateur, les unités système sont généralement plus adaptées.

Les principaux modes de planification

La directive OnCalendar= planifie une tâche selon une date et une heure. Elle est l’équivalent le plus proche d’une expression cron. Par exemple, OnCalendar=*-*-* 02:30:00 signifie tous les jours à 02:30.

systemd accepte aussi des déclencheurs relatifs, notamment :

  • OnBootSec=, pour lancer une tâche après le démarrage de la machine ;
  • OnUnitActiveSec=, pour la relancer après l’activation précédente de l’unité ;
  • OnUnitInactiveSec=, pour compter à partir de la fin de l’exécution précédente.

Une tâche de synchronisation exécutée toutes les six heures après sa dernière réussite peut ainsi être modélisée différemment d’une tâche impérativement attendue chaque jour à une heure donnée. Ce choix doit refléter le besoin : calendrier fixe ou intervalle entre deux exécutions.

La documentation officielle de systemd.timer décrit l’ensemble des directives disponibles. Pour vérifier une expression de calendrier avant de la déployer, la commande systemd-analyze calendar est particulièrement utile.

Créer un timer systemd : exemple concret de sauvegarde

Voici un exemple volontairement simple : synchroniser chaque nuit le contenu de /srv/data/ vers /var/backups/srv-data/ avec rsync. Avant toute automatisation, il faut exécuter la commande manuellement, vérifier les droits, l’espace disponible et le contenu de la destination.

L’option --delete utilisée ci-dessous supprime dans la destination les fichiers qui n’existent plus dans la source. Elle est souvent pertinente pour un miroir, mais elle mérite une validation rigoureuse : une erreur de chemin peut avoir des conséquences importantes. Un premier essai avec --dry-run est recommandé.

Créez le fichier /etc/systemd/system/sauvegarde-srv-data.service :

[Unit]
Description=Sauvegarde rsync de /srv/data
ConditionPathIsDirectory=/srv/data
ConditionPathIsDirectory=/var/backups/srv-data

[Service]
Type=oneshot
ExecStart=/usr/bin/rsync --archive --delete /srv/data/ /var/backups/srv-data/

Adaptez le chemin de rsync à votre système si nécessaire ; la commande command -v rsync permet de le contrôler. Les deux barres obliques finales dans cet exemple sont importantes : /srv/data/ désigne le contenu du répertoire source, alors que l’absence de barre finale modifierait la structure créée dans la destination.

Type=oneshot convient à une commande qui s’exécute puis se termine. systemd considérera le service comme réussi si rsync retourne un code de sortie de succès. Les directives ConditionPathIsDirectory= évitent un lancement si l’un des répertoires attendus n’existe pas. Une condition non satisfaite ne transforme pas nécessairement l’événement en échec : vérifiez donc aussi que les chemins de sauvegarde sont surveillés et montés comme prévu.

Créez ensuite le fichier /etc/systemd/system/sauvegarde-srv-data.timer :

[Unit]
Description=Planification quotidienne de la sauvegarde /srv/data

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
Unit=sauvegarde-srv-data.service

[Install]
WantedBy=timers.target

La ligne Unit= est explicite ici. Elle n’est pas indispensable puisque les deux fichiers partagent le même nom de base, mais elle facilite la lecture lorsque l’unité est revue plusieurs mois plus tard.

Avec Persistent=true, si la machine était arrêtée lors de l’heure prévue, systemd peut lancer la sauvegarde au retour du système. Cette option s’applique aux timers calendaires tels que OnCalendar=. Elle ne remplace pas une stratégie de sauvegarde complète : il faut toujours contrôler la destination, les restaurations possibles, la rétention et, le cas échéant, la copie hors de la machine source.

Valider les unités avant de les activer

Une unité systemd est une configuration de production. Une erreur de syntaxe, un chemin inexistant ou une commande mal testée doit être détectée avant la première nuit. Commencez par demander à systemd de recharger ses définitions :

sudo systemctl daemon-reload

Vous pouvez ensuite vérifier les fichiers avec :

sudo systemd-analyze verify /etc/systemd/system/sauvegarde-srv-data.service /etc/systemd/system/sauvegarde-srv-data.timer

Cette vérification ne remplace pas un essai réel de la commande, mais elle aide à repérer des problèmes de structure ou des directives invalides. Validez également le calendrier :

systemd-analyze calendar '*-*-* 02:30:00'

La sortie indique les prochaines occurrences calculées. C’est une étape précieuse lorsque le calendrier est plus complexe, par exemple pour exécuter une tâche seulement certains jours ouvrés ou à plusieurs heures dans la journée.

Enfin, testez le service sans attendre le timer :

sudo systemctl start sauvegarde-srv-data.service
sudo systemctl status sauvegarde-srv-data.service

Contrôlez le résultat de rsync sur le disque cible. Pour une procédure de sauvegarde plus globale, notamment avec des exclusions et une reprise de transfert, consultez aussi notre article sur les sauvegardes serveur Linux avec rsync. Le timer ne rend pas une commande rsync sûre par lui-même : il rend son exécution planifiée plus observable.

Activer le timer et vérifier sa prochaine exécution

Une fois l’exécution manuelle validée, activez le timer au démarrage et lancez-le immédiatement :

sudo systemctl enable --now sauvegarde-srv-data.timer

Cette commande ne lance pas nécessairement la sauvegarde à cet instant. Elle démarre le mécanisme de planification et crée l’activation nécessaire pour les prochains démarrages. Le service sera lancé à l’heure prévue, ou lors d’un rattrapage éventuel lié à Persistent=true.

Pour afficher l’état détaillé d’un timer précis :

systemctl status sauvegarde-srv-data.timer

Pour visualiser les timers connus, y compris ceux qui ne sont plus actifs :

systemctl list-timers --all

La liste affiche notamment la prochaine échéance, la dernière activation et l’unité que chaque timer déclenchera. C’est l’une des différences pratiques les plus appréciables avec une crontab : l’opérateur n’a pas besoin de recalculer mentalement une expression ni de chercher quel script est censé démarrer.

Pour désactiver temporairement la planification sans supprimer les fichiers :

sudo systemctl disable --now sauvegarde-srv-data.timer

Le service reste lançable manuellement. Cette séparation est utile durant une opération de maintenance : on peut suspendre le calendrier tout en conservant une commande de sauvegarde testable.

Lire les journaux et diagnostiquer une exécution en échec

Par défaut, systemd collecte les sorties des services dans le journal. Après une sauvegarde, consultez les messages associés à l’unité de service :

sudo journalctl -u sauvegarde-srv-data.service

Pour suivre les messages pendant un test :

sudo journalctl -fu sauvegarde-srv-data.service

L’option -f suit les nouveaux événements, tandis que -u limite l’affichage à l’unité concernée. Il est également possible de cibler le démarrage en cours avec -b :

sudo journalctl -b -u sauvegarde-srv-data.service

Pour inspecter la définition effectivement chargée, plutôt que le fichier que vous pensez avoir modifié, utilisez :

systemctl cat sauvegarde-srv-data.service
systemctl cat sauvegarde-srv-data.timer

Cette commande est très utile lorsqu’un fichier de surcharge ou une unité fournie par un paquet intervient dans le comportement observé. En cas de doute après une modification, relancez toujours sudo systemctl daemon-reload avant de tester.

Les causes fréquentes d’échec sont rarement propres au timer : chemin erroné vers l’exécutable, droits insuffisants, point de montage absent, espace disque saturé, variable d’environnement attendue par un script ou accès réseau indisponible. Le service systemd rend ces problèmes plus faciles à circonscrire, car le code de sortie et les erreurs sont centralisés. Notre guide consacré à journalctl et la lecture rapide des logs Linux détaille les filtres les plus utiles au quotidien.

Éviter les collisions et gérer les contraintes réelles

Une planification fiable ne consiste pas uniquement à choisir une heure. Il faut anticiper la durée de la tâche et les interactions avec le reste du système. Si une sauvegarde est encore en cours à l’échéance suivante, ne supposez pas que tous les scénarios sont sans risque : testez le comportement de votre service et adaptez sa conception.

Pour répartir les charges sur plusieurs machines, systemd propose notamment RandomizedDelaySec= dans la section [Timer]. Cette directive ajoute un délai aléatoire avant l’activation. Elle est pertinente lorsqu’un parc important contacte simultanément un dépôt, un serveur de mises à jour ou une API interne. Elle implique naturellement que l’exécution ne démarrera plus à une seconde fixe.

Les timers calendaires peuvent aussi être regroupés par systemd dans une fenêtre de précision afin de limiter les réveils inutiles. Si une heure extrêmement précise est indispensable, étudiez soigneusement les directives de précision et mesurez l’effet réel sur votre environnement. Dans la majorité des tâches d’administration, quelques instants de décalage sont préférables à une exigence de précision qui n’apporte pas de valeur opérationnelle.

Une tâche dépendante d’un montage réseau ou d’une connectivité doit déclarer ses besoins au lieu de simplement espérer que tout est prêt. Selon le contexte, cela peut passer par des dépendances systemd adaptées, par une vérification explicite dans le script, ou par un mécanisme de reprise contrôlé. Évitez toutefois de transformer chaque unité en fichier complexe : une commande claire, testée et accompagnée de journaux reste plus maintenable.

Migrer progressivement les tâches cron importantes

La migration la plus sûre consiste à partir des tâches qui justifient réellement un meilleur suivi : sauvegardes, synchronisations de données, vérifications d’intégrité, maintenance applicative ou traitements dont l’absence doit être détectée. Conservez cron pour les automatisations simples qui fonctionnent déjà correctement et dont les contraintes ne nécessitent pas une unité systemd.

Pour chaque tâche retenue, procédez dans cet ordre :

  • identifiez la commande réelle, son utilisateur, ses répertoires de travail et ses variables nécessaires ;
  • exécutez-la manuellement et validez son code de retour ;
  • créez d’abord le fichier .service ;
  • testez-le avec systemctl start et lisez ses journaux ;
  • ajoutez le fichier .timer et vérifiez son calendrier ;
  • activez le timer ;
  • désactivez l’entrée cron correspondante uniquement après validation.

Ne laissez pas cron et le timer exécuter simultanément la même opération de sauvegarde ou de nettoyage, sauf si ce doublon est volontaire et maîtrisé. Documentez aussi l’emplacement des unités, la commande de contrôle et le comportement attendu après une indisponibilité. Cette documentation sera utile au prochain administrateur, mais aussi à vous-même lors d’une intervention urgente.

Conclusion : faire de la planification un élément observable

Les timers systemd ne sont pas une obligation universelle, mais ils constituent un choix solide pour les tâches serveur qui méritent une exécution visible, journalisée et intégrée au cycle de vie de la machine. Le duo .service et .timer sépare clairement l’action de son calendrier, tandis que Persistent=true répond au cas fréquent des exécutions manquées pendant un arrêt.

Commencez par une seule tâche critique, testez-la manuellement, surveillez-la avec systemctl et journalctl, puis étendez progressivement la méthode. Vous obtiendrez une automatisation plus simple à diagnostiquer, sans remplacer inutilement ce qui fonctionne déjà.

Commentaires· Aucun commentaire pour l'instant

Soyez le premier à réagir.

Laisser un commentaire