Migration PrestaShop 1.7 vers PrestaShop 9 : méthodologie en production

Méthodologie complète pour migrer PrestaShop 1.7 vers 9 en production : audit modules/thème, staging reproductible, migration DB, tests et rollback.

Écrans d'ordinateur montrant la migration de PrestaShop 1.7 vers 9 avec du code et des graphiques.

Table des matières :

  1. Cartographie avant migration : ce qui casse réellement entre 1.7 et 9
  2. Chemin de montée de version : éviter le saut 1.7 ➜ 9 en one-shot
  3. Staging reproductible : cloner sans contaminer (données, emails, secrets)
  4. Migration applicative : thème, modules, overrides, Composer et back-office Symfony
  5. Migration données et performance : DB, index, cache, jobs, intégrations
  6. Bascule production : fenêtre de maintenance, rollback, SEO et observabilité

Cartographie avant migration : ce qui casse réellement entre 1.7 et 9

Migrer PrestaShop 1.7 vers PrestaShop 9 en production n’est pas un “upgrade” mais une opération de reprise applicative : vous changez de runtime (PHP), de dépendances (Symfony / Composer), de conventions de modules et, souvent, de thème. Le point de départ est un inventaire exploitable, pas un export Excel « modules installés ». En pratique, vous devez corréler modules actifs, hooks réellement exécutés, overrides chargés, patchs core et intégrations externes (ERP, PIM, paiement, tracking). La checklist d’audit thème / modules / hooks / overrides est à traiter comme un livrable technique, pas comme une formalité : voir Migration PrestaShop : checklist d’audit thème, modules, hooks et overrides.

Pour que cette cartographie soit actionnable en prod, fixez dès le départ le périmètre fonctionnel “non négociable” (souvent sous-estimé) :

  • tunnel de commande (paiement, transport, promotions, taxes),
  • emails transactionnels (confirmation, expédition, avoir),
  • export factures / avoirs (et contraintes locales : numérotation, TVA, mentions légales),
  • moteurs de recherche internes et navigation à facettes,
  • connecteurs (ERP / CRM / PIM, marketplace, transporteurs),
  • tracking / consentement (surtout si vous opérez en France / UE avec contraintes RGPD).

Un bon signal terrain : si votre boutique dépend d’un ou deux modules “clés” (paiement / transport) non maintenus ou personnalisés via override, vous n’êtes plus dans une simple montée de version ; vous êtes dans une reconstruction contrôlée.

Côté données, une 1.7 “qui tourne” cache souvent des anomalies qui explosent lors d’une montée majeure : ps_configuration polluée, tables en MyISAM, collations incohérentes, index manquants (ou inversément des index “custom” jamais documentés). Avant de parler PrestaShop 9, faites un état MySQL : charset / collation (idéalement utf8mb4), moteur InnoDB, taille des plus grosses tables (ps_order*, ps_cart*, ps_connections, logs modules). Si vous avez déjà des bricolages autour de la configuration, cadrer proprement est indispensable (ex. état panier en base) : Éviter l’état panier dans la table ps_configuration.

Ajoutez un contrôle simple mais souvent révélateur : la dérive volumétrique. Si ps_connections, ps_guest ou des tables de log modules prennent plusieurs dizaines de Go, ce n’est pas “juste du bruit” : c’est un facteur de latence (IO, buffer pool, backups) qui augmente mécaniquement le risque pendant les opérations de migration et de rollback.

L’inventaire doit être automatisable pour être rejoué (staging, préprod, prod). Typiquement : export des modules actifs, scan des overrides et extraction des hooks sur lesquels vous avez une densité anormale (symptôme de dette technique). Exemple minimal (à adapter au préfixe et multiboutique) :

-- Modules activés
SELECT m.name, m.version, m.active
FROM ps_module m
WHERE m.active = 1
ORDER BY m.name;

-- Hooks réellement “câblés” (modules greffés sur des hooks)
SELECT h.name AS hook, m.name AS module, hm.position
FROM ps_hook_module hm
JOIN ps_hook h ON h.id_hook = hm.id_hook
JOIN ps_module m ON m.id_module = hm.id_module
ORDER BY h.name, hm.position;

-- Collations / moteurs (repérage rapide des incohérences)
SELECT table_name, engine, table_collation
FROM information_schema.tables
WHERE table_schema = DATABASE()
  AND table_name LIKE 'ps\_%'
ORDER BY table_name;

Le but n’est pas d’avoir “beaucoup d’infos”, mais d’identifier 10–20 éléments bloquants : modules non maintenus, overrides qui touchent Cart, PaymentModule, Order, Product, modifications du FO, et intégrations qui dépendent du Webservice legacy.

Mini-scénario réaliste (souvent vu en France sur des boutiques à fort trafic) : un marchand a une 1.7 stable, mais avec (1) un override sur Cart pour une règle promo historique, (2) un module de paiement custom “branché” sur des hooks sensibles, (3) un thème FO modifié directement en prod. En 1.7, ça tient. En 9, ce combo devient instable : signatures PHP changées, dépendances Symfony / Composer plus strictes, et le BO bascule davantage vers Symfony. La cartographie sert précisément à repérer ce trio à risque avant de lancer le moindre script.

Chemin de montée de version : éviter le saut 1.7 ➜ 9 en one-shot

En octobre 2026, le saut direct 1.7 ➜ 9 est rarement le meilleur choix en production : la probabilité de tomber sur un combo “module + override + thème” incompatible est élevée, et les scripts de migration DB deviennent difficiles à diagnostiquer si vous concentrez tout en une seule exécution. La stratégie robuste est incrémentale : stabiliser en 1.7.8.x (dernière maintenance), puis passer par une branche 8.x avant d’atterrir sur 9.x. Vous réduisez ainsi la surface des changements par étape, et vous isolez les régressions.

En pratique, ce chemin incrémental vous permet surtout de décorréler trois chantiers qui sinon s’additionnent :

  • socle système (PHP, extensions, paramètres FPM, OPcache),
  • compatibilité code (modules / thème / overrides),
  • migration de données (schémas, collations, index, nettoyage).

Sur le terrain, l’erreur classique est de traiter l’upgrade comme un “déploiement” : même serveur, même PHP, mêmes limites memory_limit, et on lance. Or PrestaShop 9 impose un socle moderne (PHP 8.2+ dans la majorité des stacks, extensions, opcache correctement dimensionné). Si vous êtes en MySQL 5.7 / MariaDB ancien, vous cumulez deux migrations (app + SGBD) et vous décuplez le risque. Si une montée MySQL est dans le scope, faites-la en amont avec une procédure de staging et tests de charge : MySQL : procédure de migration 5.7 → 8, staging et tests de charge.

Un point méthodo qui évite des nuits blanches : définissez une “matrice de compatibilité” (même simple) avant l’exécution, pour savoir si un blocage vient du socle, du code ou de la donnée. Par exemple :

Couche Ce qui change entre étapes Symptômes typiques Vérification rapide
PHP / extensions version PHP, intl, gd, zip, opcache white screen, erreurs fatales, memory exhausted logs PHP-FPM + php -m
Composer / vendors versions verrouillées, autoload classes introuvables, conflits dépendances composer install reproductible
Modules / overrides hooks, signatures, surcharge classes BO cassé, checkout KO, erreurs sur Cart logs + désactivation ciblée
DB / collation / index schémas, encodage, index lenteurs subites, deadlocks, erreurs SQL EXPLAIN + slow queries

Pour la méthode manuelle et reproductible (hors “clic magique”), l’article « Mise à jour PrestaShop : procédure de migration manuelle 1.6/1.7 vers 8.x » sert de base pour formaliser vos étapes (git, artefacts, rollback) : Mise à jour PrestaShop : procédure de migration manuelle 1.6/1.7 → 8.x.

« Symfony is a set of reusable PHP components and a PHP framework for web projects. » — Symfony Project

Cette réalité (PrestaShop s’appuie de plus en plus sur Symfony / Composer) impose une discipline : dépendances verrouillées, build reproductible, et validation CI, sinon votre “migration” devient un débogage live.

Staging reproductible : cloner sans contaminer (données, emails, secrets)

Votre staging doit être un miroir fonctionnel de la prod, pas une sandbox approximative. Concrètement : dump DB + synchronisation des médias (img/, download/, upload/), mêmes versions de PHP-FPM / Nginx / Apache, mêmes modules activés, mêmes variables d’environnement, et surtout mêmes volumes (taille DB, nombre d’images, nombre de déclinaisons). Un staging sous-dimensionné valide des pages “à vide” et échoue quand vous rejouez sur des tables à 30–200 Go.

La partie la plus souvent négligée est la neutralisation des effets de bord : emails transactionnels, webhooks, ERP, paiements, tracking. Avant même de lancer une montée de version, vous devez pouvoir démarrer un clone en mode safe :

  • désactivation (ou “mode bac à sable”) des modules de paiement,
  • désactivation des envois email (ou routage vers un SMTP de test),
  • blocage sortant au niveau réseau (egress) vers ERP / CRM si nécessaire,
  • rotation des secrets (API keys) si le staging sort sur Internet.

Ajoutez un point souvent incontournable en contexte France / UE : données personnelles. Un staging qui contient emails / téléphones / adresses réelles devient rapidement un risque organisationnel (accès trop large, logs, exports). Sans transformer l’article en guide RGPD, retenez une règle opérationnelle : si l’environnement est accessible à plus de personnes que la prod (ou moins sécurisé), anonymisez / pseudonymisez. Même une anonymisation “minimaliste” réduit fortement le risque (ex. remplacer emails par des valeurs non délivrables, masquer téléphones).

Si vous industrialisez ce point, vous gagnez du temps à chaque itération de migration.

Sur les stacks hébergées, formalisez aussi la bascule DNS / HTTPS dès le staging : certificats, redirections, HSTS, et validation que l’URL canonique est stable. La partie “DNS + HTTPS Let’s Encrypt” (très concrète côté prod) est détaillée ici : PrestaShop Lightsail : DNS, nom de domaine et HTTPS Let’s Encrypt. Même si vous n’êtes pas sur Lightsail, la logique (TTL, propagation, renouvellement, pièges de redirection) est transposable.

Dernier réflexe utile : verrouiller un jeu de tests de non-régression sur staging (même simple, mais écrit). Exemple de check “avant / après” :

  • checkout complet (invité + client), avec au moins 2 modes de livraison,
  • un paiement “OK” + un paiement “refusé” (pour tester les retours d’état),
  • génération facture / avoir,
  • recherche + navigation catégories,
  • création compte + reset mot de passe,
  • une commande via mobile (CSS / JS thème).

Si vous industrialisez ces tests, vous gagnez beaucoup en confiance lors de la bascule.

Migration applicative : thème, modules, overrides, Composer et back-office Symfony

Le principal facteur de risque entre 1.7 et 9 n’est pas la base : c’est le code métier autour du core. En 1.7, beaucoup de boutiques “sauvent” des features via overrides et surcharges de classes historiques. En 9, les évolutions Symfony et la montée en exigences PHP rendent ces surcharges plus fragiles, et l’override devient un point de conflit récurrent (autoload, signatures, services). Si vous partez avec une dette d’override, commencez par réduire / retirer ce qui est remplaçable par des hooks ou un module propre.

Approche pragmatique :

  1. figer une version de référence 1.7 (tag git + dump DB),
  2. sur staging, remettre à plat les overrides (suppression contrôlée + tests),
  3. migrer les customisations vers un module dédié “sans override” quand possible.

Sur ce point, l’article « Module PrestaShop sans override : méthode de cadrage, tests et livraison du code » est aligné avec une migration 1.7 ➜ 9 : Module PrestaShop sans override : méthode.

Deux heuristiques simples qui évitent des régressions “fantômes” :

  • Tout override supprimé doit être remplacé soit par un hook, soit par une spécification “on accepte le comportement standard” (sinon vous réintroduisez de la dette sans le dire).
  • Tout module critique doit avoir un plan B le jour de la bascule (version compatible confirmée, ou module alternatif, ou fonctionnalité désactivable sans bloquer la vente).

Côté outillage, ce n’est pas optionnel : vous devez compiler / valider votre code avant exécution. ps-validator vous donne un premier niveau de contrôle (structure module, erreurs fréquentes) et se plug en CI / CD : ps-validator : intégration CI/CD. Pour la dette PHP, passez aussi par PHPStan / PHPUnit et un plan PHP 8.x (typage, dépréciations, appels internes cassants) ; l’approche “préparer PrestaShop avec PHPStan et PHPUnit” est détaillée ici : Préparer PrestaShop avec PHPStan et PHPUnit.

Complément très concret côté process : générez un artefact (build) identique entre staging, préprod et prod (mêmes vendor/, même composer.lock, même thème compilé). Sans ça, vous pouvez “réussir” la migration sur staging et échouer sur prod simplement à cause d’un composer update involontaire ou d’un cache / front build différent.

Enfin, ne sous-estimez pas le thème. Entre un thème 1.7 custom et un front moderne (ex. Hummingbird), vous changez de conventions JS / CSS, de structure de templates, et parfois de dépendances (fin de jQuery, accessibilité). Si le FO est très custom, cadrer une stratégie “refonte partielle” est souvent plus rationnel qu’un portage ad hoc : Passer à Hummingbird sans jQuery.

Un test “rapide mais efficace” sur le thème après migration : vérifiez 10 pages types (home, catégorie, produit simple, produit à déclinaisons, panier, livraison, paiement, CMS, recherche, compte client) avec les mêmes données (mêmes produits, même client, mêmes règles panier). C’est là que ressortent les différences de rendu, de JS cassé, ou de surcharge FO oubliée.

Migration données et performance : DB, index, cache, jobs, intégrations

Une migration 1.7 ➜ 9 en production doit inclure un volet qualité de la donnée + performance, sinon vous livrez une boutique “upgradée” mais plus lente / instable. Avant la bascule, validez : encodage utf8mb4, collations cohérentes, absence de champs TEXT en collation exotique, et index pertinents sur les tables à haut débit (paniers, sessions, recherches, facettes). Pour objectiver, utilisez EXPLAIN, mesurez le ratio scans / index et documentez les gains ; une méthode claire est présentée ici : Index MySQL : mesurer avec EXPLAIN et optimiser les requêtes.

Une règle de prudence en prod : n’optimisez pas “à l’instinct” pendant la fenêtre de bascule. Toute modification DB (index, collation, nettoyage massif) doit être testée sur une volumétrie réaliste, car le coût peut exploser (verrous, IO, temps de rebuild). Si vous devez ajouter des index, planifiez-le avant la bascule, ou a minima validez le temps d’exécution sur une copie de prod.

Ensuite, traitez les “points chauds” applicatifs : hooks surchargés, modules qui font des requêtes N+1, surcharge de actionProductSave, etc. L’optimisation au doigt mouillé ne marche pas : il faut un profilage et des preuves (slow queries, traces, histogrammes). Deux lectures utiles selon votre angle :

Pensez aussi “batch et jobs” : import catalogue, synchro stock, flux marketplace, génération de thumbnails, cron de relance panier, nettoyage sessions. Une migration réussie fonctionnellement peut échouer en exploitation si, le lendemain, vos crons saturent le CPU ou la DB (effet classique après changement de versions PHP / Symfony : temps d’exécution et mémoire peuvent varier). Documentez au minimum :

  • la liste des crons (commande + fréquence),
  • leur durée observée en prod (avant migration),
  • une limite de concurrence (éviter 10 crons simultanés),
  • un plan de reprise si un cron “prend du retard” (ex. rattrapage nocturne).

Enfin, validez vos caches et vos files de traitement. En production, une migration est souvent l’occasion de corriger une architecture bancale : OPcache sous-dimensionné, PHP-FPM mal calibré, Redis absent, cache natif mal utilisé, recherche saturée. Si vous migrez sans remettre à plat cache + DB, vous vous exposez à des 503 et à une latence BO / FO qui explose sous trafic. Sur les patterns Redis / OPcache / PHP-FPM, voir : Lenteur back-office : OPcache, PHP-FPM et Redis et la stratégie cache 2026 : Cache PrestaShop : stratégie 2026.

Un indicateur simple à suivre avant / après (utile pour objectiver auprès du métier) :

  • temps de réponse médian FO sur page produit / catégorie,
  • durée d’un checkout complet,
  • latence BO sur page commande,
  • nombre de requêtes SQL par page (sur un parcours type).

Bascule production : fenêtre de maintenance, rollback, SEO et observabilité

La bascule en production doit être pensée comme une opération réversible. La technique la plus fiable reste le blue / green (ou à défaut “clone + bascule DNS / LB”), avec une fenêtre de gel des écritures (commandes, comptes, stocks). Vous pouvez réduire la coupure à quelques minutes si vous isolez le delta : exporter / ré-importer uniquement les commandes et clients créés entre T0 (clone) et T1 (bascule). Sur des volumes modestes, une fenêtre de maintenance planifiée suffit ; sur des volumes élevés, vous devez script-er le rattrapage (et accepter la complexité).

Avant d’ouvrir la boutique, une checklist “go / no‑go” très opérationnelle (et rapide) limite les mauvaises surprises :

  • page d’accueil + 3 pages produit (dont 1 à déclinaisons) OK,
  • ajout panier / codes promo OK,
  • choix transporteurs OK,
  • paiement OK (et retour commande confirmé),
  • génération email de confirmation (ou au moins en file d’attente),
  • BO accessible + création commande manuelle OK,
  • cron critique (stocks, ERP, export) déclenchable.

La dimension SEO ne se résume pas à “ne pas changer les URLs”. Les migrations cassent surtout via : réécritures désactivées, canonical incorrects, pagination / facettes mal gérées, sitemaps incomplets, redirections 301 manquantes, et duplication multiboutique. Si vous touchez au thème ou à la génération des URLs, outillez tout de suite (map 301, audit, monitoring des 404). L’article « Modules SEO PrestaShop : sitemaps, redirections, images et performance » est pertinent ici : Modules SEO PrestaShop : sitemaps, redirections, images et performance. Pour les cas multiboutique (où une migration peut réactiver du contenu dupliqué), voir : PrestaShop multiboutique : paramétrage SEO.

« Use a permanent server-side redirect (301) if you have to change URLs. » — Google Search Central, Site moves with URL changes

Même si l’objectif est de conserver les URLs, cette recommandation doit guider votre plan de secours : si une structure change (ou si vous découvrez des différences de réécriture en 9), vous devez avoir une capacité de redirection propre et testée.

Dernier point : la migration se gagne (ou se perd) dans l’observabilité post-bascule. Fixez des SLO simples : taux d’erreurs 5xx, TTFB, temps de checkout, taux d’échec paiement, latence DB, saturation PHP-FPM. Corrélez avec logs applicatifs et slow queries ; les erreurs 503 et 500 doivent être traitées comme des incidents avec runbook, pas comme “des bugs à voir plus tard”. Pour un cadre KPI + prévention 503 : Monitoring PrestaShop : KPI et prévention des erreurs 503 et pour diagnostiquer vite : Erreur HTTP 503 : diagnostiquer PHP et logs.

Un retour d’expérience fréquent en e‑commerce (notamment sur des pics type soldes / Black Friday en Europe) : la migration “passe” techniquement, mais le premier pic révèle un goulot invisible en tests (OPcache trop petit, pool PHP‑FPM saturé, DB qui swap, ou module qui exécute une requête coûteuse sur chaque page). D’où l’intérêt d’avoir, dès J0, des tableaux de bord lisibles et des seuils d’alerte basiques (erreurs 5xx, saturation CPU / IO, slow queries, queue emails).

Au final, une migration PrestaShop 1.7 vers PrestaShop 9 “propre” en production ressemble à un projet DevOps : staging reproductible, contrôles CI, bascule réversible, et monitoring serré. Si un seul de ces piliers manque, vous ne faites pas une migration ; vous faites un pari.


À lire aussi