Aller au contenu

Hébergement WordPress d'entreprise : les exigences, et comment vérifier chacune

Les propriétés de plateforme qui comptent vraiment pour un hébergement WordPress d'entreprise - processus PHP, cache d'objets persistant, cache de page, préproduction, sauvegardes, isolation, déploiements et journaux - avec la commande qui prouve chacune sur un compte d'essai.

Toutes les pages d’hébergement WordPress d’entreprise annoncent les mêmes neuf ou dix fonctions, dans les mêmes mots, que la plateforme en dessous soit bâtie pour l’échelle ou qu’il s’agisse d’un compte de revendeur avec un plus beau tableau de bord. La seule façon de les distinguer : ouvrir un essai, obtenir un accès shell ou une session WP-CLI via SSH, et vérifier chaque propriété soi-même. Cette page est cette liste de vérification, avec la commande qui confirme ou démolit chaque affirmation en moins d’une minute. En bref, une plateforme sérieuse offre un pool de processus PHP dimensionné et connu, un cache d’objets persistant réellement connecté, un cache de page qui sert le trafic déconnecté et s’efface correctement devant les paniers et les sessions, une préproduction qui emporte la base de données, une restauration en libre-service avec un délai chiffré, de vraies frontières de locataire, un chemin de déploiement git ou CI, et des journaux lisibles sans ouvrir de billet. Ce qu’un fournisseur ne peut pas démontrer sur un compte d’essai est une affirmation, pas une propriété.

Ce que vous allez accomplir

  • Transformer une liste de fonctions en neuf vérifications exécutables sur un compte d’essai en une heure environ.
  • Prouver que le cache d’objets et le cache de page sont connectés et servent, pas seulement installés.
  • Mesurer où le pool de processus PHP se met à faire la file, et lire honnêtement la falaise de latence.
  • Établir la vraie fenêtre de sauvegarde et le délai de restauration en restaurant quelque chose.
  • Repartir avec une courte liste de propriétés que le fournisseur devra confirmer par écrit.

Prérequis

  • Un compte d’essai ou bac à sable avec une véritable installation WordPress dessus. Un compte vide n’apprend à peu près rien.
  • SSH, ou un shell avec WP-CLI. Beaucoup de plateformes infogérées offrent WP-CLI sans shell général ; la plupart des vérifications ci-dessous fonctionnent quand même. Si ni l’un ni l’autre n’existe, cette absence est déjà un constat.
  • WP-CLI 2.x et WordPress 6.x. Toutes les commandes wp ci-dessous sont fournies par WP-CLI de base, sauf wp redis status, qui vient de l’extension Redis Object Cache et n’existe que si celle-ci est active.
  • curl 7.66 ou plus récent pour tester HTTP/3 ; --http3 est marqué expérimental dans plusieurs versions de distribution, et une version sans cette option le dira.
  • Optionnel : hey ou ApacheBench (ab) pour une sonde de charge. Lisez d’abord la mise en garde de l’étape 5.
  • Les chemins, l’emplacement des journaux et le nom des en-têtes de cache varient d’une plateforme à l’autre. La documentation du fournisseur fait autorité pour son propre produit.

Comment ça fonctionne

Une requête WordPress traverse un ensemble fixe de couches, et chaque exigence appartient à exactement l’une d’elles. Savoir quelle couche possède une propriété évite de tester la mauvaise chose : une page lente avec x-cache: HIT n’est pas un problème de PHP, et une page rapide sans charge n’apprend rien sur le dimensionnement des processus.

Le chemin d'une requête dans une plateforme WordPress, du visiteur à la base de données, avec l'exigence appliquée à chaque couche et la commande qui la vérifie

Deux points méritent une note avant de commencer.

Les processus PHP sont le plafond dur. PHP-FPM fait tourner un pool fixe de processus enfants, chacun traitant une requête du début à la fin. Si pm.max_children vaut 20 et que 20 requêtes sont en vol, la 21e attend dans la file d’écoute aussi longtemps que la plus lente de ces 20. C’est pourquoi un site à l’aise à 40 requêtes par seconde tombe d’une falaise à 45 au lieu de se dégrader doucement : il ne manque pas de processeur, il manque de processus. L’arithmétique du dimensionnement est dans le calcul de pm.max_children ; ce qui compte ici, c’est de savoir si la plateforme accepte de vous donner le chiffre.

Cache d’objets et cache de page sont deux couches distinctes. Le cache de page conserve le HTML rendu et répond sans invoquer PHP. Le cache d’objets se situe sous PHP et absorbe les requêtes répétées à la base quand le cache de page rate, c’est-à-dire à chaque requête authentifiée, chaque panier, chaque écran d’administration. Une plateforme qui n’a qu’un cache de page paraît excellente dans un banc d’essai synthétique de la page d’accueil et s’effondre sur un passage à la caisse WooCommerce chargé. La distinction est détaillée dans cache d’objets contre cache de page.

Étape par étape

Descendez l’arbre. Chaque nœud a une commande, une sortie attendue et un mode de défaillance sur lequel agir.

Un arbre de vérification à quatre nœuds couvrant le cache d'objets, le cache de page, la base de données de préproduction et la restauration en libre-service, avec la commande et les signaux de réussite et d'échec à chaque nœud

  1. Confirmez que vous avez un vrai WP-CLI, et voyez sur quel PHP vous êtes.

    wp --info
    OS:      Linux 6.8.0 x86_64
    PHP binary:     /usr/bin/php8.3
    PHP version:    8.3.14
    WP-CLI version: 2.11.0

    Une version de PHP sous 8.1 sur une plateforme vendue pour du WordPress d’entreprise est déjà un constat en soi. Si wp est carrément absent, demandez pourquoi avant d’aller plus loin.

  2. Testez si le cache d’objets est persistant, pas seulement présent.

    wp cache type rapporte ce que WordPress croit utiliser, mais un fichier de raccordement mal configuré annonce un moteur qu’il n’atteint jamais. Le vrai test consiste à écrire dans un processus et à lire dans un autre :

    wp cache type
    wp cache set probe 1 chk 300
    wp cache get probe chk
    Redis
    Success: Set object 'probe' in group 'chk'.
    1

    Chaque appel à wp est un processus PHP distinct : une valeur qui survit du set au get ne peut venir que d’un moteur partagé. Si wp cache type répond Default, WordPress utilise le cache mémoire non persistant et chaque requête refait les mêmes requêtes d’options et de métadonnées. S’il nomme Redis mais que le get ne retourne rien, le raccordement est installé et la connexion échoue en silence, ce qui est la défaillance la plus fréquente et la plus trompeuse.

    Là où l’extension Redis Object Cache est active :

    wp redis status
    Status: Connected
    Client: PhpRedis (v6.0.2)
    Drop-in: Valid
    Disabled: No

    Ce sont ces quatre lignes qui comptent ; la commande enchaîne ensuite avec un long bloc de diagnostics : versions du client, délais d’attente et chaque constante WP_REDIS_* définie.

    Et depuis un shell capable de joindre le cache directement :

    redis-cli ping
    PONG
  3. Vérifiez la charge de travail qu’on demande au cache d’objets.

    wp db size --human-readable
    wp db query "SELECT ROUND(SUM(LENGTH(option_value))/1024) AS autoload_kb FROM wp_options WHERE autoload IN ('yes','on','auto-on','auto');"
    +---------+--------+
    | Name    | Size   |
    +---------+--------+
    | wp_prod | 4.2 GB |
    +---------+--------+
    autoload_kb
    1840

    Les options en chargement automatique sont lues à chaque requête. Au-delà d’environ 800 Ko, un cache d’objets persistant cesse d’être optionnel, et le chiffre devient quelque chose de concret à présenter au fournisseur quand vous demandez pour quelle taille son cache est prévu.

  4. Prouvez que le cache de page sert le trafic déconnecté, et s’efface quand il le doit.

    Demandez une page publique deux fois, à quelques secondes d’intervalle :

    curl -sI https://site.example/ | grep -Ei 'x-cache|cf-cache-status|age|cache-control|server|x-powered-by'
    server: cloudflare
    cache-control: max-age=0, s-maxage=300
    cf-cache-status: HIT
    age: 47

    Un age qui monte entre deux requêtes est le signal honnête : la réponse vient d’un entrepôt et non d’un rendu neuf. x-cache: HIT, cf-cache-status: HIT et x-litespeed-cache: hit sont tous valables selon la pile. Un age absent avec MISS à chaque fois signifie que le cache de page ne fonctionne pas pour le trafic anonyme, soit le cas le plus facile qui existe.

    Vérifiez maintenant qu’il refuse de mettre une session en cache. Envoyez un témoin que WordPress traite comme une marque d’authentification :

    curl -sI -H 'Cookie: wordpress_logged_in_probe=1' https://site.example/ | grep -Ei 'cf-cache-status|x-cache|^age:'
    cf-cache-status: BYPASS

    BYPASS ou MISS est la bonne réponse. Un HIT ici veut dire qu’on sert du HTML mis en cache à des sessions, et sur un site WooCommerce c’est ainsi qu’un client voit le panier d’un autre. Refaites l’essai sur une URL avec chaîne de requête (https://site.example/?utm_source=probe) et demandez quels paramètres entrent dans la clé de cache ; une pile qui indexe sur tous les paramètres a un cache que les étiquettes de campagne vont déchiqueter.

  5. Trouvez la falaise des processus, prudemment.

    Une petite sonde de charge indique où la file commence. Elle ne donne pas la capacité du site, et lancée d’un portable elle mesure surtout votre propre lien montant. Visez la préproduction, jamais la production, et seulement avec l’accord du fournisseur :

    hey -n 200 -c 10 https://staging.site.example/?nocache=1
    Summary:
      Total:  9.1 sec
      Requests/sec: 21.9
    
    Latency distribution:
      50% in 0.41 secs
      95% in 1.87 secs
      99% in 4.02 secs

    Le ?nocache=1 sert à contourner le cache de page pour mesurer PHP ; confirmez-le d’abord avec curl -sI. Lisez la forme, pas le chiffre : si le p50 reste plat pendant que le p95 et le p99 grimpent en flèche quand vous montez -c, vous avez trouvé le nombre de processus. Demandez ensuite quel mode pm et quel pm.max_children le forfait applique, et si ce nombre est par site ou partagé sur le compte. Un fournisseur qui refuse de le dire vous dit quelque chose.

  6. Traitez la préproduction comme un vrai environnement, pas une copie des fichiers.

    Depuis le shell de préproduction :

    wp option get siteurl
    wp db size --human-readable
    wp post list --post_type=post --format=count
    https://staging.site.example
    +------------+--------+
    | Name       | Size   |
    +------------+--------+
    | wp_staging | 4.1 GB |
    +------------+--------+
    18422

    Une préproduction dont le siteurl pointe encore sur la production est un chercher-remplacer qui n’a pas eu lieu, et elle enverra de vrais courriels et de vrais webhooks. Une base quasi vide veut dire que la préproduction ne contient que les fichiers, donc inutile pour tester une migration ou une mise à jour d’extension sur du vrai contenu. Posez ensuite la question que le tableau de bord n’aborde pas : lors d’une poussée vers la production, qu’arrive-t-il à la base de données ? Les trois vraies réponses sont : fichiers seulement, fichiers plus base écrasant la production, et fichiers plus une sélection de tables. Seule la première est sûre sur un site qui prend des commandes, et seulement si vous le savez.

  7. Établissez le RPO et le RTO en restaurant quelque chose.

    Restaurez la sauvegarde d’hier vers la préproduction et chronométrez. Notez trois chiffres : jusqu’où remonte le plus ancien point restaurable, combien de temps la restauration a pris de bout en bout, et si vous l’avez lancée vous-même ou ouvert un billet. Prenez une empreinte avant et après :

    wp db size --human-readable && wp post list --post_type=post --format=count
    +------------+--------+
    | Name       | Size   |
    +------------+--------+
    | wp_staging | 4.1 GB |
    +------------+--------+
    18422

    Si la restauration est en libre-service et s’est terminée pendant que vous regardiez, vous tenez un délai de reprise sur lequel planifier. S’il a fallu un billet, le délai de reprise est celui de la file d’attente, et cela doit entrer dans l’évaluation.

  8. Vérifiez la frontière de locataire.

    wp config get DB_HOST
    wp db query "SHOW GLOBAL VARIABLES LIKE 'max_connections';"
    nproc
    cat /sys/fs/cgroup/memory.max
    db-cluster-7.internal:3306
    Variable_name	Value
    max_connections	500
    8
    4294967296

    Un DB_HOST à localhost signifie que MySQL partage le conteneur web avec PHP et que les deux se disputent la même mémoire. Un hôte distant ne dit rien sur son caractère dédié : demandez. Le fichier cgroup est le signal le plus utile : une vraie limite en octets veut dire un conteneur avec un plafond mémoire. nproc peut rapporter le nombre de processeurs de l’hôte plutôt que votre part, traitez-le comme un indice. Sur cgroup v1 le chemin est /sys/fs/cgroup/memory/memory.limit_in_bytes, et une valeur près de 2^63 signifie qu’aucune limite n’est posée.

  9. Établissez comment le code est déployé, et quels journaux vous pouvez lire.

    ls -a /path/to/site/ | grep -E '^\.git$|^\.gitignore$'
    ls -la ~/logs/ 2>/dev/null || ls -la /var/log/php-fpm/ 2>/dev/null
    wp config get WP_DEBUG_LOG
    .git
    .gitignore
    -rw-r--r-- 1 site site  8.4M Sep  9 03:12 access.log
    -rw-r--r-- 1 site site  212K Sep  9 03:10 error.log
    /home/site/logs/wp-debug.log

    Un répertoire .git dans la racine web indique que la plateforme accepte un déploiement par git ; son absence signifie en général SFTP ou un téléverseur maison, praticable mais hostile à l’intégration continue. Pour les journaux, trois choses comptent et aucune ne figure sur une page de fonctions : si le journal d’accès brut vous est lisible, combien de jours sont conservés, et si le journal des requêtes lentes de MySQL est actif et joignable. Vérifiez le dernier depuis WP-CLI :

    wp db query "SHOW VARIABLES LIKE 'slow_query_log'; SHOW VARIABLES LIKE 'long_query_time';"
    Variable_name	Value
    slow_query_log	ON
    Variable_name	Value
    long_query_time	1.000000

    Un slow_query_log à OFF, ou actif sans moyen de lire le fichier, signifie que toute enquête future sur la base commencera par une demande au bureau de support.

Valider que ça fonctionne

Passez la série de bout en bout et notez neuf réponses. Une plateforme digne d’une courte liste produit à peu près ceci :

wp --info | grep 'PHP version'
wp cache type
curl -sI https://site.example/ | grep -Ei '^age:|cache-status'
curl -s -o /dev/null -w '%{http_version}\n' https://site.example/
wp option get siteurl
wp config get DB_HOST
PHP version:    8.3.14
Redis
cf-cache-status: HIT
age: 112
2
https://site.example
db-cluster-7.internal:3306

La sortie de %{http_version} vaut 2 pour HTTP/2 et 3 pour HTTP/3 ; ajoutez --http3 pour tester si la périphérie le négocie. Un curl compilé sans le support HTTP/3 le dit plutôt que de mentir sur le résultat.

Tout ce que vous n’avez pas pu établir depuis un shell devient une question écrite au fournisseur, avec un chiffre attaché : pas « offrez-vous un cache d’objets » mais « le cache d’objets est-il persistant entre les processus, et quel est son plafond mémoire sur ce forfait ».

Lire les réponses ensemble

Aucune plateforme ne réussit tout, et une vérification ratée est une question de cadrage plutôt qu’un rejet. Ce qui compte, c’est de savoir si les manques concordent avec votre charge de travail. Un site de contenu à fort trafic anonyme peut vivre avec un pool de processus modeste si le taux de succès du cache de page est élevé ; cette forme de trafic fait l’objet de la pile d’un éditeur d’entreprise. Un site transactionnel, non : paniers et passages à la caisse contournent le cache de page par conception et retombent sur PHP et la base à chaque fois.

Dépannage

wp cache type annonce Redis mais rien ne persiste. Le fichier de raccordement object-cache.php est en place et la connexion échoue : mauvais hôte, port ou mot de passe, ou un pare-feu entre la couche web et le cache. Confirmez avec wp redis status si l’extension est présente ; une ligne Status: Not connected rend la chose explicite. L’échec silencieux est le comportement par défaut, et c’est pourquoi le test set-puis-get vaut mieux que le rapport de type.

Chaque page affiche cf-cache-status: DYNAMIC. Cloudflare relaie mais aucune règle de cache ne vise le HTML, donc le CDN ne fait que le TLS et le WAF. C’est un manque de configuration plutôt qu’une limite de plateforme, mais sur un forfait infogéré ce devrait déjà être fait. Demandez à qui appartient ce jeu de règles avant de signer.

La sonde de charge donne de mauvais chiffres partout. Cherchez d’abord une limitation de débit. Beaucoup de WAF freinent ou défient une rafale de requêtes identiques venant d’une seule adresse IP, et vous finissez par mesurer le WAF au lieu de l’origine. Un mur de réponses 429 ou 403 dans la répartition des statuts de hey est l’indice. Coordonnez le test avec le fournisseur, sinon le résultat ne veut rien dire.

nproc et free -m rapportent l’hôte, pas votre conteneur. Les deux lisent des interfaces de niveau hôte sur beaucoup d’environnements d’exécution de conteneurs. Fiez-vous au fichier cgroup pour la mémoire, et considérez le processeur comme inconnu tant que le fournisseur n’a pas énoncé la part.

Une poussée depuis la préproduction annule discrètement un réglage d’extension. Presque toujours, la poussée a emporté la base et écrasé le wp_options de production. C’est le mode de défaillance d’une poussée fichiers-plus-base dont personne ne vous a parlé, et la raison pour laquelle l’étape 6 pose la question au lieu de se fier au libellé du bouton.

Quand cette approche n’est pas la bonne

Cette liste est calibrée pour un site WordPress où une panne coûte vraiment de l’argent : une boutique, une plateforme d’adhésion, un éditeur avec des livraisons publicitaires contractuelles. Pour un site vitrine à quelques centaines de visiteurs par jour, c’est de la surenchère, et un bon forfait mutualisé avec un cache de page battra une plateforme mal configurée bien plus chère.

C’est aussi la mauvaise lunette si votre problème est l’application plutôt que la plateforme. Un thème qui lance 400 requêtes par affichage est lent sur n’importe quelle infrastructure, et une extension qui retient un processus huit secondes sur un appel d’API externe n’est pas réglée par un pool plus gros, seulement retardée. Profilez l’application d’abord ; si le journal des requêtes lentes est plein de la même requête et que le cache d’objets est déjà connecté, la réponse est dans le code.

Cette page s’arrête aussi délibérément aux propriétés de plateforme. Ce qui se passe quand quelque chose casse à 2 h est traité dans le modèle de support WordPress d’entreprise, et la question d’acheter une plateforme plutôt que d’opérer la vôtre dans hébergement WordPress infogéré ou autogéré. Les commandes viennent de la référence des commandes WP-CLI, et la base de référence du projet pour les hébergeurs est le manuel d’hébergement WordPress.

Un WordPress qui rapporte vraiment mérite un opérateur — Stack Harbor opère cette pile sous WordPress Entreprise ; réservez une consultation d’infrastructure.