Skip to content

Install ​

pgRDF is a PostgreSQL 18 extension: one shared library (pgrdf.so) plus its SQL and control files. Installing it means:

  1. putting those files where PostgreSQL can find them;
  2. adding pgrdf to shared_preload_libraries;
  3. restarting the server;
  4. running CREATE EXTENSION pgrdf.

Requirements

PostgreSQL 18 on Linux (x86-64 or arm64) with glibc 2.39 or newer: the official postgres:18 Docker image, Debian 13, or Ubuntu 24.04 and later. musl-based systems such as Alpine are not supported.

RouteBest for
Docker in two minutesTrying it out
Your own Docker imageRepeatable local and CI setups
An existing serverVMs and bare metal
A directory of its ownKubernetes volumes, read-only images
The signed OCI bundleSupply-chain-verified deployments
From sourceDevelopment, other platforms

Try it in two minutes ​

No image build: copy the files into a stock postgres:18 container before its first start.

sh
VER=0.6.34
ARCH=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')
curl -fsSL https://github.com/styk-tv/pgRDF/releases/download/v$VER/pgrdf-$VER-pg18-glibc-$ARCH.tar.gz | tar -xz

docker create --name pgrdf -e POSTGRES_PASSWORD=pgrdf -p 5432:5432 \
  postgres:18 -c shared_preload_libraries=pgrdf
docker cp pgrdf-$VER-pg18-glibc-$ARCH/lib/pgrdf.so       pgrdf:/usr/lib/postgresql/18/lib/
docker cp pgrdf-$VER-pg18-glibc-$ARCH/share/extension/.  pgrdf:/usr/share/postgresql/18/extension/
docker start pgrdf

until docker exec pgrdf pg_isready -h localhost -U postgres -q; do sleep 1; done
docker exec -it pgrdf psql -U postgres -c 'CREATE EXTENSION pgrdf' -c 'SELECT pgrdf.version()'

docker exec -it pgrdf psql -U postgres opens a shell. Next, take the ten-minute tour. If port 5432 is taken, change -p 5432:5432 to, say, -p 5433:5432. docker rm -f pgrdf removes everything.

Release files ​

Each release has one archive per CPU architecture, plus checksums:

pgrdf-0.6.34-pg18-glibc-amd64.tar.gz
pgrdf-0.6.34-pg18-glibc-arm64.tar.gz
SHA256SUMS
pgrdf-0.6.34-pg18-glibc-amd64/
├── lib/pgrdf.so
└── share/extension/
    ├── pgrdf.control
    ├── pgrdf--0.6.34.sql
    └── pgrdf--<old>--<new>.sql     (upgrade scripts)

The current version is always listed in LATEST.md.

Your own Docker image ​

dockerfile
FROM postgres:18
ARG PGRDF_VERSION=0.6.34
ARG TARGETARCH
ADD https://github.com/styk-tv/pgRDF/releases/download/v${PGRDF_VERSION}/pgrdf-${PGRDF_VERSION}-pg18-glibc-${TARGETARCH}.tar.gz /tmp/pgrdf.tar.gz
RUN tar -xzf /tmp/pgrdf.tar.gz -C /tmp \
 && cp /tmp/pgrdf-*/lib/pgrdf.so /usr/lib/postgresql/18/lib/ \
 && cp /tmp/pgrdf-*/share/extension/pgrdf* /usr/share/postgresql/18/extension/ \
 && rm -rf /tmp/pgrdf*
CMD ["postgres", "-c", "shared_preload_libraries=pgrdf"]
sh
docker build -t my-postgres-pgrdf .
docker run -d --name pgrdf -e POSTGRES_PASSWORD=pgrdf -p 5432:5432 my-postgres-pgrdf

Docker fills in TARGETARCH, so the same file builds on x86-64 and arm64. To create the extension on first start, add a script to /docker-entrypoint-initdb.d/ that runs CREATE EXTENSION pgrdf;.

An existing PostgreSQL server ​

sh
VER=0.6.34
ARCH=amd64                       # or arm64
curl -fLO https://github.com/styk-tv/pgRDF/releases/download/v$VER/pgrdf-$VER-pg18-glibc-$ARCH.tar.gz
curl -fLO https://github.com/styk-tv/pgRDF/releases/download/v$VER/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing

tar -xzf pgrdf-$VER-pg18-glibc-$ARCH.tar.gz
cd pgrdf-$VER-pg18-glibc-$ARCH
sudo cp lib/pgrdf.so              "$(pg_config --pkglibdir)/"
sudo cp share/extension/pgrdf*    "$(pg_config --sharedir)/extension/"

Use the pg_config of your PostgreSQL 18 installation. On Debian and Ubuntu the paths are /usr/lib/postgresql/18/lib and /usr/share/postgresql/18/extension.

Add pgRDF to postgresql.conf, keeping any libraries already listed, and restart the server (a reload is not enough):

ini
shared_preload_libraries = 'pgrdf'
sql
CREATE EXTENSION pgrdf;

Keep pgRDF in its own directory ​

PostgreSQL 18 can load extensions from extra directories, so the files don't need to go into the system paths. Unpack the archive anywhere, for example /opt/pgrdf, a mounted volume, or an init-container emptyDir in Kubernetes, and point PostgreSQL at it:

sh
postgres -c shared_preload_libraries=pgrdf \
         -c 'extension_control_path=/opt/pgrdf/share:$system' \
         -c 'dynamic_library_path=/opt/pgrdf/lib:$libdir'

/opt/pgrdf is the unpacked archive directory, containing lib/ and share/extension/. The same settings work in postgresql.conf. In Kubernetes, an init container can download and unpack the release into a shared emptyDir, and the stock postgres:18 container starts with these three settings. No custom image is needed.

The signed OCI bundle ​

Every release is also published to GitHub Container Registry as an OCI artifact, holding the same files, with a verifiable SLSA build-provenance attestation:

sh
# check where it came from (GitHub CLI)
gh attestation verify oci://ghcr.io/styk-tv/pgrdf-bundle:0.6.34 --repo styk-tv/pgRDF

# fetch the files for your architecture (oras CLI) — no login needed
oras pull ghcr.io/styk-tv/pgrdf-bundle:0.6.34-pg18-amd64      # or -arm64

A successful verification means:

  • the artifact was built by the pgRDF release workflow from the tagged commit;
  • the build was recorded in the Sigstore transparency log;
  • the digest matches what you pulled.

Tags are immutable. For reproducible deployments, pin the digest listed in LATEST.md.

From source ​

Building needs Rust (1.96+) and cargo-pgrx 0.19.2. See INSTALL.md in the repository, and Development for the Docker-based build.

Check the installation ​

sql
SELECT pgrdf.version(), pgrdf.build_id(),
       (SELECT extversion FROM pg_extension WHERE extname = 'pgrdf');
--  version | build_id | extversion
-- ---------+----------+------------
--  0.6.34  | v0.6.34  | 0.6.34

SELECT pgrdf.stats() -> 'shmem_ready';   -- true when shared_preload_libraries is set

Using pgRDF from an application role ​

CREATE EXTENSION needs a superuser; your application doesn't have to be one. pgRDF keeps its data in tables in the pgrdf schema, and its functions run with the caller's privileges:

sql
GRANT USAGE ON SCHEMA pgrdf TO app;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA pgrdf TO app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA pgrdf TO app;
  • Creating a graph (add_graph) also creates a table partition. Do that as the extension owner, or additionally grant CREATE on schema pgrdf.
  • For a read-only role, grant only USAGE and SELECT.
  • The file loaders (load_turtle and variants) read files from the database server's filesystem. Give write access only to roles you trust with that.

Upgrading ​

  1. Install the new release's files (any route above).
  2. Restart PostgreSQL.
  3. In every database that uses pgRDF: ALTER EXTENSION pgrdf UPDATE;
  4. Check that version(), build_id() and extversion agree.

Upgrade scripts cover 0.6.22 and later, and your graphs stay in place.

Troubleshooting ​

SymptomCause and fix
stats() -> 'shmem_ready' is falsepgrdf is missing from shared_preload_libraries, or the server wasn't restarted. Most functions still work, but the shared caches and the parallel staged loader don't.
Server won't start: could not access file "pgrdf"The library isn't where PostgreSQL looks. Check the copy step, or dynamic_library_path.
could not load library … GLIBC_2.39 not foundThe system's glibc is too old. Use Debian 13, Ubuntu 24.04+, or the postgres:18 image.
CREATE EXTENSION can't find pgrdf.controlThe share/extension files are missing, or went into a different PostgreSQL installation.
version() and extversion differNew files installed but the database not updated. Run ALTER EXTENSION pgrdf UPDATE.
Alpine-based imageNot supported (musl). Use postgres:18.

pgRDF is released under the MIT license. Documentation built with VitePress, served via GitHub Pages.