Database installation

The Database component provides the PostgreSQL instance that all other components read from and write to. It must be installed and verified before any other component.

Responsible team: Simavi.

Which instance to install

The procedure on this page installs the bundled database used by standalone deployments. It runs on port 5444 and is restored automatically from a supplied dump at first start.

In a central deployment the shared database already exists on the data host and does not need to be installed. Confirm that it is reachable, as described in Prerequisites, and continue to ETL installation.

Before you begin

Confirm the following are in place.

  • Docker Engine and Compose, verified as described in Prerequisites
  • The installation directory containing docker-compose.yml and the init directory
  • The database dump file, placed inside the init directory
  • Port 5444 free, or an alternative port chosen and recorded

The init directory must contain both the restore script and the dump file:

DatabaseImageBuild/
├── docker-compose.yml
└── init/
    ├── 00-configure-and-restore.sh
    └── cvdlink_<date>.dmp

1. Confirm the port is available

On Linux:

sudo lsof -i:5444

On Windows:

netstat -ano | findstr :5444

No output means the port is free. If a process is listening, either stop it or choose a different port.

To change the port, edit docker-compose.yml and replace every occurrence of 5444, including the value in the command entry. Record the port chosen: it must match the DB_PORT value used when configuring the ETL and Metadata components.

2. Obtain the PostgreSQL image

The image must provide the vector extension, which the metadata schema requires. Use the pgvector image rather than the standard PostgreSQL image:

docker pull pgvector/pgvector:pg17

Set the same image in docker-compose.yml:

services:
  postgres:
    image: pgvector/pgvector:pg17

For installations without registry access, load the image from a supplied archive instead:

docker load -i pgvector-pg17.tar

Why this image is required

CVDLink uses a large language model to answer questions about the data it holds. To do this, the documents and datasets available to the model are converted into numerical representations, called embeddings, which capture their meaning in a form that can be compared mathematically. When a user asks a question, the question is converted the same way, and the database finds the stored material whose embeddings are closest to it. That material is then supplied to the model as context for its answer.

This requires the database to store embeddings and to search them by similarity rather than by exact match, which standard PostgreSQL cannot do. The vector extension adds both: a column type for embeddings and an index that makes similarity search efficient over a large collection.

The metadata schema therefore creates the vector extension and defines columns and indexes that depend on it. The standard postgres:17 image does not include the extension, so restoring the dump into it fails when the schema reaches the CREATE EXTENSION statement. The pgvector/pgvector:pg17 image is the same PostgreSQL release with the extension already built in.

Compose files distributed with earlier versions of this component specify postgres:17. Change this to pgvector/pgvector:pg17 before the first start. Changing it later requires a fresh restore, because the restore runs only against an empty data directory.

Required extensions

The restore creates the following extensions. All are provided by the pgvector image.

Extension Purpose
vector Stores embeddings and searches them by similarity, supporting the language model features
pgcrypto Cryptographic functions used by the schema
uuid-ossp Identifier generation

The embedding width is fixed by the model that produces the embeddings, and the schema declares it explicitly. Changing the embedding model therefore requires the stored embeddings to be regenerated, as embeddings produced by different models cannot be compared with one another.

After the restore completes, confirm they are present as described in the verification section below.

3. Create the data directory

The database stores its files outside the container so that data survives container replacement.

On Linux:

sudo mkdir -p /var/pgdata

On Windows:

mkdir C:\var\pgdata

The path must match the volume mapping in docker-compose.yml. If a different location is used, update that mapping accordingly.

4. Create the Docker network

docker network create external-db-net

If the network already exists from a previous installation and its configuration is uncertain, remove and recreate it:

docker network rm external-db-net
docker network create external-db-net

Removing a network fails while containers are still attached to it. Stop those containers first.

5. Start the container

docker compose up -d

At first start, with an empty data directory, PostgreSQL runs the initialisation script in the init directory. The script enables remote access, locates the dump file, and restores it into the cvdlink database.

Restoring the supplied dump takes several minutes. Follow the progress:

docker logs -f pg5444

Wait until log output stops before continuing. The database is not ready for use while the restore is in progress.

6. Verify the installation

Each step below states the expected result. Complete all four before installing further components.

Confirm the container is running

docker ps

The output must include a container named pg5444 with a status beginning Up.

Confirm the logs are free of errors

docker logs pg5444 | grep -iE "error|fatal"

No output is expected. Messages during restore are normal; errors and fatal entries are not.

Confirm the database exists

docker exec -it pg5444 psql -U postgres -p 5444 -c "\l"

The list of databases must include cvdlink.

Confirm the schema was restored

docker exec -it pg5444 psql -U postgres -p 5444 -d cvdlink -c "SELECT table_schema, COUNT(*) AS table_count FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema NOT IN ('pg_catalog','information_schema') GROUP BY table_schema ORDER BY table_schema;"

The result must list the application schemas with a non-zero table count for each. An empty result means the restore did not complete; see Troubleshooting below.

Confirm the required extensions are installed

docker exec -it pg5444 psql -U postgres -p 5444 -d cvdlink -c "SELECT extname, extversion FROM pg_extension ORDER BY extname;"

The result must include vector, pgcrypto, and uuid-ossp. A missing vector extension means the image does not provide it; see Troubleshooting below.

Connecting to the database

From the host

psql -h localhost -p 5444 -U postgres -d cvdlink

From another machine

psql -h APPLICATION_HOST -p 5444 -U postgres -d cvdlink

From another container on the same network

Other components reach the database using the service name rather than an address. Use the following values when configuring them:

Setting Value
Host postgres
Port 5444
Database cvdlink
User postgres

Routine operations

Operation Command
Restart docker compose restart
Stop, keeping data docker compose down
Start again docker compose up -d
View logs docker logs -f pg5444

Stopping with docker compose down removes the container but leaves the data directory intact. The data is removed only by deleting that directory.

Troubleshooting

The restore did not run and the database is empty

PostgreSQL runs initialisation scripts only when the data directory is empty. If the directory already contained files, the restore was skipped and the logs state that initialisation was skipped.

To restore into a fresh database, stop the container, remove the contents of the data directory, and start again. This destroys any existing data in that directory.

docker compose down
sudo rm -rf /var/pgdata/*
docker compose up -d

The restore fails reporting that the extension "vector" is not available

The image in use does not provide the vector extension. Confirm which image the container was created from:

docker inspect pg5444 --format '{{.Config.Image}}'

Where this reports postgres:17, change the image in docker-compose.yml to pgvector/pgvector:pg17 and carry out a fresh restore. Because initialisation runs only against an empty data directory, the directory must be emptied first. This destroys any data it holds.

docker compose down
sudo rm -rf /var/pgdata/*
docker compose up -d

The dump file cannot be read

The init directory is mounted read-only, which is expected. If the logs report that the dump file cannot be found, confirm the file is present in the init directory and that its name ends in .dmp or .sql, which the restore script uses to detect it.

The dump reports an unsupported version in the file header

The dump was produced by a newer version of PostgreSQL than the image provides. Either use an image matching the version that produced the dump, or obtain a dump exported for PostgreSQL 17.

Remote connections are refused

Confirm the container is publishing the port:

docker port pg5444

If the port is published and connections are still refused, the host firewall is blocking it. On Windows, allow the port through Windows Defender Firewall. On Linux, allow it in the active firewall configuration.

Other containers cannot connect

Containers must be attached to the same Docker network and must use the service name postgres as the host, not localhost. Confirm network membership:

docker network inspect external-db-net

A permission error occurs when starting

On Linux, the data directory must be writable by the user the container runs as. Confirm ownership of the directory and that the account carrying out the installation has permission to write to it.

Next steps

Continue to ETL installation.