Kennisbank › Vps Hosting › Optimiser WordPress sur un VPS : la stack Nginx, PHP FPM, Redis et OPcache
vps hosting gemiddeld 16 September 2026

Optimiser WordPress sur un VPS : la stack Nginx, PHP FPM, Redis et OPcache

Optimiser WordPress sur un VPS : la stack Nginx, PHP-FPM, Redis et OPcache Un VPS avec 2 GB de RAM peut faire tourner WordPress plus vite qu'un hébergement

Ce guide s'adresse à quelqu'un qui a déjà un accès root à un VPS et une installation WordPress fonctionnelle. Si tu débutes sur Linux, commence par un hébergement managé — le temps que tu perdras à comprendre pourquoi ta base de données sature à 3 h du matin ne se rattrape pas sur la facture.

Prérequis

Un VPS sous Debian 12 ou Ubuntu 24.04 LTS. Les commandes ci-dessous utilisent `apt` et `systemctl`, donc pas de RHEL ni d'AlmaLinux sans adaptation.

Les versions testées : Nginx 1.24, PHP 8.3 avec PHP-FPM, MariaDB 10.11, Redis 7.2, WP-CLI 2.10. Des versions plus récentes fonctionnent aussi, mais les chemins de configuration peuvent différer.

Il te faut :

  • Un accès SSH avec un utilisateur `sudo`, pas root directement pour WordPress.
  • WordPress 6.5 ou plus récent, installé dans `/var/www/monsite`.
  • Le plugin Redis Object Cache (version 2.5 ou plus) si tu veux la partie object cache.
  • Une sauvegarde de la base et des fichiers avant de toucher à quoi que ce soit. Sans exception.
Un mot sur le coût de cette approche : tu vas tout configurer à la main. Un panneau comme RunCloud ou GridPane fait la même chose en trois clics pour 8 à 15 € par mois et par serveur. C'est un choix légitime si tu ne veux pas maintenir la configuration toi-même. La suite de cet article part du principe que tu veux comprendre ce que ces panneaux font à ta place.

Étape 1 — Mesurer avant de toucher à quoi que ce soit

Sans mesure initiale, tu ne sauras jamais si tes changements ont servi à quelque chose. Installe les outils de diagnostic.

```bash sudo apt update sudo apt install -y htop iotop sysstat curl ```

`htop` montre CPU et RAM en temps réel. `iotop` montre quels processus écrivent sur le disque — utile quand MySQL sature l'I/O. `sysstat` fournit `iostat` et `sar` pour des mesures historiques.

Relève ta Time To First Byte (TTFB) avant optimisation :

```bash curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://monsite.be ```

Note le chiffre. C'est ta ligne de départ. Une TTFB au-dessus de 600 ms sur une page non cachée indique que PHP ou MySQL travaille trop.

Étape 2 — Activer OPcache correctement

OPcache garde le bytecode PHP compilé en mémoire. Sans lui, PHP recompile chaque script à chaque requête. C'est du CPU gaspillé pour rien.

Vérifie d'abord s'il est actif :

```bash php -i | grep opcache.enable ```

Si la sortie indique `Off`, édite la configuration :

```bash sudo nano /etc/php/8.3/fpm/conf.d/10-opcache.ini ```

Ajoute ou ajuste :

```ini opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=10000 opcache.revalidate_freq=60 opcache.validate_timestamps=1 opcache.save_comments=1 ```

`memory_consumption=128` suffit pour la plupart des sites. Monte à 256 si tu utilises beaucoup de plugins lourds. `max_accelerated_files=10000` couvre WordPress et ses dépendances ; en dessous, OPcache vide son cache et recompile, ce qui annule le bénéfice.

`validate_timestamps=1` fait qu'OPcache vérifie les fichiers modifiés toutes les 60 secondes. Mets-le à `0` en production pure pour gagner un peu — mais alors tu devras vider OPcache à chaque déploiement. C'est un compromis, pas une évidence.

Recharge PHP-FPM :

```bash sudo systemctl reload php8.3-fpm ```

Étape 3 — Régler PHP-FPM selon ta RAM

PHP-FPM gère les processus qui exécutent WordPress. Mal réglé, il consomme toute la RAM ou refuse des visiteurs sous charge.

Ouvre le pool :

```bash sudo nano /etc/php/8.3/fpm/pool.d/www.conf ```

Pour un VPS de 2 GB de RAM, avec PHP à environ 40 MB par processus :

```ini pm = dynamic pm.max_children = 25 pm.start_servers = 5 pm.min_spare_servers = 3 pm.max_spare_servers = 8 pm.max_requests = 500 ```

La règle : `pm.max_children` multiplié par la mémoire moyenne d'un processus PHP ne doit pas dépasser 60 à 70 % de la RAM disponible. Sur 4 GB, tu peux monter à 50 enfants. Sur 8 GB, à 100.

`pm.max_requests = 500` recycle les processus après 500 requêtes. Ça masque les fuites mémoire de plugins mal écrits. Le coût : un léger pic de CPU à chaque recyclage. C'est acceptable.

Recharge :

```bash sudo systemctl reload php8.3-fpm ```

Étape 4 — Activer le page cache côté Nginx

Un page cache stocke le HTML final. La requête suivante ne touche ni PHP ni MySQL. C'est le gain le plus important de toute la stack.

Ouvre la configuration de ton site :

```bash sudo nano /etc/nginx/sites-available/monsite.be ```

Ajoute dans le bloc `http` (ou dans un fichier séparé dans `/etc/nginx/conf.d/`) :

```nginx fastcgi_cache_path /var/cache/nginx/monsite levels=1:2 keys_zone=monsite_cache:100m inactive=60m max_size=1g; fastcgi_cache_key "$scheme$request_method$host$request_uri"; ```

Puis dans le bloc `server` :

```nginx set $skip_cache 0;

if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } if ($request_uri ~ "/wp-admin/|/wp-json/|/xmlrpc.php|wp-..php|/feed/|sitemap(_index)?.xml") { set $skip_cache 1; } if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1; }

location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.3-fpm.sock;

fastcgi_cache monsite_cache; fastcgi_cache_valid 200 301 302 60m; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache_use_stale error timeout updating http_500 http_503; add_header X-FastCGI-Cache $upstream_cache_status; } ```

Les conditions `skip_cache` évitent de servir une page en cache à un utilisateur connecté ou après un commentaire. Sans elles, tu montres le contenu d'un visiteur à un autre. C'est le genre d'erreur qui se découvre trop tard.

Crée le dossier et recharge :

```bash sudo mkdir -p /var/cache/nginx/monsite sudo chown -R www-data:www-data /var/cache/nginx sudo nginx -t sudo systemctl reload nginx ```

Étape 5 — Installer Redis pour l'object cache

WordPress interroge MySQL des dizaines de fois par page pour les options, les métadonnées, les utilisateurs. Redis garde ces objets en RAM.

```bash sudo apt install -y redis-server php8.3-redis sudo systemctl enable --now redis-server ```

Vérifie que Redis écoute en local uniquement :

```bash sudo ss -tlnp | grep 6379 ```

Tu dois voir `127.0.0.1:6379`, pas `0.0.0.0:6379`. Redis n'a pas d'authentification par défaut. Exposé sur internet, c'est une porte ouverte.

Ajoute les constantes dans `wp-config.php`, avant la ligne `/ That's all, stop editing! /` :

```php define('WP_REDIS_HOST', '127.0.0.1'); define('WP_REDIS_PORT', 6379); define('WP_REDIS_TIMEOUT', 1); define('WP_REDIS_READ_TIMEOUT', 1); define('WP_REDIS_DATABASE', 0); define('WP_CACHE', true); ```

Active le plugin via WP-CLI :

```bash sudo -u www-data wp plugin install redis-cache --activate --path=/var/www/monsite sudo -u www-data wp redis enable --path=/var/www/monsite ```

Étape 6 — Tuning de MariaDB

MariaDB sort de l'installation avec des réglages pensés pour un Raspberry Pi. `innodb_buffer_pool_size` est le paramètre le plus important : il détermine combien de RAM MariaDB utilise pour garder les pages de données en mémoire.

Édite la configuration :

```bash sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf ```

Sous `[mysqld]` :

```ini innodb_buffer_pool_size = 512M innodb_log_file_size = 128M innodb_flush_method = O_DIRECT innodb_flush_log_at_trx_commit = 2 max_connections = 50 query_cache_type = 0 query_cache_size = 0 ```

Pour 2 GB de RAM, `innodb_buffer_pool_size = 512M` est raisonnable. Sur 4 GB, monte à 1G. La règle empirique : 50 à 70 % de la RAM disponible si la base est seule sur le serveur.

`innodb_flush_log_at_trx_commit = 2` réduit les écritures disque à chaque transaction. Tu perds au maximum une seconde de transactions en cas de crash. Sur un site de contenu, c'est acceptable. Sur une boutique, laisse à `1`.

Redémarre :

```bash sudo systemctl restart mariadb ```

Étape 7 — Nettoyer la base et compresser les images

Les révisions, les commentaires spam et les transients expirés s'accumulent. Chaque requête qui les croise coûte du temps.

```bash sudo -u www-data wp transient delete --expired --path=/var/www/monsite sudo -u www-data wp post delete $(sudo -u www-data wp post list --post_type=revision --format=ids --path=/var/www/monsite) --force --path=/var/www/monsite sudo -u www-data wp db optimize --path=/var/www/monsite ```

Pour les images, `jpegoptim` et `optipng` font le travail en ligne de commande :

```bash sudo apt install -y jpegoptim optipng find /var/www/monsite/wp-content/uploads -type f -name "*.jpg" -exec jpegoptim --strip-all --max=85 {} \; find /var/www/monsite/wp-content/uploads -type f -name "*.png" -exec optipng -o2 {} \; ```

`--max=85` applique une compression avec perte légère. À l'œil nu, invisible. Sur le poids total, souvent 40 % de gain. Pousse à 80 si tu veux, mais teste d'abord sur une page avec des dégradés — c'est là que ça se voit.

Étape 8 — Ajouter un CDN devant tout ça

Le CDN cache les fichiers statiques sur des serveurs proches du visiteur. Il réduit la latence et décharge ton VPS.

Cloudflare en plan gratuit fonctionne bien pour WordPress. Tu changes les nameservers chez ton registrar, tu laisses Cloudflare gérer le DNS, et tu actives le proxy orange sur l'enregistrement A.

Deux réglages à ne pas oublier : mets le mode SSL sur « Full (strict) » et désactive Rocket Loader si tu utilises un page builder. Rocket Loader casse régulièrement les scripts des thèmes basés sur Elementor ou Divi. Le plan gratuit suffit pour la majorité des sites ; le plan Pro à 20 $ par mois ajoute le cache HTML complet et l'optimisation d'images, ce qui peut valoir le coup si tu ne veux pas gérer ça côté serveur.

Vérification

Recharge ta page trois fois de suite, puis regarde l'en-tête :

```bash curl -I https://monsite.be | grep -i x-fastcgi-cache ```

Tu dois voir `X-FastCGI-Cache: HIT` à partir de la deuxième requête. Si c'est `MISS` à chaque fois, ton cache Nginx ne fonctionne pas — vérifie les règles `skip_cache` et que le cookie de session n'est pas présent.

Vérifie Redis :

```bash sudo -u www-data wp redis status --path=/var/www/monsite ```

La sortie doit indiquer `Status: Connected`.

Refais la mesure de TTFB :

```bash curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://monsite.be ```

Compare avec ton relevé de l'étape 1. Sur un site correctement caché, tu descends souvent sous 100 ms.

Problèmes courants

Le site affiche la page d'un autre utilisateur, ou un panier vide. Ton page cache sert du contenu personnalisé. Vérifie que les cookies `wordpress_logged_in`, `woocommerce_cart_hash` et `comment_author` sont bien dans la liste `skip_cache`. Ajoute les cookies de ton plugin e-commerce à la même liste.

PHP-FPM sature et renvoie des 502. Tu as mis trop de `pm.max_children` pour ta RAM. Regarde `htop` : si la mémoire est pleine et que le swap est utilisé, réduis. Un enfant PHP de trop coûte plus cher qu'un visiteur qui attend 200 ms de plus.

OPcache ne se met pas à jour après un déploiement. Si `opcache.validate_timestamps=0`, recharge PHP-FPM après chaque déploiement : `sudo systemctl reload php8.3-fpm`. Sinon, laisse à `1` et vis avec 60 secondes de latence sur les mises à jour de code.

La stack Nginx, PHP-FPM, Redis et OPcache n'est pas la seule valable. OpenLiteSpeed avec LSCache fait aussi bien sur certains profils, et un hébergement managé te sort de l'équation. Ce que tu gagnes ici, c'est la compréhension de ce qui se passe entre la requête du visiteur et la réponse — et cette compréhension, aucun panneau ne te la vend.

← Terug naar kennisbank
← Terug naar kennisbank