Image de couverture : PostgreSQL 18 : gérez vos extensions sans reconstruire vos images serveur
Bases de données

PostgreSQL 18 : gérez vos extensions sans reconstruire vos images serveur

3 août 2026
6 min de lecture
4 vues
Sébastien Muler

Et si mettre à jour pgvector ne nécessitait plus de toucher à votre image PostgreSQL ?

Dans les environnements Kubernetes et Docker modernes, chaque mise à jour d'une extension PostgreSQL implique souvent de reconstruire une image serveur entière, de la tester, de la pousser dans le registry, puis de redéployer. Pour une simple montée de version de pgvector ou PostGIS, le coût organisationnel est disproportionné. PostgreSQL 18 s'attaque directement à ce problème avec l'introduction du paramètre extension_control_path, une évolution discrète mais structurante pour les équipes qui gèrent des flottes de bases de données en production.

Ce que PostgreSQL 18 change concrètement

Avant PostgreSQL 18, le moteur disposait déjà de dynamic_library_path pour localiser les bibliothèques partagées (.so) en dehors du répertoire compilé $libdir. C'était utile, mais partiel : les fichiers de contrôle (.control) et les scripts SQL des extensions devaient obligatoirement résider dans $sharedir/extension/. Impossible de faire pointer CREATE EXTENSION ailleurs. Résultat : toute extension non installée dans les répertoires du serveur était tout simplement invisible.

PostgreSQL 18 comble ce manque avec extension_control_path, un nouveau paramètre GUC (Grand Unified Configuration) qui permet de spécifier un ou plusieurs répertoires alternatifs où le moteur cherchera les fichiers .control et les scripts SQL. Combiné à dynamic_library_path pour les binaires, on dispose désormais d'un mécanisme complet pour externaliser une extension hors de l'image serveur.

-- Exemple de configuration dans postgresql.conf
dynamic_library_path = '/mnt/extensions/pgvector/lib:$libdir'
extension_control_path = '/mnt/extensions/pgvector/share:$sharedir'

Cette configuration suffit pour que CREATE EXTENSION vector; trouve tous ses fichiers dans le répertoire monté, sans que l'image PostgreSQL elle-même ait été modifiée.

Le scénario Kubernetes : des extensions comme des volumes OCI

C'est ici que la combinaison devient vraiment intéressante d'un point de vue infrastructure. Kubernetes 1.31+ introduit le support des ImageVolumes : la possibilité de monter une image OCI directement comme volume dans un pod, sans couche de stockage intermédiaire. Docker offre l'équivalent avec --mount type=image.

Le workflow cible ressemble à ceci :

  1. On package pgvector 0.9 dans une image OCI minimaliste (FROM scratch, quelques dizaines de Mo)
  2. Cette image est montée en ImageVolume dans le pod PostgreSQL au démarrage
  3. extension_control_path et dynamic_library_path pointent vers le point de montage
  4. CREATE EXTENSION vector; fonctionne, sans rebuild de l'image serveur
# Extrait de PodSpec Kubernetes
volumes:
  - name: pgvector
    image:
      reference: registry.example.com/pgvector:0.9
      pullPolicy: IfNotPresent
containers:
  - name: postgres
    image: postgres:18
    volumeMounts:
      - name: pgvector
        mountPath: /mnt/extensions/pgvector
    env:
      - name: POSTGRES_INITDB_ARGS
        value: "-c extension_control_path='/mnt/extensions/pgvector/share:$sharedir'"

Pour une flotte de clusters partageant la même image PostgreSQL de base, la promesse est réelle : on peut faire évoluer pgvector de 0.8 à 0.9 en changeant la référence d'image du volume, sans pipeline de rebuild côté serveur.

Là où la décorrélation atteint ses limites

L'article source (publié par Muhammad Aqeel sur le blog de pgEdge) formule une nuance importante que l'enthousiasme autour de cette fonctionnalité tend à masquer : tous les types d'extensions ne bénéficient pas également de cette architecture.

Certaines extensions s'intègrent profondément dans le cycle de vie du serveur PostgreSQL :

  • Les extensions shared_preload_libraries (comme pg_stat_statements, auto_explain, ou les extensions de réplication logique avancées) doivent être chargées au démarrage du processus principal. Même si leurs fichiers sont accessibles via extension_control_path, elles exigent toujours une modification de postgresql.conf et un redémarrage complet du serveur.
  • Les extensions qui modifient le WAL ou le stockage (comme pg_prewarm, certains plugins de compression) sont liées à des comportements internes du moteur qui ne se découplent pas via un simple montage de volume.
  • Les extensions avec des hooks C peuvent dépendre de symboles spécifiques à une version mineure du serveur, rendant la compatibilité croisée délicate.

En pratique, les extensions qui profitent pleinement du mécanisme sont celles qui s'exécutent entièrement dans le contexte d'une session utilisateur, sans accroches dans le processus postmaster : pgvector, PostGIS (pour la partie SQL), pg_trgm, uuid-ossp. Pour ces cas d'usage — souvent les plus fréquents dans un contexte applicatif PHP/Symfony — le gain est réel et immédiat.

Ce que ça change pour vos pipelines CI/CD

Concrètement, si votre stack repose sur Symfony avec Doctrine et PostgreSQL en production Kubernetes, extension_control_path ouvre des simplifications notables :

  • Séparation des cycles de release : l'image PostgreSQL de base peut rester stable sur plusieurs mois pendant que les extensions évoluent indépendamment.
  • Réduction de la surface de test : un rebuild d'extension ne nécessite plus de re-valider l'ensemble de la configuration serveur.
  • Rollback granulaire : revenir à une version précédente de pgvector revient à pointer vers l'ancienne image OCI, sans toucher au serveur.
  • Mutualisation des images : plusieurs environnements (staging, production multi-tenant) peuvent partager une image de base strictement identique, les variations étant portées par les volumes d'extensions.

La dette technique liée aux images PostgreSQL custom — souvent gonflées d'extensions compilées à des moments différents, avec des dépendances enchevêtrées — peut être significativement réduite.

Conclusion : une évolution structurante, à adopter avec discernement

extension_control_path n'est pas une révolution dans le moteur PostgreSQL, mais c'est une pièce manquante qui rend l'architecture "extensions-as-containers" enfin viable en production. Pour les extensions orientées session (pgvector étant le cas d'école), le découplage est propre et le gain opérationnel tangible.

La prudence s'impose néanmoins pour les extensions profondément ancrées dans le cycle de démarrage du serveur : le container boundary ne découple pas ce qui est fondamentalement couplé au niveau du moteur. Identifier dans votre inventaire d'extensions lesquelles entrent dans quelle catégorie est le premier travail à faire avant d'architechter une solution basée sur des ImageVolumes.

PostgreSQL 18 n'est pas encore en disponibilité générale au moment de cet article, mais cette fonctionnalité mérite d'être intégrée dès maintenant dans les réflexions d'architecture infra pour les équipes qui maintiennent des flottes de bases de données. La source originale de Muhammad Aqeel sur le blog pgEdge fournit une analyse complémentaire des différentes catégories d'extensions et de leur compatibilité avec ce nouveau mécanisme.

Partager cet article