Tâches cron
Exécutez une commande ou une requête HTTP selon un planning. Lisez « Où la commande s'exécute » avant votre première tâche : une tâche planifiée ne s'exécute pas dans le conteneur en marche de votre application, mais dans un conteneur jetable qui reçoit les mêmes variables.
Création d'une tâche cron
Les tâches planifiées se gèrent depuis la page Tâches cron du tableau de bord, ou avec sh0 cron. Une tâche est en général rattachée à une application.
- Ouvrez Tâches cron dans la barre latérale et cliquez sur Créer une tâche planifiée.
- Nom -- un libellé, par exemple
nightly-report. - Application -- l'application à laquelle la tâche appartient. Sans application, seules les commandes HTTP sont acceptées (voir plus bas).
- Planification -- une expression cron à 5 champs, évaluée en UTC.
- Commande -- une requête HTTP (
curl,wgetou une URL seule), ou un programme à lancer dans un conteneur. - Facultatif : une Image du conteneur (vide = l'image de l'application) et un Délai d'expiration (secondes), 300 par défaut. Créez ensuite la tâche.
La même chose en ligne de commande, sur un serveur où ces commandes ont été exécutées :
$ sh0 cron create --app my-api --name nightly-report \
--schedule "0 3 * * *" \
--command "curl -s -X POST https://api.example.com/internal/report"
Cron job 'nightly-report' created (id: 72173a56-1962-47dc-88e5-2a276ef3bfcc)
$ sh0 cron trigger 72173a56-1962-47dc-88e5-2a276ef3bfcc
Cron job 'nightly-report' triggered.
$ sh0 cron runs 72173a56-1962-47dc-88e5-2a276ef3bfcc
RUN ID STATUS EXIT DURATION STARTED
----------------------------------------------------------------------------------------------------
9e329bc7-01c5-41ec-9eb5-5ab745fde533 success 0 295ms 2026-10-02 02:33:23Où la commande s'exécute
sh0 choisit le mode d'exécution d'après la commande et les réglages de la tâche, dans cet ordre :
- Requête HTTP -- une commande commençant par
curlouwget, ou une URL seule, n'est pas exécutée par un shell : sh0 envoie lui-même la requête, depuis le serveur, avec une limite de 30 secondes.-X,-Het-dsont pris en compte. Un statut de réponse de 400 ou plus marque l'exécution comme échouée. Pour une tâche rattachée à une application, un nom interne de son projet (my-api.internal, oumy-apiseul) est résolu vers ce service. - Image de l'application -- toute autre commande s'exécute dans un nouveau conteneur jetable démarré depuis l'image actuelle de l'application, sous un utilisateur non root, sur le réseau sh0 et sur le réseau de son projet. Ce n'est pas votre conteneur en marche : les fichiers écrits par l'application pendant son exécution n'y sont pas, et le conteneur est supprimé après l'exécution.
- Image explicite -- si Image du conteneur est renseignée, le conteneur jetable part de cette image.
- Ni application ni image -- une commande non HTTP est refusée au moment de l'exécution. sh0 n'exécute jamais une commande planifiée sur l'hôte.
Mesuré sur une application Node.js portant GREETING sur l'application et REGION sur son projet : la tâche env affiche les deux, à côté des variables intégrées à l'image.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=0.0.0.0
REGION=eu431
GREETING=hello431
NODE_VERSION=22.23.3
YARN_VERSION=1.22.22
PORT=3000
HOME=/home/nodeGREETING et REGION sont bien présentes. La ligne HOME=/home/node montre l'utilisateur non root.
Règles de commande
Une commande est un seul programme suivi de ses arguments. sh0 la vérifie à la création de la tâche :
- Pas de shell. Les caractères
;|&><et l'accent grave,$(et les sauts de ligne sont refusés. Pas de tubes, pas d'enchaînements&&, pas d'expansion de variables. - Les guillemets ne comptent que pour les requêtes HTTP. Dans un conteneur, la commande est découpée sur les espaces :
sh -c "echo hi"ne fait pas ce que ferait un shell. Pour les requêtes HTTP, les guillemets sont respectés, donc-H "Authorization: Bearer …"fonctionne. - Les redirections sont retirées plutôt que refusées :
> /dev/null,2>/dev/null,&> /dev/nullet2>&1sont supprimées avant la vérification, si bien qu'une ligne collée depuis une crontab est acceptée. - 4 096 caractères au plus.
$ sh0 cron create --app my-api --name cleanup --schedule "0 3 * * *" --command "env | grep X"
Error: Invalid command: Command contains forbidden character '|'. Use simple commands without shell operators. (VALIDATION_ERROR)Tâches qui ont besoin de la base ou de secrets
Une tâche rattachée à une application voit ses variables et résout les noms internes de son projet : une commande comme python manage.py cleanup lit la même DATABASE_URL et joint le même db.internal. Quand le travail a sa place dans votre application en marche, deux autres voies restent possibles :
- Un point d'accès HTTP. Exposez la tâche comme une route de votre application, protégée par un jeton, et laissez la tâche planifiée l'appeler par son nom interne. Le travail s'exécute dans votre application en marche, avec sa connexion à la base et ses secrets.
- Ou planifiez dans l'application, avec l'ordonnanceur de votre framework (par exemple Celery beat, node-cron ou le planificateur de Laravel), quand la tâche ne doit pas du tout être joignable en HTTP.
curl -s -X POST -H "Authorization: Bearer <token>" http://my-api.internal:3000/internal/cleanupmy-api.internal (ou my-api) parmi les services en marche du seul projet de la tâche. Un nom qui ne désigne aucun service en marche échoue avec un message explicite ; une application hors projet, ou qui tourne sur un nœud distant, doit être appelée par son URL publique. Le jeton figure en clair dans la commande de la tâche, visible par quiconque peut lire la tâche : ne lui donnez aucun autre usage.Syntaxe des expressions cron
sh0 utilise des expressions cron standard à 5 champs. Chaque champ représente une unité de temps :
┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday = 0)
│ │ │ │ │
* * * * *| Symbole | Signification | Exemple |
|---|---|---|
| * | Toutes les valeurs | * * * * * = chaque minute |
| , | Liste de valeurs | 0 8,12,18 * * * = 8h, midi, 18h |
| - | Plage | 0 9-17 * * * = toutes les heures de 9h à 17h |
| / | Pas | */15 * * * * = toutes les 15 minutes |
Schémas courants
# Every minute
* * * * *
# Every 5 minutes
*/5 * * * *
# Every hour at minute 0
0 * * * *
# Every day at midnight
0 0 * * *
# Every day at 3:30 AM
30 3 * * *
# Every Monday at 9:00 AM
0 9 * * 1
# First day of every month at midnight
0 0 1 * *
# Every weekday (Mon-Fri) at 6:00 AM
0 6 * * 1-50 3 * * * s'exécute à 03:00 UTC. L'ordonnanceur cherche les tâches dues toutes les 60 secondes : une exécution peut donc démarrer jusqu'à une minute après son heure.Historique d'exécution et logs
Chaque exécution est enregistrée avec son statut (success, failed ou timeout), son code de sortie, sa durée, ses heures de début et de fin, et sa sortie. Dans le tableau de bord, ouvrez Historique d'exécution sur une tâche, puis affichez la sortie d'une exécution. En ligne de commande : sh0 cron runs <id>.
Activation et désactivation des tâches
- Désactiver arrête les exécutions planifiées sans supprimer la tâche ni son historique ; Activer les reprend.
- Déclencher maintenant (ou
sh0 cron trigger <id>) lance une exécution immédiatement, quel que soit le calendrier. - Supprimer une tâche (
sh0 cron delete <id>) supprime aussi son historique.
Délais, chevauchement et limites
- Délai d'expiration -- 300 secondes par défaut (
--timeouten ligne de commande). Une exécution qui le dépasse est enregistrée avec le statuttimeoutet le message « Job timed out after Ns ». - Chevauchement -- tant qu'une exécution d'une tâche est en cours, l'ordonnanceur n'en lance pas d'autre. L'occurrence sautée n'apparaît pas dans l'historique.
- 50 tâches par application.
- Ni nouvelle tentative ni notification d'échec. Une exécution en échec n'est pas relancée et ne déclenche aucune alerte : consultez l'historique, ou faites signaler ses propres échecs par le point d'entrée qu'appelle la tâche.