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

Docker – pgvector – Run PostgreSQL with pgvector in Docker Compose

The official postgres Docker image does not include pgvector. To run PostgreSQL with pgvector locally, use the pgvector/pgvector image: it is the same postgres image, with the extension already installed. Here is a minimal pgvector docker compose file, tested with PostgreSQL 18.

The pgvector docker compose file

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:

The image has pgvector, but the extension is not turned on in the database yet. A small script in the initdb folder does it on the first start:

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

Start it, then check that the extension is there:

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

With --wait, the command waits until the healthcheck is green. The pg18 tag gives PostgreSQL 18 with the latest pgvector. To pin the pgvector version too, use a tag like 0.8.7-pg18.

PostgreSQL 18: mount the volume on /var/lib/postgresql

Many pgvector docker compose examples still mount the volume on /var/lib/postgresql/data. With the pg18 image, the container stops right away, and the logs say:

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

Since PostgreSQL 18, the data lives in /var/lib/postgresql/18/docker. So the volume goes on /var/lib/postgresql, as in the file above. With pg17 or older, the old /var/lib/postgresql/data path is still the right one.

Switching an existing volume from pg17 to pg18 does not move the data over. Make a dump with the old version, then restore it into the new one.

The errors extension "vector" is not available and type "vector" does not exist

ERROR: extension "vector" is not available means the image does not include pgvector. That is the case with the plain postgres image. Switch the image to pgvector/pgvector.

ERROR: type "vector" does not exist means pgvector is installed, but the extension is not turned on in this database. CREATE EXTENSION only applies to one database. The initdb script only creates it in the POSTGRES_DB database, not in the other databases on the server.

If the script was added after the first start, it does not run. Scripts in /docker-entrypoint-initdb.d only run when the volume is empty, and the logs then show Skipping initialization. Two fixes: run CREATE EXTENSION vector; by hand, or start from scratch with docker compose down -v. Careful, -v deletes the volume and all its data.

Once the database is ready, the next step is often the index. See how to keep the pgvector ivfflat index when you give results a weight.

Leave a comment