Packaging & Distribution¶
How pgokf is packaged and released for every supported channel. Supported
PostgreSQL majors: 15, 16, 17, 18, 19 (19 is not GA as of 2026-08 and PGDG
publishes no postgresql-19 package yet - its build/CI legs are advisory until
PGDG ships packages).
Every format shares one build primitive, so there is exactly one place where the extension image is produced.
The single build primitive¶
cargo pgrx package compiles the extension and writes a filesystem image
whose directory tree mirrors the target root, using the paths reported by the
supplied pg_config:
cd crates/extension
cargo pgrx package \
--no-default-features --features pg${PGVER} \
--pg-config /path/to/pg${PGVER}/bin/pg_config
Output (Debian/Ubuntu example, PGVER=18):
target/release/pgokf-pg18/
└── usr/
├── lib/postgresql/18/lib/pgokf.so # $(pg_config --pkglibdir)
└── share/postgresql/18/extension/
├── pgokf.control
├── pgokf--0.2.0.sql
└── pgokf--0.1.16--0.2.0.sql # $(pg_config --sharedir)/extension
On PGDG RPM systems the same command against /usr/pgsql-18/bin/pg_config
produces usr/pgsql-18/lib/... and usr/pgsql-18/share/extension/....
Because the tree already mirrors the install root, every packaging format
does the same thing: run this command, then copy the resulting tree into the
package payload. --no-default-features --features pg${PGVER} pins the build
to exactly one PostgreSQL major.
Pinned toolchain (keep in sync with rust-toolchain.toml and CI):
rustc 1.96.0, cargo-pgrx 0.19.2 (cargo install --locked cargo-pgrx --version 0.19.2).
Debian / Ubuntu (.deb)¶
One package per major, named postgresql-N-pgokf, depending on postgresql-N,
mirroring PGDG's own per-major extension packages.
packaging/deb/build-deb.sh 18 # or 15 / 16 / 17 / 19
build-deb.sh runs the build primitive, stages the tree into a package root,
renders DEBIAN/control from packaging/deb/control.template,
and calls dpkg-deb --root-owner-group --build. Output defaults to
target/packaging/deb/postgresql-N-pgokf_<version>-1_<arch>.deb.
| Override | Default |
|---|---|
PG_MAJOR |
18 (or the first positional argument) |
PG_CONFIG |
/usr/lib/postgresql/$PG_MAJOR/bin/pg_config |
DEB_REVISION |
1 |
OUTPUT_DIR |
<repo>/target/packaging/deb |
MAINTAINER |
repo author |
Inspect and install:
dpkg-deb -I postgresql-18-pgokf_0.2.0-1_amd64.deb # control metadata
dpkg-deb -c postgresql-18-pgokf_0.2.0-1_amd64.deb # payload file list
sudo apt install ./postgresql-18-pgokf_0.2.0-1_amd64.deb
Building the .deb for a major requires that major's postgresql-server-dev-N
(for pg_config) - only the locally installed major can be built on a given
host.
RHEL / Fedora (.rpm)¶
packaging/rpm/pgokf.spec follows the PGDG
convention: package pgokf_NN, installed under /usr/pgsql-NN, depending on
postgresql NN-server. The major is chosen at build time:
rpmbuild -ba packaging/rpm/pgokf.spec --define 'pgmajorversion 16'
# or under mock for a clean chroot:
mock -r rocky-9-x86_64 --define 'pgmajorversion 16' \
--buildsrpm --spec packaging/rpm/pgokf.spec --sources .
%build installs the pinned cargo-pgrx into a build-local root and runs the
build primitive; %install copies the staged tree into %{buildroot}.
Source0 is a pgokf-0.2.0.tar.gz of the repository at the release tag.
PGXN (META.json)¶
META.json is a PGXN meta-spec v1.0.0 distribution manifest
(name pgokf, version 0.2.0, provides.pgokf, prereqs PostgreSQL
≥ 15, resources, AGPL-3.0-only core license). provides.pgokf.file points at the generated
crates/extension/sql/pgokf--0.2.0.sql, which the release process emits into
the tree before building the PGXN zip.
Validate locally:
jq empty META.json # well-formed JSON
# required v1 fields present:
jq -e 'has("name") and has("version") and has("abstract")
and has("maintainer") and has("license") and has("provides")
and has("meta-spec")' META.json
Docker image¶
packaging/docker/Dockerfile is a stock
postgres:N image with the extension pre-installed, so CREATE EXTENSION
pgokf; works out of the box (auto-created on first init), plus the optional
extensions pgokf lights up at runtime - pgvector, pg_cron, and a BM25
provider: Tiger Data pg_textsearch by default (PostgreSQL license; on the
17 and 18 images), or ParadeDB pg_search when opted in - each toggled by a
WITH_* build argument (the providers are fetched from their pinned upstream
releases and verified against packaging/docker/pg_textsearch.sha256 /
pg_search.sha256). First-init hooks create the extensions,
env-driven least-privilege login roles, and the catalog policy; the image also
carries the pgokf-backup and pgokf-restore tools. Build from the repository root (a
.dockerignore keeps target/ and .git/ out of the context):
docker build -f packaging/docker/Dockerfile \
--build-arg PG_MAJOR=18 \
-t pgokf:0.2.0-pg18 .
A second Dockerfile,
packaging/docker/Dockerfile.companions,
packages the three network companions (pgokf-ingest, pgokf-embed,
pgokf-mcp) into one non-root image.
CI builds and smoke-tests both images natively on amd64 and arm64 for every
supported major on every packaging change, and on a version tag pushes the
per-architecture images by digest and merges them into multi-architecture
manifests: ghcr.io/logicocean/pgokf:<version>-pg<major> and
ghcr.io/logicocean/pgokf-companions:<version> (so the same tag runs on x86,
arm64 servers, and Apple Silicon). Between releases, build locally with the
commands above. The smoke scripts CI runs
(packaging/docker/smoke-test.sh, smoke-test-companions.sh) work against
any Docker daemon.
Details, build arguments, and the init hooks: packaging/docker/README.md. The reference production stack built on these images is compose-deployment.md.
Homebrew tap¶
packaging/homebrew/pgokf.rb builds from
source against Homebrew's postgresql@N and installs into that keg. For a tap
LogicOcean/homebrew-pgokf:
brew tap logicocean/pgokf
brew install pgokf
Update url, sha256 (from the release tarball), and the postgresql@N
dependency at each release.
Release process¶
PGVER ranges over 15-19; 19 is best-effort until PGDG ships packages.
- Gate. Complete release-checklist.md (static, supply-chain, schema, and per-major live smoke gates). Confirm CHANGELOG.md records the release.
- Version bump. Bump every pin of the version together, as one
deliberate commit - the exact list lives in
release-checklist.md
(crate and control file,
META.json, the rpm spec and Homebrew formula, the companions' path-dependency pins, the compose and Docker examples, andCargo.lock). - Tag.
git tag v0.2.0 && git push origin v0.2.0. CI (.github/workflows/packages.yml) builds the.debs (uploaded as workflow artifacts), validatesMETA.json, and builds the Docker images per major. - PGXN. Emit the generated SQL into the tree
(
cd crates/extension && cargo pgrx schema pg18 > sql/pgokf--0.2.0.sql), build the distribution zip (repo contents +META.json+ generated SQL), and upload it at https://manager.pgxn.org/ under thepgokfdistribution. - Docker. Automatic: pushing the version tag runs the packages workflow,
which builds, smoke-tests, then pushes
ghcr.io/logicocean/pgokf:<version>-pg<major>for each supported major. A newly created GHCR package is private; flip it to public once, in the package settings, on the first release only. - Homebrew. In
LogicOcean/homebrew-pgokf, updateFormula/pgokf.rburl+sha256for the new tag (curl -fsSL <tarball> | shasum -a 256) and push. - Announce. GitHub Release notes from the CHANGELOG entry.
Build-output hygiene¶
Built .deb/.rpm files and images are never committed. build-deb.sh
writes under target/ (git-ignored); packaging/**/build/, *.deb, and
*.rpm are also git-ignored. Build into target/packaging/ or /tmp.