[UPDATE 2026] Akeneo PIM 6 vers 7 en Docker — migration, upgrade et centralisation serveur avec MyVestaCP

Published by David on






Akeneo PIM 6 vers 7 en Docker — migration et upgrade vers Docker Compose avec reverse proxy MyVestaCP

Akeneo PIM 6 → 7 en Docker — migration et upgrade

Sixième étape : migrer Akeneo PIM 6 (Community Edition) d’un VPS standalone
vers PIM 7 en Docker Compose sur le serveur centralisé, avec reverse proxy MyVestaCP.

Paramètres à adapter

Ce document utilise des variables entre {{...}}. Remplacez-les par vos propres valeurs avant d’exécuter les commandes.

Variable Description Exemple
{{HOSTNAME_VPS_PIM}} Hostname du VPS PIM (ancien) vps-pim-ancien
{{IP_VPS_PIM}} IP du VPS PIM 203.0.113.50
{{USER_VPS_PIM}} Utilisateur SSH du VPS PIM ubuntu
{{HOSTNAME_NOUVEAU}} Hostname du nouveau serveur vps-nouveau
{{IP_NOUVEAU}} IP du nouveau serveur 198.51.100.20
{{PORT_SSH_NOUVEAU}} Port SSH du nouveau serveur 22
{{DOMAINE_PIM}} Domaine Akeneo PIM pim.exemple.com
{{MYSQL_ROOT_PASSWORD}} Mot de passe root MySQL MonMotDePasseRoot!
{{APP_SECRET}} Secret Symfony (APP_SECRET) GenerateWithOpenSSLRand
{{USER_VESTA}} Utilisateur VestaCP admin

Les identifiants MySQL akeneo_pim (user/db/password) sont les valeurs par défaut Akeneo. Changez le mot de passe en production.

Introduction

Akeneo PIM 6 (Community Edition, v6.0.45) tourne actuellement sur un VPS séparé
({{HOSTNAME_VPS_PIM}}, IP {{IP_VPS_PIM}}, SSH port 22, utilisateur SSH {{USER_VPS_PIM}}).
L’installation est en standalone : PHP 8.0, MySQL 8.0.30, Elasticsearch 7.x, le tout installé
directement sur le système dans /home/pim-community-standard/.

On migre vers le serveur centralisé ({{HOSTNAME_NOUVEAU}}, IP {{IP_NOUVEAU}},
SSH port {{PORT_SSH_NOUVEAU}}) en Docker Compose, avec un upgrade de PIM 6.0 vers PIM 7.0
en même temps.

Architecture cible

  • 6 conteneurs Docker : MySQL 8.0.30, Elasticsearch 8.4.2, PHP 8.1 FPM, Nginx, Job Worker, Cron
  • Domaine : {{DOMAINE_PIM}} (port interne 8480)
  • MyVestaCP gère le reverse proxy et les certificats SSL
  • Fichiers Docker : /home/docker/akeneo/

Ce qui change entre PIM 6 et PIM 7 :
PHP 8.0 → 8.1, Elasticsearch 7.x → 8.4.2,
le SKU n’est plus obligatoire (UUID devient l’identifiant technique),
les nouveaux endpoints API utilisent /products-uuid,
et la configuration du mailer passe en format DSN (MAILER_URLMAILER_DSN).

Ressources nécessaires : Elasticsearch 8 consomme ~2-4 Go de RAM,
MySQL ~1-2 Go, PHP-FPM ~1 Go. Assurez-vous que la RAM disponible sur votre serveur est suffisant pour votre usage,
même en coexistence avec d’autres services.

1) Créer le domaine dans MyVestaCP

Dans le panel MyVestaCP → WEBAdd Web Domain :

  • {{DOMAINE_PIM}}

Paramètres :

  • DNS Support : cocher (obligatoire pour Let’s Encrypt)
  • Mail Support : décocher
  • Advanced options : laisser les valeurs par défaut

DNS Support obligatoire : même si le DNS est géré ailleurs (OVH, Cloudflare, etc.),
il faut cocher DNS Support dans MyVestaCP. Le script v-add-letsencrypt-domain
a besoin de la zone DNS locale pour créer l’enregistrement _acme-challenge.
Sans cette zone, la demande de certificat échoue avec une erreur 404.

Important : ne pas activer Let’s Encrypt pour l’instant — le DNS ne pointe pas encore vers le nouveau serveur.

2) Créer les templates Nginx pour reverse proxy PIM

Même principe que pour Odoo : on crée des templates Nginx personnalisés pour que VestaCP
fasse du reverse proxy vers le conteneur Docker (port 8480).

2.1 Template HTTP : akeneo-8480.tpl

Contenu :

Le client_max_body_size 128M est important pour PIM : l’import de fichiers CSV
et l’upload d’images produits peuvent être volumineux.

2.2 Template HTTPS : akeneo-8480.stpl

Contenu :

2.3 Appliquer le template au domaine

2.4 Vérifier et recharger Nginx

3) Créer la structure des répertoires Docker

  • pim/ : code source Akeneo PIM 7 (installé via Composer)
  • config/nginx/ : configuration Nginx pour le conteneur interne
  • config/crontab : tâches planifiées PIM (créé en section 4.3)
  • backup/ : exports temporaires (dump MySQL, tar filestore)

4) Créer les fichiers de configuration Docker

4.1 Créer le docker-compose.yml

Contenu :

Points clés :

  • mysql:8.0.30 avec mysql_native_password (Akeneo ne supporte pas le nouveau plugin d’authentification MySQL 8) et log_bin_trust_function_creators=1 (nécessaire pour les migrations qui créent des triggers)
  • elastic/elasticsearch:8.4.2 en mode single-node, sécurité désactivée (réseau Docker interne)
  • akeneo/pim-php-dev:8.1 pour PHP-FPM avec toutes les extensions requises. Le user: "0:0" fait tourner le conteneur en root pour éviter les erreurs de permission sur les logs PHP-FPM et le cache Symfony
  • nginx:1.25-alpine comme serveur web interne, exposé sur le port 8480
  • job-worker : démon qui traite les imports/exports et tâches asynchrones via 4 queues PIM 7 (ui_job, import_export_job, data_maintenance_job, scheduled_job). Le --time-limit=300 le redémarre toutes les 5 minutes (libère la mémoire)
  • cron : conteneur léger (docker:27-cli, ~15 Mo) qui exécute les tâches planifiées PIM via docker exec dans le conteneur PHP. Tout est dans le compose, pas de crontab à configurer sur l’hôte
  • Réseau et volumes complètement séparés d’Odoo

Image akeneo/pim-php-dev:8.1 : c’est l’image officielle Akeneo pour le développement.
Elle inclut toutes les extensions PHP requises (apcu, bcmath, imagick, intl, etc.). Pour la production,
Akeneo ne fournit pas d’image officielle. On désactive Xdebug via XDEBUG_MODE=off.

user: "0:0" sur le service php : sans cela, le conteneur tourne en www-data
et PHP-FPM ne peut pas écrire son fichier de log (Permission denied: /var/log/php8.1-fpm.log),
ce qui provoque un crash en boucle de supervisord. Le job-worker garde user: www-data
car il n’a pas besoin d’accès root (il exécute uniquement des commandes Symfony).

Queues PIM 7 : PIM 6 utilisait une seule queue (main_queue).
PIM 7 la remplace par 4 queues spécialisées : ui_job, import_export_job,
data_maintenance_job, scheduled_job. Si vous gardez main_queue,
le job-worker crashe avec No such transport "main_queue".

Conteneur cron et Docker socket : le service cron monte le
docker.sock en lecture seule pour pouvoir exécuter docker exec
dans le conteneur PHP. C’est le même mécanisme que la crontab hôte, mais conteneurisé.
Les commandes PIM tournent dans le contexte du conteneur akeneo-php
(mêmes volumes, même réseau, mêmes variables d’environnement).
Avantage : un docker compose down && up -d restaure tout automatiquement,
pas de crontab à reconfigurer manuellement.

4.2 Créer la configuration Nginx interne

Contenu :

Ce Nginx interne (dans Docker) proxie les requêtes PHP vers le conteneur php (FPM port 9000).
Le Nginx de MyVestaCP (sur l’hôte) proxie vers ce Nginx interne sur le port 8480.
C’est une architecture classique « double reverse proxy ».

4.3 Créer le fichier crontab

Contenu :

Ligne vide obligatoire à la fin : BusyBox crond (utilisé par Alpine)
exige une ligne vide à la fin du fichier crontab. Sans elle, la dernière entrée est ignorée
silencieusement.

15 crons officiels CE : ces crons sont regroupés en 4 catégories :
Data Quality Insights (4 crons — calcul des scores qualité),
Versioning (2 crons — historique des modifications),
Maintenance (4 crons — purge, volumes, jobs planifiés, messages),
Connectivity (5 crons — audit, purge erreurs, logs API, clés OpenID).
Source : documentation officielle PIM 7.0 CE.

Modifier les crons : pour ajouter ou supprimer un cron, éditer le fichier
/home/docker/akeneo/config/crontab puis redémarrer le conteneur :
docker compose restart cron.

5) Installer le code PIM 7 via Composer

On utilise l’image Docker PHP pour télécharger et installer PIM 7 sans rien installer sur l’hôte.

Point de montage : ne pas monter directement /home/docker/akeneo/pim
comme volume — Composer a besoin de créer le répertoire cible lui-même.
On monte donc le répertoire parent et on laisse create-project
créer le sous-répertoire pim. La commande tourne en root
(pas -u www-data) pour éviter les erreurs de permission.

5.0.1 Corriger les permissions après installation

5.0.2 Créer le fichier docker/supervisord.conf

L’image akeneo/pim-php-dev:8.1 utilise supervisord comme processus principal,
mais pim-community-standard installé via Composer n’inclut pas le fichier de configuration.
Sans ce fichier, le conteneur PHP crashe en boucle avec Error: could not find config file docker/supervisord.conf.

user=root et -F sont obligatoires :
sans user=root, supervisord affiche un warning CRIT running as root, privileges were not dropped.
Sans -F (foreground), PHP-FPM se détache en arrière-plan (daemonize) : le processus parent
quitte avec status 0, supervisord croit qu’il a crashé et tente de le relancer, mais le port 9000
est toujours occupé par le processus enfant orphelin — résultat : crash en boucle avec
Address already in use (98).

Première exécution longue : Composer télécharge toutes les dépendances (~500 Mo).
Cette commande peut prendre 5-10 minutes selon la connexion.
Si elle échoue sur un timeout, relancer avec COMPOSER_PROCESS_TIMEOUT=600.

5.1 Créer le fichier .env.local

Ce fichier contient la configuration spécifique à notre environnement Docker.
Il surcharge les valeurs par défaut de .env.

Contenu :

Différences avec PIM 6 :
APP_DATABASE_HOST pointe vers mysql (nom du service Docker, pas localhost).
APP_INDEX_HOSTS pointe vers elasticsearch:9200.
AKENEO_PIM_URL utilise https:// (après activation Let’s Encrypt).

5.2 Permissions

6) Préparer la base PIM 6 avant l’export

Avant d’exporter la base, il faut s’assurer que toutes les migrations PIM 6
ont été appliquées. On fait cela sur le VPS PIM 6.

Permissions : le rm -rf var/cache/* doit être fait en root,
mais les commandes cache:clear et cache:warmup doivent être lancées
en tant que www-data (via sudo -u www-data), sinon le cache sera recréé
avec des permissions root et PIM 6 retournera une erreur 500 Internal Server Error au prochain redémarrage.
Si cela arrive, corriger avec : chown -R www-data:www-data /home/pim-community-standard/var/

Si doctrine:migrations:migrate affiche No migrations to execute,
c’est normal — cela signifie que la base PIM 6 est déjà à jour.

7) Exporter les données depuis le VPS PIM 6

Sur le VPS PIM ({{IP_VPS_PIM}}), on exporte la base MySQL et le filestore.

7.1 Arrêter les workers PIM 6

7.2 Exporter la base MySQL

La base se nomme akeneo_pim, utilisateur akeneo_pim,
mot de passe akeneo_pim (tel que configuré dans le .env de PIM 6).

7.3 Exporter le filestore

7.4 Exporter le cache média (optionnel)

8) Transférer les exports via rsync

Depuis le nouveau serveur ({{IP_NOUVEAU}}), récupérer les archives :

Le VPS PIM utilise le port SSH par défaut (22), donc pas besoin de -p.
Si une clé SSH n’est pas configurée, utiliser scp à la place.

9) Démarrer les services et restaurer la base

9.1 Démarrer MySQL et Elasticsearch

Ne pas démarrer tous les services : à cette étape, ne lancer que
mysql et elasticsearch. Le conteneur PHP sera démarré après
la restauration de la base et la correction des permissions (sections 9.2 et 10).

Attendre que MySQL soit prêt :

Quand tu vois mysqld is alive, c’est prêt.

Vérifier Elasticsearch :

Le status doit être green ou yellow.

9.2 Supprimer la base vide et restaurer le dump PIM 6

Attention : la restauration peut prendre plusieurs minutes selon la taille de la base.
Ne pas interrompre le processus.

9.3 Restaurer le filestore

10) Exécuter la migration PIM 6.0 → 7.0

Maintenant que la base PIM 6 est restaurée dans le conteneur MySQL et que le code PIM 7
est installé, on peut exécuter les migrations Doctrine pour upgrader le schéma.

10.0.1 Corriger les permissions du cache

Le code PIM a été installé en root (section 5), donc le répertoire var/
appartient à root. Il faut corriger les permissions depuis l’intérieur du conteneur
pour que www-data puisse créer le cache.

Important : la commande chown doit être faite depuis l’intérieur
du conteneur
(via docker compose exec), pas depuis l’hôte. Le chown
depuis l’hôte avec chown -R 33:33 peut ne pas fonctionner correctement selon le type
de volume Docker utilisé.

10.1 Démarrer le conteneur PHP

10.2 Vider le cache

10.3 Créer les index Elasticsearch (obligatoire avant les migrations)

Les migrations Doctrine incluent une étape de conversion UUID qui a besoin des index Elasticsearch.
Si les index n’existent pas, la migration échouera avec index_not_found_exception
sur akeneo_pim_product_and_product_model.

10.4 Exécuter les migrations Doctrine

Migration très longue (1 à 3 heures) : cette commande applique toutes les migrations de schéma
entre PIM 5.0 et PIM 7.0 (les versions 5.0 → 6.0 sont incluses dans le code PIM 7).
Les étapes les plus longues sont :

  • ALTER TABLE pim_versioning_version — cette table stocke l’historique complet
    de chaque modification de chaque entité PIM. C’est la plus grosse table de la base (souvent > 1 Go).
    L’ALTER TABLE crée une copie temporaire, ce qui peut prendre 1 à 2 heures.
  • Conversion UUID (Version_7_0_20220429131804_execute_uuid_migration) —
    crée des triggers temporaires sur plusieurs tables pour migrer les identifiants vers des UUID.
  • INSERT INTO pim_data_quality_insights_*
    peuple les tables de scoring qualité, plusieurs milliers de lignes par table.

Monitoring : pour vérifier que la migration progresse, ouvrir un second terminal et observer le processlist MySQL :
docker compose exec mysql mysql -u akeneo_pim -pakeneo_pim akeneo_pim -e "SHOW FULL PROCESSLIST;".
Un Time qui augmente sur un ALTER TABLE est normal.
Des warnings did not result in any SQL statements sont bénins.

10.5 Migrations de données complémentaires

11) Réindexer Elasticsearch et compiler les assets

11.1 Réindexer Elasticsearch

La réindexation peut prendre du temps si tu as beaucoup de produits.
C’est normal — Elasticsearch reconstruit tout l’index depuis MySQL.

11.2 Préparer les fichiers requis par webpack

Webpack a besoin de fichiers générés par Symfony (routes JS, require-paths, bundles publics).
Ces commandes doivent être exécutées depuis le conteneur PHP avant de lancer Node.

assets:install sans --symlink : utiliser la copie (pas les liens symboliques).
Avec --symlink, webpack suit les symlinks vers vendor/ et ne trouve plus
les modules @akeneo-pim-community/* dans node_modules/.
La commande assets:install doit tourner en root pour pouvoir créer
les répertoires dans public/bundles/.

11.3 Compiler les assets frontend

La compilation se fait avec un conteneur node:18 éphémère.
L’ordre des commandes est important : packages:build (compile les front-packages
TypeScript en JavaScript), puis less, puis webpack.

packages:build obligatoire : sans cette étape, webpack échoue avec 333 erreurs
Module not found: Can't resolve '@akeneo-pim-community/shared'.
Les front-packages sont en TypeScript source (src/) et leur package.json
déclare "main": "./lib/index.js". Le répertoire lib/ n’existe qu’après
la compilation par packages:build (qui lance tsc sur chaque workspace).

Compilation longue : le build complet (install + packages + less + webpack)
prend environ 5-10 minutes et consomme beaucoup de RAM.
C’est une opération unique (pas besoin de le refaire à chaque redémarrage).
Les commandes tournent en -u root pour éviter les erreurs de permission
sur node_modules/.

11.4 Générer extensions.json

Le frontend PIM charge /js/extensions.json au démarrage pour connaître la liste
des extensions de formulaires (menus, onglets, champs, etc.). Sans ce fichier, le dashboard
reste bloqué sur « Loading… » à l’infini après la connexion.

Ce fichier est généré par un script Node (pas par une commande Symfony) qui lit
require-paths.js (généré en 11.2), scanne les fichiers form_extensions.yml
de chaque bundle, et les fusionne en un seul JSON.

Fichier critique : aucune commande bin/console ne génère ce fichier.
Il n’est référencé dans aucune documentation officielle Akeneo pour les installations self-hosted.
Si /js/extensions.json retourne 404, le PIM se connecte mais affiche un écran
« Loading… » infini avec l’animation du dinosaure.

11.5 Corriger les permissions après compilation

11.6 Vider le cache Symfony

12) Démarrer tous les services

Vérifier l’état de tous les conteneurs :

Les 6 conteneurs doivent être en état Up :

  • akeneo-mysql
  • akeneo-es
  • akeneo-php
  • akeneo-nginx
  • akeneo-job
  • akeneo-cron

Consulter les logs en cas d’erreur :

13) Tester localement (avant le DNS)

La commande doit retourner HTTP/1.1 302 Found avec un header Location
pointant vers /user/login. Cela confirme que PIM 7 fonctionne.

Identifiants par défaut PIM : admin / admin.
Si tu as changé le mot de passe dans PIM 6, les anciens identifiants sont conservés après la migration.

14) Basculer les enregistrements DNS

Créer (ou modifier) l’enregistrement A chez le registrar :

Sous-domaine Type Cible
{{DOMAINE_PIM}} A {{IP_NOUVEAU}}

Vérifier la propagation :

15) Activer Let’s Encrypt

Important : attendre que le DNS pointe vers {{IP_NOUVEAU}} avant de lancer
cette commande. Let’s Encrypt valide via HTTP.

16) Vérifier les crons PIM

Les crons PIM sont déjà configurés dans le docker-compose.yml (section 4.1)
via le conteneur akeneo-cron et le fichier config/crontab (section 4.3).
Ils démarrent automatiquement avec docker compose up -d.

Vérifier que le conteneur cron tourne :

Pour vérifier qu’un cron s’est bien exécuté, consulter les logs du conteneur PHP
(les commandes docker exec y redirigent leur sortie) :

Avantage par rapport au crontab hôte : tout est dans le compose.
Un docker compose down && up -d restaure les crons automatiquement.
Si tu migres le serveur à nouveau, pas de crontab à reconfigurer manuellement.

Récapitulatif de l’architecture finale

Coexistence sur le serveur : Akeneo PIM, Odoo 8 et Odoo 17 tournent sur le même
serveur, complètement isolés dans leurs réseaux Docker respectifs :

  • akeneo-network : MySQL 8.0.30 + ES 8.4.2 + PHP + Nginx + Job Worker + Cron (port 8480)
  • odoo17-network : PostgreSQL 13 + Odoo 17 (ports 8069/8169/8269/8369)
  • odoo8-network : PostgreSQL 9.6 + Odoo 8 (ports 8469/8472)

En cas de problème

Erreur 502 Bad Gateway

Le conteneur PHP-FPM n’est pas prêt ou a crashé :

Erreur « Connection refused » sur Elasticsearch

Elasticsearch n’a pas démarré (souvent un problème de mémoire ou de vm.max_map_count) :

Erreur de permission sur le filestore

Écran « Loading… » infini après la connexion

Le fichier extensions.json est manquant. Vérifier :

Si le résultat est 404, regénérer le fichier (section 11.4) :

PHP-FPM crash en boucle avec « Address already in use (98) »

Vérifier que supervisord.conf contient bien command=/usr/local/sbin/php-fpm -F
(avec le flag -F pour le mode foreground). Sans ce flag, PHP-FPM se détache et
supervisord tente de le relancer en boucle (voir section 5.0.2).

Job-worker crash avec « No such transport « main_queue » »

PIM 7 a remplacé main_queue par 4 queues séparées.
Vérifier le command du service job-worker dans docker-compose.yml
(voir section 4.1).


À suivre

Akeneo PIM 7 est maintenant opérationnel en Docker avec reverse proxy et SSL.
Dans les prochains articles :

  • ownCloud — migration des données et Docker Compose
  • Serveurs de jeux — CS 1.6, TeamSpeak 3, EmuLinker
  • Sauvegardes — stratégie et automatisation

Article précédent : Odoo 8 en Docker — migration standalone vers Docker Compose.



Catégories : Non classé

0 commentaire

Laisser un commentaire

Emplacement de l’avatar

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *