Table des matières :
- DDEV pour un projet PrestaShop : parité d’environnement, versions PHP et pièges classiques
ddev exec: exécuter des commandes de manière déterministe (Composer, Symfony, scripts maison)ddev ssh: session interactive, debug et observation (sans bricoler sur l’hôte)- Extensions d’image : GD, Imagick, EXIF, WebP/AVIF — ce que PrestaShop consomme réellement
- Installer des extensions d’image dans DDEV : temporaire vs persisté (et donc versionnable)
- Recette de validation : régénération miniatures, contrôle qualité, et garde-fous perf
DDEV pour un projet PrestaShop : parité d’environnement, versions PHP et pièges classiques
DDEV est surtout utile quand vous avez besoin d’une exécution reproductible (PHP, extensions, services annexes) sans polluer l’OS hôte. Sur PrestaShop, c’est rarement un luxe : entre les différences de memory_limit, les dépendances système (libjpeg, libpng, libwebp), les binaires (Node/Yarn), et les modules qui imposent leur propre stack, un “ça marche chez moi” se fabrique très vite. DDEV force un contrat : tout ce qui est nécessaire au run doit être déclaratif et versionné.
Côté versions, alignez d’abord PrestaShop ↔ PHP. Si vous ciblez PrestaShop 9.x, partez d’une matrice supportée (et documentée) plutôt que d’improviser. L’article interne sur la compatibilité est une référence utile pour cadrer vos choix : PrestaShop 9.1 : compatibilité PHP 8.1–8.5, CLI et nouveautés développeurs. En complément (plus “neutre” et utile pour cadrer aussi les extensions et prérequis système), la documentation officielle — prérequis d’installation.
Ensuite, figez la version via .ddev/config.yaml (ex. php_version: "8.3") et vérifiez dès le départ :
ddev exec php -v
ddev exec php -i | grep -E "Loaded Configuration File|Scan this dir for additional .ini"
Quelques pièges classiques (souvent confondus avec des “bugs PrestaShop”) :
- Droits et UID/GID : sur Linux notamment, un mauvais mapping peut vous créer des répertoires
var/cache/ouimg/inécrivables. Très tôt dans le projet, faites un test simple (création/suppression de fichiers) depuis PHP et depuis le shell. - Différences CLI vs FPM : un
php -d memory_limit=...lancé en CLI peut passer, alors que le traitement web (FPM) échoue. D’où l’intérêt d’inspecter les.inichargés et de versionner les overrides. - Ressources Docker : si Docker n’est pas correctement provisionné (CPU/RAM/IO), vous allez “optimiser” PrestaShop alors que vous optimisez un laptop à bout de souffle. Sur macOS/Windows, les montages de volumes sont souvent le goulot : dans ce cas, explorez les options DDEV dédiées (et, selon vos contraintes d’équipe, documentez-les pour éviter que chacun ait un ressenti différent sur “la perf du projet”).
- Parité ≠ production : un conteneur DDEV n’est pas votre prod (kernel, FS, réseau, reverse-proxy, stockage objet…). L’objectif est la parité sur l’exécution PHP et les outils, pas une simulation parfaite.
Pour rendre la parité “audit-able” et partageable dans une équipe (agence, freelance + client, équipe distribuée), une pratique simple consiste à lister ce qui doit être vrai au démarrage du projet, puis à le vérifier via DDEV :
Checklist “parité minimale” (à versionner et à vérifier)
.ddev/config.yaml: version PHP, type de serveur web, services additionnels (Redis/Elastic si applicable), ports..ddev/php/: overrides*.ini(ex.memory_limit,upload_max_filesize,opcache.*en dev si besoin)..ddev/web-build/(si nécessaire) : Dockerfile custom, ou mécanisme DDEV équivalent.- Commandes de sanity check documentées dans le README du projet :
ddev exec php -vddev exec php -m | sortddev exec composer -Vddev describe(URL, ports, versions, services actifs)
Mini-scénario très courant : un module d’import produit des miniatures “noires” chez un dev Windows et “OK” chez un dev macOS. Sans DDEV, on part sur une chasse aux fantômes. Avec DDEV, on compare factuellement : php -m, gd_info(), présence d’ImageMagick, et taille mémoire réellement appliquée côté PHP-FPM.
ddev exec : exécuter des commandes de manière déterministe (Composer, Symfony, scripts maison)
ddev exec sert à exécuter une commande dans le conteneur (généralement le service web). Vous éliminez donc les variables parasites : version de PHP de l’hôte, extensions manquantes, PATH différent, etc. La documentation officielle DDEV (référence des commandes) décrit explicitement ce comportement : Documentation DDEV — commandes.
C’est précisément ce que vous voulez quand vous lancez des commandes sensibles à l’environnement (Composer, bin/console, scripts d’import, outils de QA).
Exemples concrets côté PrestaShop (8.x/9.x) :
# Vérifier l’environnement d’exécution
ddev exec php -v
ddev exec php -m | sort
# Installer des dépendances de module sans dépendre du composer local
ddev exec composer install --no-interaction
# Diagnostiquer Symfony/PrestaShop sans ouvrir un shell
ddev exec php bin/console --version
ddev exec php bin/console debug:container --env=dev
Quelques usages qui font gagner du temps sur PrestaShop (notamment quand un module embarque du front) :
# Lancer un build d'assets (si votre module/thème utilise Node)
ddev exec node -v
ddev exec npm -v
ddev exec npm ci
ddev exec npm run build
# Vérifier rapidement les limites "upload" (souvent en cause sur import CSV/images)
ddev exec php -r 'echo "upload_max_filesize=" . ini_get("upload_max_filesize") . PHP_EOL;'
ddev exec php -r 'echo "post_max_size=" . ini_get("post_max_size") . PHP_EOL;'
Point important pour l’industrialisation : ddev exec renvoie un code de sortie exploitable. Donc vous pouvez l’intégrer tel quel dans des scripts Makefile, justfile, ou une CI locale. Exemple minimal (facile à relire et à partager) :
.PHONY: qa
qa:
ddev exec composer validate --no-interaction
ddev exec php -v
ddev exec php -m | grep -i gd
.PHONY: cache-clear
cache-clear:
ddev exec php bin/console cache:clear --env=dev
Si vous cherchez une chaîne reproductible de build/test, l’article Intégration continue PrestaShop : BuildKit, GitHub Actions et build reproductible pose un cadre utile ; ici, DDEV joue surtout le rôle d’“environnement standard” local (et éventuellement en CI auto-hébergée) avec le même set d’outils et d’extensions.
Astuce pratique : pour éviter les surprises de quoting (espaces, pipes, redirections), vous pouvez encapsuler la commande côté shell, mais gardez-le lisible. Exemple :
ddev exec bash -lc 'php -m | egrep -i "gd|imagick|exif" || true'
ddev ssh : session interactive, debug et observation (sans bricoler sur l’hôte)
ddev ssh ouvre une session interactive dans le conteneur (par défaut web). Là où ddev exec est parfait pour des commandes idempotentes et scriptables, ddev ssh est adapté à l’investigation : explorer le FS, lire des logs, tester une commande en boucle, lancer un profiler, etc. Typiquement : reproduire une erreur d’upload image, vérifier les droits sur img/, ou confirmer qu’une extension PHP est bien chargée.
Un pattern efficace en debug PrestaShop : entrer dans le conteneur, figer le contexte, et collecter des preuves (versions, limites, droits, logs).
ddev ssh
whoami
id
php -i | grep -E "memory_limit|max_execution_time|upload_max_filesize|post_max_size"
ls -la var/log/ app/logs/ 2>/dev/null || true
Complétez avec une lecture “serveur web / PHP-FPM” (les chemins exacts varient selon images et configs, donc restez exploratoire) :
# Explorer les logs disponibles
ls -la /var/log 2>/dev/null || true
ls -la /var/log/nginx 2>/dev/null || true
# Exemple: suivre les logs (si présents)
tail -n 200 -f /var/log/nginx/error.log 2>/dev/null || true
Quand vous traquez des erreurs “blanches” ou des réponses 500 sans stacktrace, vous gagnez du temps à relier les symptômes à la config PHP/serveur. Pour la méthodologie côté PHP (affichage, logs, niveaux d’erreur, séparation dev/prod), recoupez avec ce guide : bonnes pratiques de gestion d’erreurs PHP entre dev et production. Et pour ne pas confondre bug fonctionnel et dégradation perçue, gardez une approche “mesure d’abord” : Audit performance PrestaShop : méthode en 6 étapes reproductibles.
Enfin, ne limitez pas ddev ssh au conteneur web. En investigation, il est parfois utile d’aller voir la base :
# Entrer dans le service db (si nécessaire)
ddev ssh -s db
mysql --version
Cela évite les diagnostics “à l’aveugle” du type “MySQL est lent” alors que le souci est un swap Docker, ou une option de configuration différente entre deux machines.
Extensions d’image : GD, Imagick, EXIF, WebP/AVIF — ce que PrestaShop consomme réellement
Sur PrestaShop, les images ne sont pas un détail : import catalogue, miniatures, recadrage, conversion, performance front (poids, formats modernes). Le cœur s’appuie classiquement sur GD (extension PHP) pour redimensionner, mais l’écosystème (modules, connecteurs, DAM, export marketplaces) arrive souvent avec des exigences plus strictes : Imagick, lecture EXIF, support WebP/AVIF, gestion ICC, etc.
Deux rappels utiles pour cadrer les attentes :
- GD : rapide à mettre en place, souvent suffisant pour des JPEG/PNG “propres”, mais ses capacités dépendent fortement de la manière dont PHP/GD a été compilé (donc des libs disponibles au build).
- Imagick (extension PHP) : s’appuie sur ImageMagick et peut gérer davantage de formats/options (au prix d’une stack système plus riche). Pour le périmètre, la référence fiable reste la doc du manuel PHP : PHP — Imagick.
Le problème n’est pas théorique : il se matérialise sous forme d’erreurs silencieuses, de miniatures noires, de temps de régénération disproportionnés, ou d’images “corrompues” au sens du code.
Commencez par inventorier ce que votre conteneur fournit réellement (ne supposez rien) :
# Extensions chargées
ddev exec php -m | egrep -i "gd|imagick|exif" || true
# Fonctions clés souvent testées par des modules
ddev exec php -r 'echo "imagewebp=" . (function_exists("imagewebp") ? "yes" : "no") . PHP_EOL;'
ddev exec php -r 'echo "imageavif=" . (function_exists("imageavif") ? "yes" : "no") . PHP_EOL;'
# Capacités GD (WebP/AVIF dépendent du build)
ddev exec php -r 'var_export(function_exists("gd_info") ? gd_info() : null);'
# Côté ImageMagick (si installé)
ddev exec convert -version 2>/dev/null || true
Un cas concret (très fréquent en e-commerce) : vous recevez des visuels “smartphone” avec orientation EXIF. Sans EXIF (ou sans traitement adapté), les images peuvent apparaître pivotées dans certaines étapes du pipeline (import, miniatures, export). D’où l’intérêt de vérifier l’extension EXIF et d’avoir un jeu de tests incluant des images avec metadata.
Sur la partie “formats modernes”, gardez un objectif pragmatique : ne cherchez pas à cocher WebP/AVIF “pour le principe”. Cherchez à améliorer le poids et le rendu sans casser la compatibilité. À titre indicatif, la documentation WebP de Google rapporte des gains de compression typiques de l’ordre de 25–34% versus JPEG à qualité comparable (Google Developers, documentation WebP). En boutique, l’impact réel dépend de votre catalogue (photos produits vs packshots), du nombre d’images au-dessus de la ligne de flottaison, et de votre stratégie de cache/CDN.
Pour choisir rapidement quoi activer, un tableau “décision” aide souvent (surtout quand plusieurs modules touchent aux images) :
| Besoin courant | GD | Imagick |
|---|---|---|
| Redimensionnements simples (JPEG/PNG) | ✅ | ✅ |
| Gestion fine des profils couleur / certains formats exotiques | ⚠️ (limité) | ✅ (souvent meilleur) |
| Support WebP/AVIF côté PHP | ✅ si build compatible | ✅ si ImageMagick est compilé avec les bons délégués |
| Surface système (libs, policy) | ✅ (plus simple) | ⚠️ (à gouverner) |
Dernier point “gouvernance” : ImageMagick a déjà été concerné par des vulnérabilités notables (ex. CVE-2016-3714). En dev, ce n’est pas un motif pour l’éviter, mais c’est une raison de plus pour (1) versionner l’installation, (2) garder la stack à jour, (3) traiter les policies correctement en production.
Installer des extensions d’image dans DDEV : temporaire vs persisté (et donc versionnable)
Installer “à la main” dans un conteneur via ddev ssh puis apt-get install ... peut dépanner, mais ce n’est pas persisté : au prochain rebuild d’image, vous perdez tout. Ce mode sert uniquement à valider une hypothèse (ex. “Imagick règle-t-il ce bug de conversion WebP ?”). Dès que vous confirmez, vous devez rendre l’installation déclarative dans .ddev/.
Avant de sortir l’artillerie lourde (Dockerfile), vérifiez si votre besoin se limite à des paquets Debian. DDEV permet d’ajouter des paquets système au build de l’image web via la configuration (pratique pour imagemagick, jpegoptim, etc.). Selon votre version de DDEV, la clé la plus courante est webimage_extra_packages dans .ddev/config.yaml (à vérifier dans votre projet si vous avez déjà ce bloc) :
# .ddev/config.yaml (exemple)
webimage_extra_packages:
- imagemagick
- ghostscript
Si vous avez besoin d’une extension PHP supplémentaire (Imagick, par exemple) et que vous devez la versionner proprement, la voie classique est un build custom du service web via .ddev/web-build/Dockerfile (ou mécanique équivalente documentée par DDEV selon version). L’objectif : rendre l’installation rejouable et reviewable.
Exemple minimal pour ajouter ImageMagick + Imagick (à adapter à votre base image et à votre gestion des paquets) :
# .ddev/web-build/Dockerfile
ARG BASE_IMAGE
FROM $BASE_IMAGE
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends \
imagemagick \
php-imagick; \
rm -rf /var/lib/apt/lists/*
Ensuite, rebuild :
ddev restart
Points d’attention (sinon vous allez perdre une demi-journée) :
- Validez l’effet après rebuild, pas “en théorie” :
ddev exec php -m | egrep -i "imagick|gd|exif" || true
ddev exec php -r 'echo (class_exists("Imagick") ? "Imagick OK" : "Imagick absent") . PHP_EOL;'
- WebP/AVIF n’est pas “juste installer GD” : c’est une question de features compilées (côté GD) et/ou de délégués ImageMagick (côté convert). Ne patchez pas au hasard : contrôlez
gd_info()etconvert -version. - Policy ImageMagick : si vous observez des erreurs du type “attempt to perform an operation not allowed by the security policy”, ce n’est pas “un bug PHP” mais une policy (
policy.xml). En dev, vous pouvez diagnostiquer ; en prod, vous devez décider explicitement ce que vous autorisez.
Recette de validation : régénération miniatures, contrôle qualité, et garde-fous perf
Avant de déclarer “OK, les extensions d’image sont en place”, faites un test qui ressemble à la réalité : importez un lot (50–200 images variées : JPEG progressif, PNG avec alpha, WebP, images avec orientation EXIF, et si vous en avez : CMYK/profils ICC), puis régénérez des miniatures.
PrestaShop varie selon versions et backoffice, donc évitez de vous accrocher à un nom de commande supposé. Utilisez plutôt l’exploration via Symfony Console (si disponible) :
# Découvrir les commandes disponibles (utile sur PrestaShop 9.x)
ddev exec php bin/console list | grep -i image || true
# Et exécuter la commande identifiée avec des options explicites
# (exemples : --env=dev, -vvv, etc. selon le binaire)
Mesurez au lieu d’“observer”. Même en local, vous pouvez capturer un ordre de grandeur : temps total, mémoire, et erreurs.
# Temps d’exécution global et code retour
/usr/bin/time -v ddev exec php -d memory_limit=1024M bin/console <commande_images>
Contrôlez ensuite les logs et recherchez explicitement les erreurs de conversion (formats, policy, timeouts). Là encore, adaptez aux chemins de votre version PrestaShop :
# Contrôle logs (à adapter : var/log, app/logs, etc.)
ddev exec find var app -maxdepth 3 -type f -name "*.log" -print 2>/dev/null || true
ddev exec grep -RInE "imagick|ImageMagick|gd|webp|avif|exif|policy" var app 2>/dev/null || true
Ajoutez un contrôle qualité “simple mais utile” sur le résultat :
- Quelques miniatures au hasard : poids, dimensions attendues, transparence PNG préservée.
- Au moins une image avec orientation EXIF : pas de rotation surprenante.
- Si vous générez du WebP/AVIF via un module : vérifiez que le navigateur reçoit bien le format attendu (DevTools → Network → type MIME), et que vous avez un fallback correct.
Enfin, posez des garde-fous “performance & stabilité” avant de laisser tourner une régénération sur un gros catalogue :
- Augmentez temporairement
memory_limitetmax_execution_timedans une conf versionnée (ex..ddev/php/my-php.ini) plutôt qu’en bidouillant à la volée. Exemple :
; .ddev/php/image-tasks.ini
memory_limit=1024M
max_execution_time=300
Puis redémarrez DDEV pour appliquer.
Si vous avez des problèmes de contention disque/CPU, traitez-les comme un sujet d’architecture (ressources Docker, IO, volumes) — pas comme un “problème PrestaShop”.
Gardez une baseline : si vous optimisez les images pour améliorer LCP/INP, faites-le en cohérence avec une stratégie globale (cache, TTFB, front). Pour la partie serveur (OPcache, MySQL, PHP-FPM), recoupez avec ce guide d’optimisation : benchmarks et réglages PHP-FPM/OPcache/MySQL pour PrestaShop ; sinon vous allez “gagner” 50 ms sur des miniatures et perdre 500 ms sur le backoffice.
