pgvector docker compose : piles de conteneurs dans un port sous un ciel bleu

Docker – pgvector – Lancer PostgreSQL avec pgvector dans Docker Compose

L’image Docker officielle postgres ne contient pas pgvector. Pour avoir PostgreSQL avec pgvector en local, il faut prendre l’image pgvector/pgvector : c’est la même image postgres, avec l’extension déjà installée. Voici un fichier pgvector docker compose minimal, testé avec PostgreSQL 18.

Le fichier pgvector docker compose

services:
  db:
    image: pgvector/pgvector:pg18
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: app
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql
      - ./initdb:/docker-entrypoint-initdb.d:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  pgdata:

L’image a pgvector, mais l’extension n’est pas encore activée dans la base. Un petit script dans le dossier initdb s’en occupe au premier démarrage :

-- initdb/01-vector.sql
CREATE EXTENSION IF NOT EXISTS vector;

On lance, puis on vérifie que l’extension est bien là :

docker compose up -d --wait
docker compose exec db psql -U app -d app -c "SELECT extversion FROM pg_extension WHERE extname = 'vector';"

Avec --wait, la commande attend que le healthcheck soit au vert. Le tag pg18 donne PostgreSQL 18 avec la dernière version de pgvector. Pour fixer aussi la version de pgvector, on peut prendre un tag comme 0.8.7-pg18.

PostgreSQL 18 : le volume se monte sur /var/lib/postgresql

Beaucoup d’exemples de pgvector docker compose montent encore le volume sur /var/lib/postgresql/data. Avec l’image pg18, le conteneur s’arrête tout de suite, et les logs disent :

The suggested container configuration for 18+ is to place a single mount
at /var/lib/postgresql which will then place PostgreSQL data in a
subdirectory

Depuis PostgreSQL 18, les données sont rangées dans /var/lib/postgresql/18/docker. On monte donc le volume sur /var/lib/postgresql, comme dans le fichier ci-dessus. Avec pg17 ou plus ancien, l’ancien chemin /var/lib/postgresql/data reste le bon.

Passer un volume existant de pg17 à pg18 ne migre pas les données. Il faut faire un dump avec l’ancienne version, puis le restaurer dans la nouvelle.

Les erreurs extension "vector" is not available et type "vector" does not exist

ERROR: extension "vector" is not available veut dire que l’image ne contient pas pgvector. C’est le cas avec l’image postgres de base. Il faut changer l’image pour pgvector/pgvector.

ERROR: type "vector" does not exist veut dire que pgvector est installé, mais que l’extension n’est pas activée dans cette base. CREATE EXTENSION ne vaut que pour une seule base. Le script initdb ne la crée que dans la base POSTGRES_DB, pas dans les autres bases du serveur.

Si le script a été ajouté après le premier démarrage, il ne tourne pas. Les scripts de /docker-entrypoint-initdb.d ne sont lancés que si le volume est vide, et les logs affichent alors Skipping initialization. Deux solutions : lancer CREATE EXTENSION vector; à la main, ou repartir de zéro avec docker compose down -v. Attention, -v supprime le volume et donc toutes les données.

Une fois la base prête, l’étape suivante est souvent l’index. Voir comment garder l’index ivfflat de pgvector quand on donne un poids aux résultats.

Laisser un commentaire