Aller au contenu principal

Hébergement

Migrer le dossier files de Drupal de NFS vers l'Object Storage S3

EN BREF

  • Le stockage réseau traditionnel (NFS) présente des limites physiques de verrouillage de fichiers et d'IOPS qui pénalisent la scalabilité des plateformes Drupal multi-serveurs.
  • L'intégration du protocole S3 via le module S3FS permet de supprimer le point de défaillance unique (SPOF) en déportant les médias vers un stockage d'objets cloud natif.
  • La configuration nécessite une attention particulière sur la gestion des styles d'images pour éviter les allers-retours réseau coûteux en ressources CPU et en latence.
  • Une transition réussie repose sur une synchronisation asynchrone des données historiques et un paramétrage fin dans le fichier settings.php.

Le point de défaillance unique des montages réseaux

Dans une architecture web hautement disponible, la redondance des serveurs applicatifs est une norme absolue. Cependant, le partage du répertoire des fichiers publics et privés (situé par défaut dans sites/default/files) devient rapidement un goulot d'étranglement complexe. Historiquement, les administrateurs système déployaient un serveur NFS (Network File System) pour monter ce dossier sur chaque nœud applicatif. Cette approche pose de graves limites de performance sous forte charge.

Les verrous système et la latence sous forte charge

Le protocole NFS a été conçu pour partager des fichiers au sein d'un réseau local stable, mais il montre ses faiblesses lors de l'exécution d'applications web modernes hautement concurrentes. Lorsque des milliers d'utilisateurs parcourent un site Drupal simultanément, chaque chargement de page déclenche des requêtes de lecture et d'écriture sur le montage réseau.

NFS utilise des mécanismes de verrouillage (file locking) pour préserver l'intégrité des fichiers lors des accès simultanés. À grande échelle, ces verrous s'accumulent et créent des files d'attente système. Les threads PHP restent bloqués en attente d'un descripteur de fichier libre, ce qui augmente le temps de réponse global de l'application et peut mener à la saturation rapide des serveurs PHP-FPM.

Pourquoi le protocole NFS sature les entrées-sorties physiques

La performance du système d'entrées-sorties (IO) est intrinsèquement limitée par le réseau et le stockage physique du serveur NFS. Contrairement à un disque SSD local (NVMe) qui offre des dizaines de milliers d'IOPS, un montage NFS standard introduit une latence réseau supplémentaire pour chaque opération de lecture/écriture (system call latency).

Si l'application doit vérifier la présence d'un fichier (via la fonction file_exists de PHP), la requête traverse le réseau physique. Sur un site Drupal riche en médias où une seule page peut solliciter des dizaines de fichiers, cette surcharge réseau cumulée dégrade dramatiquement l'expérience utilisateur.

Graphique montrant la hausse exponentielle du temps de réponse PHP-FPM sous NFS par rapport à la stabilité de l'Object Storage

L'alternative cloud native : le stockage d'objets S3

Pour s'affranchir des limitations physiques et architecturales du NFS, l'adoption de l'Object Storage (compatible avec l'API S3 d'AWS ou les solutions souveraines d'OVHcloud) s'impose comme la solution de référence pour les infrastructures modernes.

Avantages de l'Object Storage par rapport au système de fichiers partagé

L'Object Storage ne repose pas sur une structure de dossiers hiérarchique classique, mais stocke chaque élément comme un objet unique accessible directement par une clé unique via des protocoles HTTP/HTTPS standard.

  • Scalabilité horizontale : la capacité de stockage et la bande passante s'adaptent automatiquement au volume de données, sans nécessiter d'opération de redimensionnement de disque de la part des administrateurs système.
  • Haute disponibilité native : les fichiers sont répliqués par défaut sur plusieurs zones de disponibilité au sein de l'infrastructure de l'hébergeur cloud, garantissant une résilience bien supérieure à un serveur NFS unique.
  • Soulagement des serveurs applicatifs : le trafic lié aux médias est déchargé vers les infrastructures de stockage d'objets, libérant de la bande passante et des ressources système sur vos serveurs Drupal.
  • Intégration simplifiée avec un CDN : la distribution des médias via un réseau de diffusion de contenu (comme Cloudflare, CloudFront ou OVH CDN) est nativement optimisée avec l'Object Storage, permettant d'abaisser la latence de chargement à quelques millisecondes partout dans le monde.

Configuration pas-à-pas du Stream Wrapper S3 sous Drupal

La mise en production d'une telle architecture nécessite le remplacement du gestionnaire de fichiers natif de Drupal par un Stream Wrapper capable d'intercepter les requêtes de fichiers pour les rediriger vers l'API S3. Nous utiliserons ici le module s3fs, réputé pour sa robustesse et sa gestion performante des caches de métadonnées.

Installation des paquets requis et du module s3fs

La première étape consiste à installer le module et ses dépendances de manière propre à l'aide de Composer. Cette commande télécharge automatiquement le SDK AWS pour PHP requis pour communiquer avec les API compatibles S3.

# Installation du module Drupal s3fs et du kit SDK AWS
composer require drupal/s3fs

Une fois le module téléchargé, activez-le via l'interface d'administration ou en ligne de commande avec Drush :

# Activation du module via Drush
drush pm:enable s3fs -y

Configuration du fichier settings.php pour la production

Pour des raisons évidentes de sécurité et de performance, la configuration de la connexion à votre bucket S3 doit être centralisée dans le fichier settings.php de votre installation Drupal. Cela permet également de faire varier la configuration selon l'environnement de déploiement (développement, pré-production, production).

Voici l'exemple de configuration optimisée à inclure dans votre fichier settings.php :

/**
 * Configuration du stockage d'objets S3 avec le module S3FS.
 */
// Définition de S3FS comme gestionnaire par défaut pour les dossiers publics et privés
$settings['s3fs.use_s3_for_public'] = TRUE;
$settings['s3fs.use_s3_for_private'] = TRUE;

// Configuration des accès et des endpoints du bucket
$config['s3fs.settings']['bucket'] = 'mon-bucket-drupal-prod';
$config['s3fs.settings']['region'] = 'fr-par'; // Exemple pour la région Paris
$config['s3fs.settings']['use_custom_host'] = TRUE;
$config['s3fs.settings']['hostname'] = 's3.fr-par.scw.cloud'; // Exemple Scaleway ou endpoint OVH S3

// Configuration des clés d'API (à injecter idéalement via des variables d'environnement)
$config['s3fs.settings']['access_key'] = getenv('S3_ACCESS_KEY') ?: 'votre-cle-acces-ici';
$config['s3fs.settings']['secret_key'] = getenv('S3_SECRET_KEY') ?: 'votre-cle-secrete-ici';

// Paramétrage des en-têtes de cache pour optimiser les performances de distribution
$config['s3fs.settings']['cache_control_header'] = 'public, max-age=31536000, immutable';

// Activation de la mise en cache locale des métadonnées pour réduire les appels d'API de vérification
$settings['s3fs.use_s3_for_uploads'] = TRUE;
$config['s3fs.settings']['use_s3_client_cache'] = TRUE;

Optimisation stratégique de la génération des styles d'images

L'un des principaux écueils lors de la migration vers l'Object Storage concerne la création des styles d'images (les différentes résolutions générées par Drupal pour s'adapter aux différents écrans).

Comprendre le cycle de traitement de Drupal et ses faiblesses sur S3

Par défaut, lorsqu'un utilisateur demande une déclinaison d'image qui n'existe pas encore, Drupal intercepte la requête HTTP, télécharge l'image source depuis S3 vers un espace temporaire local, applique les filtres graphiques (redimensionnement, compression), sauvegarde la nouvelle image dérivée sur S3, puis la renvoie à l'utilisateur.

Ce processus synchrone génère :

  • Une latence excessive pour le premier utilisateur qui demande l'image (parfois plusieurs secondes).
  • Une consommation CPU importante sur vos serveurs PHP-FPM.
  • Des transferts réseau aller-retour constants et coûteux entre le serveur applicatif et l'Object Storage.

Implémenter un mécanisme asynchrone de génération et de distribution

Pour optimiser ce workflow de production, nous recommandons de décorréler la génération des styles d'images du trafic utilisateur principal.

  • Délégation au CDN : configurez votre CDN pour qu'il serve directement les styles d'images existants depuis le bucket S3. En cas d'absence du fichier (erreur 404), le CDN redirige temporairement la requête vers une instance Drupal spécifique dédiée aux tâches asynchrones.
  • Génération en tâche de fond : utilisez le module complémentaire Image Style Warmer pour pré-générer les déclinaisons d'images dès la création ou la mise à jour d'un contenu par un contributeur. L'utilisateur final ne subit ainsi jamais la latence du premier appel.
  • Cache permanent : configurez la base de données locale pour stocker l'état et l'existence des fichiers distants afin d'éviter que Drupal ne vérifie physiquement sur S3 la présence d'une image à chaque affichage de page.

Voici un exemple de code PHP à placer dans un module personnalisé (nommé par exemple custom_s3_optimisations.module) pour pré-générer automatiquement des styles d'images essentiels lors de l'insertion de nouveaux médias :

<?php

/**
 * @file
 * Contient les optimisations de performances pour la gestion des images sur S3.
 */

use Drupal\media\MediaInterface;
use Drupal\image\Entity\ImageStyle;

/**
 * Implements hook_ENTITY_TYPE_insert() for media entities.
 */
function custom_s3_optimisations_media_insert(MediaInterface $media) {
  // Liste des styles d'images critiques à générer immédiatement
  $styles_critiques = ['thumbnail', 'large', 'card_responsive'];
  
  if ($media->bundle() === 'image') {
    $fid = $media->getSource()->getSourceFieldValue($media);
    if ($fid) {
      $file = \Drupal\file\Entity\File::load($fid);
      if ($file) {
        $uri = $file->getFileUri();
        
        // Déclenchement de la génération asynchrone pour chaque style défini
        foreach ($styles_critiques as $style_name) {
          $image_style = ImageStyle::load($style_name);
          if ($image_style) {
            // Création de l'image dérivée directement sur l'Object Storage
            $destination = $image_style->buildUri($uri);
            if (!file_exists($destination)) {
              $image_style->createDerivative($uri, $destination);
            }
          }
        }
      }
    }
  }
}

Méthodologie de migration des données de production

Pour réaliser la bascule d'une plateforme existante hébergeant des dizaines de gigaoctets (ou téraoctets) de fichiers sur un montage NFS vers l'Object Storage, la méthode doit être rigoureuse pour éviter toute coupure de service.

  • Première phase : réalisez une synchronisation initiale en arrière-plan à l'aide de l'outil rclone (extrêmement performant pour le transfert vers du stockage d'objets).
  • Deuxième phase : configurez s3fs en mode lecture/écriture tout en gardant une synchronisation active des nouveaux fichiers arrivants pendant la phase transitoire.
  • Troisième phase : mettez à jour la configuration settings.php globale pour finaliser la bascule définitive.

La commande rclone ci-dessous illustre comment démarrer la copie initiale de vos données locales vers le bucket distant :

# Configuration et lancement de la synchronisation avec rclone
rclone sync /var/www/drupal/web/sites/default/files/ mon_s3_distant:mon-bucket-drupal-prod/ --transfers 16 --checkers 32 --progress

Cette méthode permet de limiter au strict minimum le delta de fichiers à synchroniser lors de la coupure de l'accès en écriture sur le site pendant la maintenance de bascule finale.

Conclusion

Migrer le dossier des fichiers de Drupal d'un montage NFS vieillissant vers un stockage d'objets cloud natif compatible S3 résout de manière définitive les problèmes de concurrence d'écriture, de verrouillage système et de scalabilité horizontale de votre plateforme d'hébergement. Associée à un CDN performant et à une stratégie intelligente de génération des styles d'images, cette architecture garantit un temps de réponse minimal et une haute disponibilité sans compromis pour vos projets Drupal à fort trafic.

FAQ : tout savoir sur la migration de Drupal vers le stockage S3

Est-il possible d'utiliser l'Object Storage pour les fichiers privés de Drupal ?

Oui, le module S3FS prend pleinement en charge le schéma de stockage private://. Les fichiers stockés de cette manière ne sont pas accessibles publiquement via le CDN. Le module génère automatiquement des URLs présignées temporaires et sécurisées avec une durée de validité restreinte pour permettre l'accès aux utilisateurs autorisés par le système de permissions de Drupal.

Quel est l'impact financier du passage de NFS à S3 ?

L'Object Storage est facturé à l'usage réel (au gigaoctet stocké et au volume de requêtes HTTP sortantes). Bien qu'il engendre des coûts de transfert réseau légers, il supprime le besoin de maintenir un serveur NFS dédié surdimensionné ou des volumes de stockage bloc réseau coûteux et souvent sous-utilisés. Pour les architectures à fort trafic, l'association de l'Object Storage à un CDN limite fortement les appels directs et rend l'opération financièrement très avantageuse.

La mise en cache des métadonnées avec S3FS est-elle obligatoire ?

Oui, la mise en cache locale des métadonnées (dans la base de données de Drupal) est fortement recommandée en production. Sans cette option, Drupal doit exécuter des requêtes réseau d'API vers S3 à chaque fois qu'il cherche à l'aide de PHP si un fichier existe ou à connaître sa taille. Cela ralentirait considérablement l'affichage des pages et ferait s'envoler votre facture de requêtes auprès de votre fournisseur cloud.

Que se passe-t-il si l'Object Storage devient temporairement inaccessible ?

L'Object Storage des grands fournisseurs cloud (AWS, OVHcloud, Scaleway) garantit un taux de disponibilité extrêmement élevé (généralement supérieur à 99,9 %). Pour prémunir votre application de toute coupure, vous pouvez configurer un CDN en frontal de votre bucket S3 doté de fonctionnalités de cache persistant (Stale-While-Revalidate). Ainsi, même en cas de panne temporaire du stockage d'origine, les médias déjà mis en cache restent servis de façon transparente à vos visiteurs.

Cyprien Prouvot

Cyprien Prouvot

Associé & Directeur Technique

Associé de l'agence, Cyprien pilote la vision technique et garantit la qualité des développements web. Il encadre les équipes internes et conseille les clients sur les choix d'architecture ou d'outils digitaux les plus pertinents. Il intervient également sur ce blog pour décrypter l'écosystème web, les tendances tech et les bonnes pratiques de conception.


Prêt ? Partez.

Que ce soit pour vous aider à faire le point sur vos besoins ou vous présenter les avantages et fonctionnalités de nos solutions, nous sommes là.
 

Back to top