La planification des tâches sous WordPress utilise un système de cron. Ce système a besoin d’un déclencheur. La configuration des hébergeurs étant très variables, le cron WordPress a besoin d’un mécanisme indépendant. C’est donc l’arrivée de l’internaute qui déclenche le cron.
Si cette astuce a le mérite de s’affranchir du serveur, elle peut toutefois poser des problèmes aux sites très fréquentés comme à ceux qui le sont peu. Dans un cas le cron sera sollicité trop souvent, dans l’autre trop rarement.
Voyons pourquoi et comment corriger ce problème.
Pour qui ? Cet article s’adresse aux personnes qui commencent à maîtriser la partie administration système de WordPress, c’est-à-dire ce qui concerne l’installation, la sauvegarde, le clonage de site, la sécurisation…
Pourquoi ? J’en suis venu à rédiger cet article car, bien qu’ayant trouvé sur internet des didacticiels indiquant comment mettre en place un cron, ils ne m’ont pas permis de comprendre pourquoi cela ne fonctionnait pas chez moi.
Comment ? Il m’a fallu lire des dizaines d’articles pour arriver à trouver ce qui clochait. J’ai donc réuni ici tout ce qu’il me semblait nécessaire de savoir sur ce sujet. J’espère permettre à d’autres de gagner du temps dans la prise en main du cron WordPress.
Pas besoin d’explication, je veux juste voir le mode opératoire.
Au commencement était le cron
Cron est une abréviation de crontab, elle-même une abréviation de chrono table qui signifie table de planification (de Chronos, dieu grec du temps).
Issue du monde Unix, le programme cron, lancé au démarrage d’un système d’exploitation, permet de planifier l’exécution automatique de tâches avec une certaine fréquence ou à un moment donné. Le cron se cale sur l’horloge du serveur, elle-même synchronisée avec une horloge atomique.
En pratique le cron vérifie toutes les minutes sa liste de tâches, la crontab. Celle-ci contient les tâches à exécuter et leur horaire d’exécution avec éventuellement une périodicité.
Le moment est venu, cron lance l’exécution de l’action en attente.
Tous les systèmes d’exploitation (Unix, Linux, Mac, Windows…) utilisent un système de planification de tâches de type cron.
Il faut donner du cron à WordPress
Vérifier les mises à jour du cœur, des extensions et du thème, publier un article… WordPress a besoin de gérer des tâches récurrentes. Par ailleurs, les extensions peuvent elles aussi avoir besoin d’activer leurs fonctionnalités de façon récurrente et automatique : lancer une sauvegarde, envoyer un lot de newsletters.
Cette fonctionnalité est mise en œuvre à travers un cron WordPress qui repose sur deux scripts PHP /wp-cron.php et /wp-includes/cron.php
En tête du fichier /wp-cron.php :
<?php
/**
* Un daemon pseudo-cron pour planifier les tâches de WordPress.
*
* WP-Cron est déclenché lorsque le site reçoit une visite. Dans le scénario
* où un site peut ne pas recevoir assez de visites pour exécuter les tâches
* programmées en temps voulu, ce fichier peut être appelé directement ou
* via un daemon cron depuis un serveur pour un nombre X de fois.
*
* Définir DISABLE_WP_CRON à « true » et appeler ce fichier directement sont
* mutuellement exclusifs et le dernier ne dépend pas du premier pour fonctionner.
*
* La requête HTTP vers ce fichier ne ralentira pas le visiteur présent lorsqu'un
* événement cron planifié s'exécute.
*
* @package WordPress
*/
Cron WordPress : allô Houston…
Ce mécanisme peut poser des problèmes en cas d’affluence (déclenchement trop fréquent du cron WordPress) tout comme si le site connaît une faible fréquentation (les tâches planifiées sont exécutées en retard).
Cela dit, les tâches qui ne sont pas exécutées au moment voulu ne sont pas perdues. Elles sont placées dans liste d’attente. Problème : quand la liste est bien remplie, l’internaute qui déclenche le cron va encaisser un gros ralentissement du site.
Nous allons voir comment régler ce problème en mettant en place un système régulier et qui ne pénalise pas les internautes.
Mise en œuvre de solutions
Note : Inutile de préciser que ce didacticiel s’adresse aux personnes qui utilisent un hébergement mutualisé. Le cron n’a pas de secret pour celles et ceux qui gèrent un serveur dédié.
Cela va consister à désactiver le cron WordPress par défaut puis activer un cron serveur.
Désactiver wp-config.php
Pour cela, ajoutez la ligne suivante dans le fichier /wp-config.php.
...
/** Stop du cron WordPress **/
define('DISABLE_WP_CRON', true);
/* C'est tout, ne touchez pas à ce qui suit ! Bon blogging ! */
...
Cela évite le déclenchement du cron par deux systèmes concurrent (visites et cron serveur).
Cette modification peut perturber certaines extensions. Vous verrez alors un message qui indique que le cron est désactivé.
WP Crontrol
La constante DISABLE_WP_CRON est définie à « true ». Le déclenchement de WP-Cron est désactivé.
ou Updraft+
Attention : Le planificateur de sauvegarde est désactivé dans votre installation WordPress, par le biais du réglage DISABLE_WP_CRON. Aucune sauvegarde ne pourra débuter (même la sauvegarde immédiate) tant que vous n'aurez pas paramétré un moyen de lancer le planificateur manuellement ou tant que vous ne l'aurez pas activé.
02/2019 : L’extension Disable Admin WP Cron Notice For UpdraftPlus a pour vocation de supprimer cette note.
03/2022 : Updraft+ ne semble plus afficher ce message.
Ces message sont perturbants, car ils donnent l’impression que le cron ne va plus fonctionner. En activant correctement un cron externe, ce ne sera pas le cas.
Activer un cron externe à WordPress
Deux cas de figure, selon que votre hébergeur propose ou non un service de planification de tâches.
1 – Hébergeur avec planificateur (tâches cron)
Quel que soit votre hébergeur (OVH, o2switch…), il faudra deux informations : la fréquence et la commande à lancer.
Fréquence
La fréquence devra être ajustée à la tâche qui se produit le plus souvent, sachant que la fréquence ne peut pas être inférieure à la minute.
En général, un déclenchement toutes les 30 minutes devrait suffire. Pour un site WooCommerce on recommande toutes les 5 minutes.
Note : OVH ne permet pas une fréquence inférieure à l’heure, tandis qu’o2switch descend à la minute.
Pour connaître la liste des tâches de votre site et leur fréquence, utilisez l’extension WP Crontrol ou Advanced Cron Manager – debug & control.
Commande
Là aussi, deux possibilités :
a) Lancer le fichier avec PHP
Cette méthode serait la plus efficace en terme de performance. Pour en savoir plus, je vous conseille de lire Running WordPress Cron via PHP-CLI (article en anglais).
Pour lancer le script directement en PHP, il faut que le service de tâches planifiées soit exécuté sur le même serveur que le site.
/usr/bin/php /chemin/dossier_wordpress/wp-cron.php
Chez o2switch, la commande pour le site par défaut est :
cd ~/public_html/; /usr/local/bin/php -q wp-cron.php > ~/logs/wp-cron-www.log 2>&1
Chez o2switch, le dossier « ~/public_html/ » contient les fichiers et dossiers de WordPress. C’est la racine du site. Le dossier ~/logs/ permet de stocker les fichiers de log.
Le signe « ~ » désigne le dossier racine de votre hébergement. Attention la racine de l’hébergement est différente de la racine du/des site(s).
Astuce : en phase de test, réglez la fréquence à 1 minute puis vérifiez dans ~/logs/ si le fichier wp-cron-www.log a été créé ou modifié. Si c’est le cas vous pouvez repasser la fréquence à une valeur supérieure.
Chez OVH faire pointer la tâche sur /répertoire_de_wordpress/wp-cron.php. OVH fourni un didacticiel pour configurer le système de tâches planifiées.
Note : certains disent que les droits du fichier wp-cron.php doivent le rendre exécutable (755), d’autres que ce n’est pas nécessaire (644). Pour ma part, j’ai opté pour 644. Testez.
b) Lancer le script avec une URL
Cela permet de lancer la commande depuis un serveur qui n’est pas obligatoirement celui qui héberge le site. Il arrive aussi que le déclenchement avec PHP pose des problèmes sur certains serveur. L’appel depuis l’URL semble être une solution plus sûre.
Merci à Renaud Pacouil pour son aide dans la résolution du blocage de cron auquel j’étais confronté ainsi que pour l’info sur la liste hackrepair.com qui ne bloque plus wget.
Le programme utilisé peut être wget ou curl selon votre hébergeur ou le service de cron (voir la documentation de votre fournisseur).
wget -q https://www.example.com/wp-cron.php
Le cron du site est lancé en mode silencieux (-q). Il n’affiche pas de message.
wget -q https://www.example.com/wp-cron.php -O ~/logs/wp-cron-www.log
Le cron du site est lancé et les logs sont écrits dans ~/logs/wp-cron-www.log. Avec l’option « -O » les logs sont écrasés à chaque écriture, avec « -a » les logs sont cumulés.
Avec certaines extensions de sécurité ou les pare-feux d’hébergeur, la commande wget est bloquée. Elle peut être remplacée par curl.
curl -s https://www.example.com/wp-cron.php
avec logs
curl -v https://www.example.com/wp-cron.php > ~/logs/wp-cron-www.log 2>&1
Vous pouvez tester l’appel à l’URL avec curl ou wget dans une console.
user@host:~$ wget http://www.example.com/wp-cron.php?doing_wp_cron
--2016-03-08 14:09:16-- http://www.example.com/wp-cron.php?doing_wp_cron
Résolution de www.example.com (www.example.com)… 213.187.33.20
Connexion à www.example.com (www.example.com)|213.187.33.20|:80… connecté.
requête HTTP transmise, en attente de la réponse… 200 OK
Le code 200 indique une connexion réussie.
user@host:~$ wget http://www.example2.com/wp-cron.php?doing_wp_cron
--2016-03-08 14:09:38-- http://www.example2.com/wp-cron.php?doing_wp_cron
Résolution de www.example2.com (www.example2.com)… 104.78.54.15, 104.78.54.15
Connexion à www.example2.com (www.example2.com)|104.78.54.15|:80… connecté.
requête HTTP transmise, en attente de la réponse… 403 Forbidden
2016-03-08 14:09:39 erreur 403 : Forbidden.
Le code 403 indique une erreur.
En l’occurrence, il s’agissait d’un blocage de wget par l’extension iThemes Security.
Attention : si vous utilisez iThemes Security, la liste noire de HackRepair.com bloque wget. Il faut alors utiliser curl ou retirer le blocage de wget dans le fichier .htaccess.
Mise à jour 03/2022 : la liste HackRepair ne bloque plus wget.
2 – Hébergeur sans planificateur
Quelques services spécialisés dans la planification de tâches cron.
easycron.com | Gratuit ou 12$ à 120$/an | |
setcronjob.com | 20$ à 100$ | |
cron-job.org | gratuit | |
webcron.org | 0.001€/lancement | |
cronoo | 1 000 crédits puis 0.0001€/lancement |
Certaines offres gratuites permettent de tester le service.
En ce qui concerne EasyCron (seul fournisseur que j’ai testé), il n’est pas possible d’activer les logs dans l’offre gratuite, ce qui rend difficile l’analyse quand cela ne fonctionne pas. De plus, il semblerait que certains appels au cron retournent une erreur (par exemple si le serveur de votre site a un problème ponctuel ou s’il met du temps à répondre). Dans ce cas, EasyCron désactive la tâche.
Une autre option passe par l’utilisation de IFTT. Voir le mode opératoire.
Si vous utilisez ces services ou d’autres, merci de laisser un commentaire. Je les ajouterai à cet article si besoin.
Alors, ça fonctionne ?
Pour voir si tout va bien, il faut attendre qu’un premier cycle se soit écoulé, vérifier que la prochaine tâche planifiée a bien été exécutée, puis regarder dans les logs de l’hébergeur si la tâche cron a été lancée.
[2016-03-07 00:43:03] ## OVH ## START - 2016-03-07 00:41:03.637658 executing: /usr/local/php5.6/bin/php /homez.xx/moncompte/www/wp-cron.php [2016-03-07 00:43:03] [2016-03-07 00:43:03] ## OVH ## END - 2016-03-07 00:41:05.442767 exitcode: 0 [2016-03-07 01:43:03] ## OVH ## START - 2016-03-07 01:41:03.534382 executing: /usr/local/php5.6/bin/php /homez.xx/moncompte/www/wp-cron.php [2016-03-07 01:43:03] [2016-03-07 01:43:03] ## OVH ## END - 2016-03-07 01:41:05.225793 exitcode: 0 .
La tâche a été lancée à 01h43 et « exitcode: 0 » indique qu’elle s’est bien passée.
Cas particuliers
Certaines extensions comme MailPoet proposent d’activer leur propre cron.
Il semblerait que la mise en maintenance d’un site désactive le cron WordPress.
Pour aller plus loin…
- Codex WordPress : Hooking WP-Cron Into the System Task Scheduler
- Codex WordPress : wp_cron
- Codex WordPress : les fonctions du cron
- Codex WordPress : wp_schedule_single_event
- Explication (en anglais) de Samuel Wood (Otto) sur le fonctionnement du cron WordPress
- Conférence « Prenez le crontrol des tâches planifiées » de Jonathan Buttigieg. Aborde l’aspect programmation du cron
- Ben Lobaugh : Article très complet
- WP Formation : Qu’est-ce que le CRON de WordPress ?
- Automatiser des logiques WordPress en arrière-plan avec un Cron ou Action Scheduler : Pierre Saïkali
et enfin…
- WP Mayor : Best Cron Plugins for WordPress