Les migrations de base de données en double sont plus faciles à éviter lorsque les modifications de schéma s’exécutent comme une étape de déploiement explicite, plutôt qu’au démarrage de chaque conteneur d’application.
La conception préventive consiste à attribuer un seul responsable aux migrations, un seul jeu d’identifiants et un seul signal de fin avant que les nouvelles répliques ne commencent à traiter le trafic. Laissez les conteneurs web et worker redémarrer librement sans disposer des privilèges nécessaires pour modifier le schéma, faites attendre le déploiement jusqu’à la réussite d’un job de migration et concevez les modifications de schéma de manière à permettre la coexistence temporaire des anciennes et des nouvelles versions de l’application. Cela supprime la condition de concurrence au lieu de simplement espérer que chaque réplique détectera d’abord le même historique de migrations.
Supprimer les commandes de migration du démarrage normal de l’application
Inspectez le point d’entrée de l’image, la commande Compose, la commande du worker, le wrapper de vérification d’état et le script de déploiement pour repérer les appels automatiques aux migrations. L’application doit pouvoir redémarrer sans modifier le schéma, sauf si ce redémarrage correspond à l’étape de migration choisie délibérément.
Un article d’Octopus consacré aux déploiements affirme que les migrations nécessitent un cycle de vie distinct, plutôt que d’être liées au démarrage de chaque processus de microservice.
Conservez le binaire de migration là où il est nécessaire, mais ne l’appelez pas à la fois depuis le point d’entrée web et depuis un second job. Un responsable explicite est plus facile à auditer que plusieurs chemins de démarrage qui dépendent tous du verrouillage du framework.
Exécuter un job de migration avant le déploiement
Créez un job exécuté une seule fois, qui utilise les mêmes fichiers de migration que la version déployée et ne se termine avec succès qu’une fois que la base de données cible a atteint l’état de schéma attendu. Faites dépendre le déploiement de l’application de ce résultat.
Un guide de déploiement récent montre comment un job s’exécute avant le déploiement, au lieu de laisser chaque réplique entrer en concurrence au démarrage.
Ne dimensionnez pas la tâche de migration comme le service applicatif. Le job doit avoir un seul responsable d’exécution par base de données cible, un délai d’expiration limité, des journaux et un état d’échec explicite qui bloque la nouvelle version de l’application.
Conditionner le démarrage de l’application à la réussite de la migration
Faites attendre les nouveaux conteneurs web et worker jusqu’à ce que l’étape de migration signale sa réussite, mais ne faites pas relancer la migration par chaque conteneur en attente. La dépendance porte sur le résultat, pas sur l’exécution répétée de la modification du schéma.
Le modèle de déploiement d’Andrew Lock utilise des pods d’application qui attendent la migration, tandis que la logique de migration reste centralisée.
Pour une petite infrastructure sur serveur personnel, le même principe peut être mis en œuvre avec un service Compose dédié et un script de déploiement contrôlé. Gardez le mécanisme suffisamment simple pour qu’une migration échouée arrête visiblement le déploiement.
Utiliser des modifications de schéma rétrocompatibles pendant la coexistence
Les déploiements progressifs peuvent temporairement exécuter d’anciennes et de nouvelles versions de l’application sur une même base de données. Évitez de supprimer ou de renommer un champ avant que l’ancienne version ait cessé de l’utiliser.
Un guide récent sur les migrations sans interruption recommande d’étendre avant de contracter, afin que les modifications additives du schéma soient déployées avant le nettoyage destructif.
Divisez les modifications importantes en phases d’extension, de remplissage des données, de basculement et de contraction lorsque cela est nécessaire. Le job de migration ne doit pas créer un schéma que seul le nouveau conteneur comprend alors que les anciennes répliques traitent encore des requêtes.
Ne pas exposer les identifiants de migration aux répliques de l’application
Lorsque cela est possible, utilisez un compte de base de données disposant des privilèges de modification du schéma uniquement pour l’étape de migration exécutée une seule fois. Les conteneurs applicatifs normaux doivent conserver les autorisations de lecture et d’écriture plus limitées nécessaires aux données de l’application.
Un article de Liquibase sur les déploiements décrit comment les modifications de base de données doivent être intégrées à l’automatisation, avec une application contrôlée et reproductible des changements.
Cette séparation réduit les risques d’exécution accidentelle d’une migration, même si un processus applicatif est redémarré ou dupliqué. Stockez l’identifiant à privilèges élevés dans le chemin des secrets de déploiement, plutôt que dans l’environnement du service standard de longue durée.
Vérifier que le déploiement ne peut pas appliquer le lot deux fois
Testez le déploiement sur une base de données jetable ou un instantané restauré en démarrant plusieurs répliques de l’application, en les redémarrant, puis en relançant la commande de déploiement. L’étape de migration doit signaler l’état de schéma existant sans le modifier une seconde fois.
JetBrains résume la règle opérationnelle ainsi : exécuter les migrations comme une étape de déploiement avant le démarrage normal de l’application.
La politique de prévention est complète lorsque les redémarrages de l’application ne peuvent pas modifier le schéma, qu’une migration échouée bloque la mise en production et que l’exécution répétée du déploiement laisse la base de données inchangée. L’article ZimaSpace associé sur le diagnostic d’une migration en double constitue la procédure de récupération si une exécution en double a déjà eu lieu.
Assistance et conseils
Plus à lire

Plex peut-il partager un GPU avec un autre conteneur Docker ?
Plex et un autre conteneur peuvent souvent accéder au même GPU, mais vous devez tester la prise en charge des pilotes, le mappage des...

Comment déterminer si une erreur Plex vient du client ou du serveur
Reproduisez le même élément sur un autre client, comparez le chemin de session, puis recueillez les preuves côté serveur uniquement après que la portée...

Comment configurer le cache de Plex et le stockage temporaire du transcodage
Protégez l’état persistant de Plex en plaçant les fichiers temporaires de transcodage sur un stockage local adapté, puis vérifiez le nettoyage, l’espace libre et...

