~ knotless Search/
↑↓ move↵ open⇧↵ all results
0
0
main
302 lines · 26.7 KB Raw History

pg-source: where the pinned PostgreSQL 18 comes from (0006 M0-PG-SOURCE)

Date: 2026-10-11 (measured on hat-8, Fedora 44, glibc 2.43, x86_64, as uid 1000). Consumers: the gateway kcp store (M2-KCP-STORE, kine -> postgres over a unix socket) and every tenant cluster store (M2-POSTGRES). Dev and bidder kcp stores are kine-sqlite and need none of this.

1. Decision order (user, 2026-10-11, final)

  1. Official binaries first. The PostgreSQL Global Development Group publishes no generic Linux binary tarball; its official binaries are the PGDG packages (apt.postgresql.org debs, yum.postgresql.org rpms). Use them if they can be extracted without root and run relocatably as a non-root user.
  2. Build from the official source tarball (ftp.postgresql.org/pub/source) only if (1) cannot be made to work, with a build-host script scripts/build-postgres.sh. This is the fallback.
  3. Third-party repackagers are out: zonky embedded-postgres-binaries and theseus-rs/postgresql-binaries are not used. Section 6 keeps the facts measured before that ruling, for the record only.

2. Choice

PGDG jammy-pgdg debs for PostgreSQL 18.6 (18.6-1.pgdg22.04+2), amd64 and arm64, plus their Ubuntu 22.04 (jammy) shared-library dependency closure, extracted without root into one relocatable tree. PGDG works on hat-8 and on every distro image tried, so the fallback was not needed. A source build was prototyped and measured before the user's final order (section 5). Its script is not committed.

Why jammy and not bookworm, noble or the EL rpms: PGDG binaries link the host distro's ICU, OpenLDAP and OpenSSL by soname. The oldest PGDG target at or below the plan's floor (Ubuntu 22.04) is jammy: max GLIBC_2.34 in the PG binaries and GLIBC_2.35 across the bundled libraries. EL8 links OpenSSL 1.1, and EL9 links ICU 67. Both have the same soname problem as jammy, and neither lowers the floor.

What "relocatable" means for the PGDG tree (measured)

  • Layout must be kept. PGDG compiles in bindir=/usr/lib/postgresql/18/bin, sharedir=/usr/share/postgresql/18 and pkglibdir=/usr/lib/postgresql/18/lib. At startup PostgreSQL resolves share and pkglib relative to the running binary (make_relative_path) only while the tail lib/postgresql/18/bin of the binary's path matches. So the tree is kept as <any-root>/usr/lib/postgresql/18/{bin,lib} plus <any-root>/usr/share/postgresql/18, where <any-root> can be any path. That was proven from .../arbitrary2/x y/z/... (a path containing a space) on hat-8, and from /opt/any/where/... read-only in containers. Flattening to bin/ lib/ share/ breaks it.
  • No RUNPATH in PGDG binaries. libpq.so.5 (from the PGDG libpq5 deb) and the jammy libraries sit in <any-root>/usr/lib/sys/, and are found only through LD_LIBRARY_PATH=<any-root>/usr/lib/sys. That variable must be set on the postgres, initdb and pg_dump exec ONLY, never in the core's own environment. Measured: hat-8's grep, spawned under that variable, loaded jammy's libpcre2 and warned libpcre2-8.so.0: no version information available. pg_ctl starts postgres through /bin/sh, which then inherits the variable. That is one more reason the units exec postgres directly (M2-POSTGRES, M2-KCP-STORE already do), not pg_ctl.
  • Host requirements left: glibc >= 2.35 (libc.so.6 libm.so.6 libresolv.so.2 ld-linux-*.so) and host tzdata. PGDG is built --with-system-tzdata=/usr/share/zoneinfo, an absolute path that is not relocatable. On ubuntu:22.04 (no tzdata in the image) the server started with TimeZone=UTC0, and SET timezone='UTC' failed with invalid value for parameter "TimeZone". On every image with /usr/share/zoneinfo it worked. check-host (M1) must require /usr/share/zoneinfo/UTC on gateway hosts.
  • Non-root: every run was as uid 1000 on hat-8 and as uid 65534 in the container stand-ins. initdb refuses root anyway.
  • Port 0: postgres refuses it in every build: FATAL: 0 is outside the valid range for parameter "port" (1 .. 65535) (the GUC minimum is 1). This shapes the two stores differently:
    • The gateway kcp store opens no TCP port at all: listen_addresses='' plus a unix socket directory. M2-KCP-STORE already specifies this.
    • Tenant stores that need TCP must lease a port (M2-POSTGRES "0 = leased"). The bound port is read back from ss -ltnp (matched on the postmaster pid) and from line 4 of postmaster.pid.
    • kine itself takes --listen-address 127.0.0.1:0 and announces the bound port.
  • Collation: initdb with --locale-provider=builtin --builtin-locale=C.UTF-8 -E UTF8, which gives datlocprovider=b, datlocale=C.UTF-8 and datcollversion=1. The builtin provider is versioned with PostgreSQL itself, independent of glibc and ICU. kine's name column is COLLATE "C" anyway (kine v0.17.1 pkg/drivers/pgsql/pgsql.go:40). ICU 70.1 is still linked, and its unicode collation reports collversion=153.112. M2-POSTGRES records that value and treats a change as major-class only for databases that actually use ICU collations.
  • Security update churn: 44 of the 47 pins are Ubuntu jammy packages (taken from jammy + jammy-updates + jammy-security, highest version). Every Ubuntu security update to libssl3, libxml2, krb5 and the rest changes the bundle's pins.

3. Verification steps (performed; M1-ASSETS repeats them in its assembly script)

  1. PGDG key: https://www.postgresql.org/media/keys/ACCC4CF8.asc, imported into a fresh GNUPGHOME. Fingerprint B97B 0AFC AA1A 47F0 44F2 44A0 7FCC 7D46 ACCC 4CF8 ("PostgreSQL Debian Repository", rsa4096, 2011-10-13).
  2. https://apt.postgresql.org/pub/repos/apt/dists/jammy-pgdg/InRelease was verified against that key: Good signature, made 2026-10-11 09:30:45 UTC.
  3. Ubuntu archive key F6EC B376 2474 EDA9 D21B 7022 8719 20D1 991B C93C ("Ubuntu Archive Automatic Signing Key (2018)") was fetched by full fingerprint from keyserver.ubuntu.com. It verified the jammy, jammy-updates and jammy-security InRelease files: archive.ubuntu.com for amd64, ports.ubuntu.com for arm64. All Good.
  4. Each main/binary-<arch>/Packages.gz sha256 was checked against the SHA256 section of its signed InRelease.
  5. Each .deb sha256 was checked against its Packages stanza (47 per arch, all matched; table below).
  6. Extraction without root: ar x <deb> then tar -xf data.tar.* into a scratch root (no dpkg, no maintainer scripts). Then copy usr/lib/postgresql/18/{bin,lib}, usr/share/postgresql/18, and every *.so* from lib/<triplet> and usr/lib/<triplet> into usr/lib/sys. Drop usr/share/postgresql/18/man and usr/lib/postgresql/18/lib/bitcode (JIT bitcode; llvm-jit is a separate package and is not installed).
  7. Repack: tar --sort=name --owner=0 --group=0 --numeric-owner --mtime=@1786473511 | zstd -19. The epoch is the newest mtime in postgresql-18.6.tar.bz2.

Helper scripts used: apt_fetch.py, jammy_closure.py, pgrun.sh, pgmini.sh and minisign_verify.py, all in the session scratchpad. M1-ASSETS turns steps 1-7 into its own script.

4. Pins

Repository bases: https://apt.postgresql.org/pub/repos/apt/ (pgdg). For ubuntu, https://archive.ubuntu.com/ubuntu/ (amd64) and https://ports.ubuntu.com/ubuntu-ports/ (arm64). Filename = <pool dir><package>_<version without epoch>_<arch>.deb, for example https://apt.postgresql.org/pub/repos/apt/pool/main/p/postgresql-18/postgresql-18_18.6-1.pgdg22.04+2_amd64.deb.

packageversionrepopool dirsha256 amd64sha256 arm64
postgresql-1818.6-1.pgdg22.04+2pgdgpool/main/p/postgresql-18/2aab00b13babd3d9abc257bc5f6b00efa1f7c27cda071413f358d2e0cdb844208a379f0684b480b60e79657ac8178e8b00c835e7575e85ae746c091d336563d3
postgresql-client-1818.6-1.pgdg22.04+2pgdgpool/main/p/postgresql-18/ad4e491adceaf1453162c62691473ace78ed81ab20f50d11b344a793d13ed4bd21f1b418621fc9c90785b18ec2d7fe4fd8ff111cc607fc3b3625464fc6e7886b
libpq518.6-1.pgdg22.04+2pgdgpool/main/p/postgresql-18/8af0b458834e219f3aa7c904fa1237ea484950486e3165a3a90204878e060530fc0d787c9da82bd0146e5e365989f3c92dbb3d73c3a32c62a2e4d56ab90933a6
libaudit-common1:3.0.7-1ubuntu0.1ubuntupool/main/a/audit/3e4e8586db5f57f431954a9125556fe6df86610592c0cf46ba1127fae8871e3f3e4e8586db5f57f431954a9125556fe6df86610592c0cf46ba1127fae8871e3f
libaudit11:3.0.7-1ubuntu0.1ubuntupool/main/a/audit/00d7eb086dedc85bd5b9cbde650a1c71460499cb62e439acb761bc7bcb4eaaac963474b42258e8caa15eec1db61d8424fd6b7ef717ca4e371b3240506854b3fe
libcap-ng00.7.9-2.2build3ubuntupool/main/libc/libcap-ng/124d0c8748a841f279e996298ef8aac69a249e294792f4b5e16dc00496f1d3ac884c8bc87da241abaa2b0ca80162486cf66eff67dfc545bea56622e1170e9ee5
libcap21:2.44-1ubuntu0.22.04.3ubuntupool/main/libc/libcap2/c497efb7fa3cd19a7ff297d95c7c5d678063c80c9fc230c9d034a8ee02ca84467a8eb6549355a16f327ede574f12e6ebed983b52ab38ce4a618e6e9274b9d4f5
libcom-err21.46.5-2ubuntu1.2ubuntupool/main/e/e2fsprogs/552bc8169451cfdcf174a8da845b13ced0a55777149af5cf47491193161ed7913a7b6a2b34c2171b7c8f9ddae58c93b6e416fcd9ac4fa8eb5a15a1a8f3f99afa
libdb5.35.3.28+dfsg1-0.8ubuntu3ubuntupool/main/d/db5.3/ce60e446c9cb0e94bb4b4d0fe4f969e772edec250deb186bacf955e4d196548be5b672aeaca690b3b7ee97b03dbc07ddb49be7b6ea0a770fa6707666ca1cef59
libffi83.4.2-4ubuntupool/main/libf/libffi/b4f88c91fa6f4c942097be6abfc365fb133c5e147640168cbb7704fd855eac10a0cdf938e8da19bd2252c681f80268609a32d06496a1f8d0ebe1fa41debec697
libgcc-s112.3.0-1ubuntu1~22.04.3ubuntupool/main/g/gcc-12/d383e642d83263147f7b4b69fb92cf1036e5246c6be3accf10b77f986684589a46626e1af6b159061e055f843654ee1f0f1e65fa280331ed47ee76ba1b1f6045
libgcrypt201.9.4-3ubuntu3.3ubuntupool/main/libg/libgcrypt20/8f16329a0aabf4900271a3687890721bbef307e60983acae5b92eeff12e799b3bd98a709641e7e61c8798bb84030886a96fd56424b053a6e9996a8391ce20597
libgmp102:6.2.1+dfsg-3ubuntu1ubuntupool/main/g/gmp/d199a77e11701d4d620dd4f62e05740e3072dce893856ea3bbaa6ae9fa19fef132233a3bf7c8b19e86ef3629334f0bece716bb163605d12e0d3a443d57a401d7
libgnutls303.7.3-4ubuntu1.9ubuntupool/main/g/gnutls28/65e08f0b5d1e620cc5cc9478cd1035f83ea752a6fae23141afd2d111a8f6c555cce4bf33fa79446ddee42a992e569f12a57c1a6f8916a2e8349249be0f7ad655
libgpg-error01.43-3ubuntupool/main/libg/libgpg-error/1fbacdf9bd1e431cee874a697b339f6f925182bc79bba5a112b53669b33265c5ffa9029cdeb2786e0db1f614f3d2205f75f466a66b25e22aa89ecdf814491875
libgssapi-krb5-21.19.2-2ubuntu0.10ubuntupool/main/k/krb5/08e98a3dc74361cdb13c0d68bc73e0352552490546c1ad3ce5bff5426f6a2dfee1001bffd91dd306498ec1824a8330014399a0e0889a562069003726348d7f55
libhogweed63.7.3-1build2ubuntupool/main/n/nettle/2402ac51ebc760799b01f3fd4933126c5eb446e5b043832601fb589f5e50c363844e5d093dd3982a85c134d47a9e22b129123fb817eb3eea96e936805b0f5170
libicu7070.1-2ubuntupool/main/i/icu/58a154f6307289813da2276f900498ef536ae7c0522d2cf31a3c3c5cf62dfd9aac68372cf4a976e6a206858fd9b28c68e49d37d650b9b8653270038a6e7bc174
libidn2-02.3.2-2build1ubuntupool/main/libi/libidn2/bc935e1871aa4a75d3f4ff549af32b7316aecfbea2200d85055878767b8398c8aeb29cc8deedc0710a97e44088ef0271dfe1197e77c0a0fc0c5602e14aeb938f
libk5crypto31.19.2-2ubuntu0.10ubuntupool/main/k/krb5/40429c0099678fbc35045f0c63a10bc3490251d80cf1006095eaa0272c8d5e27e51d72b346813b57f26c09827f96eb856adb9b553814fbc61a5e8c8a25d292a3
libkeyutils11.6.1-2ubuntu3ubuntupool/main/k/keyutils/940daf78ee0229549b4eabc92ffd79dd038ed96a44e2e912305a23540cf22a0afc26b34c487ea5187585ee0f2c67c738b97e8bae434cca4b546d86743b9e6c80
libkrb5-31.19.2-2ubuntu0.10ubuntupool/main/k/krb5/0da3e0df7d6314615160a42f65ff345986783be02cd65a6ce797cfbacc7bcb0d8de066e35be457bf0c53c995f8baa270ad61566dcd892d0a7cc3c0438ff513b7
libkrb5support01.19.2-2ubuntu0.10ubuntupool/main/k/krb5/0406052ac2d267f05088ada6d36df61aaa338cbe8d5e13fb1d7f79da560817edc535d5ccf5ea99fb63d86b33082c5ed553a6aa8c7cbf3fed1ef0dac1d7b7dcd6
libldap-2.5-02.5.20+dfsg-0ubuntu0.22.04.1ubuntupool/main/o/openldap/a3ee4ac116a2c50c9ddfe9de91c0781a50704244771474334340cdce02f5cd4f305ec2bf85ad8e8a6309b1a48e601f172503a267ca90d511ccbb098cdf009d6b
liblz4-11.9.3-2build2ubuntupool/main/l/lz4/ac9b54d0feb840345060c74fb687675c5e1eb2b195effafae38c5f9991041e983e2274893e0963c758f0d18ba80d033736909373247a7deb211e9ff590a09133
liblzma55.2.5-2ubuntu1.1ubuntupool/main/x/xz-utils/af77f099e7fa95a31267023535832804382fa66572a6b38002187be6e15116cb97f4c7e360aa229d3bf0a5b56b204652ce4f1704536dc0256c0e2537b356f397
libnettle83.7.3-1build2ubuntupool/main/n/nettle/6da09e685e5587f8873f662b007de45f75424fb33d2c4a51837380e683d33c7ebcd667d9a51c2474f7ffc52807ab4a24f8b877b6da1a6f5b75e50e48ec4d634a
libnuma12.0.14-3ubuntu2ubuntupool/main/n/numactl/0721c89001fbbd1ada23e89da5d60e762763c1a7b3dc814a2e9a518480a8043dca67a774b20ed639361715ef0981d236f294ff2987579b3d18faede67c3a9152
libp11-kit00.24.0-6ubuntu0.1ubuntupool/main/p/p11-kit/9d949950970a062a81051a78ec4075b8dba608f063afaa5c8752a612d139a9b50cfad0790be90ccb56de67e6c58a67d73e4769028eb19a2c0d799fa19478c2ff
libpam0g1.4.0-11ubuntu2.8ubuntupool/main/p/pam/faaf4b6d1bfb33a7fc4e195448439c202869d67c8de17c4ecd29b7719e0ac4d6f61ae0342dfba2b6c6b61f3d46925371434a4719a251f7585f9baa1341fcc9e2
libpcre2-8-010.39-3ubuntu0.1ubuntupool/main/p/pcre2/01a5a74f3d305cad32fffffdc200c2a92fd8e5a01bff97de76ac598fb444d53eb85beefd54108f1c34a89cb26688eb1b2eeaa099e4995091295a1d39f9c67a91
libreadline88.1.2-1ubuntupool/main/r/readline/51fd16f608efa710c987e4b071ffba0bec63a9ac8e55eddd5770f5e5252edc0954291f2dd185d3a759227b31b7de4269e495a084fdad89e24a9cc4d0d20888a7
libsasl2-22.1.27+dfsg2-3ubuntu1.2ubuntupool/main/c/cyrus-sasl2/391cb48d7e601d5bb590da8d426750acf6c987241ba280a36227873b94f20ceed4f60677a0024f2b888a563f1d396a1f43fe22097e01d0a7048695c3c1ef8e18
libsasl2-modules-db2.1.27+dfsg2-3ubuntu1.2ubuntupool/main/c/cyrus-sasl2/0e222c26d70c2cfd132c8de035bcf9673067b6cbfea0a7421dced7b6256ae774438df2296b2f828ab05287fadbf1a29f2e3bc0d618807b01128829313be91895
libselinux13.3-1build2ubuntupool/main/libs/libselinux/b96c6b40ee2388bd51341cb11c0f1d5bcca29b9180b6e3a77a06b881f2913f7e3a0726b2174a40fa28e74712867aa6e40d3d725543e8f668af9e9e59a28c817c
libssl33.0.2-0ubuntu1.30ubuntupool/main/o/openssl/d1b4636e32ac6d3b95d583ac05ac548b1aa248414bae1c51b14f54be0f8fd7bc1c4b8cc736eed8a0caafc385f854fa6852382221d84be4795f1d19a52b9fec53
libstdc++612.3.0-1ubuntu1~22.04.3ubuntupool/main/g/gcc-12/29ef3d289b272704b75141906c8f683db0f2bdb0942061366691333bfb289bdc59d244119e6129c7e9c0897491c0e210e925d15881b2dedcf8965ceb4fbf1aa3
libsystemd0249.11-0ubuntu3.22ubuntupool/main/s/systemd/4fae4644bcfd86f891faae12cedbf30aca280cf76a034768aec3a03fe42ddc259805c8c136fd41d9bff355297fdf6f811529960908711f647e38e1fd39a198ec
libtasn1-64.18.0-4ubuntu0.2ubuntupool/main/libt/libtasn1-6/a0903b4fae3ac2548a22d8822382e6d23586e42196d83ff67e82df36cd39fc6cd9f0ed3ca0cb86f6116bb59388aea92b021c05797b4fba7451a2fed594cb1e1e
libtinfo66.3-2ubuntu0.3ubuntupool/main/n/ncurses/3b8dff43a31168f5020928f2ab9a97324c5b47ae708311781f6bd01306c96214971b5fd1cf8f7d68ba00f40d8eec6474fae6a6adbe19883aa42dd2b74c672e4a
libunistring21.0-1ubuntupool/main/libu/libunistring/988fb59de6a0a313844277e8a6e45d3dc16f5ea75a603a46b16b936426f0ac6559e4af5c1fac70d1fbc19f3c732331ace8449f1f7112887e7b56b8370bd8942b
liburing22.1-2build1ubuntupool/main/libu/liburing/f6e9bdf50c9683cd9a74ad92d51dde085f40baf0a5fcd8a56fc68425c1bd3c5fa9221f0d47fd32819558f7a91677e97c72bd88646d38d369ffa70720ac49c27d
libuuid12.37.2-4ubuntu3.6ubuntupool/main/u/util-linux/97eaa1090c2e7ddaad55d58f9d0d7907d64b70f89228405d68a7ce7d56a89d672478ccd8df956d8e5cf087bff1471bcd9991838be9c7999e5737d092034c492d
libxml22.9.13+dfsg-1ubuntu0.14ubuntupool/main/libx/libxml2/16e395b2c52d6ab232053468febc69f0876956ec2fae357a941a2a8dab36574f1e85b731baabd51331d70a6392c652bc39fa2c231ff784555bd6a61631009387
libxslt1.11.1.34-4ubuntu0.22.04.5ubuntupool/main/libx/libxslt/5e50bc83e9365942cf63272d8a45ce71170aaf4a1a4e3c4b30f591f6194d77efdd533b9980918ca64531254ccbdfd5efc492bbef37c70f0b5559b3b8f306b626
libzstd11.4.8+dfsg-3build1ubuntupool/main/libz/libzstd/ae7db00ce8b093e50c994518b90203544e063b4bc574836a048bb142b950b2c90102eb80384c2432c4be819663341a1c4e511d05f13ec1467643696531ec6491
zlib1g1:1.2.11.dfsg-2ubuntu9.2ubuntupool/main/z/zlib/9dc17e51a1be2d9ed63b7b84ef0e4e29c5abe6f1bc62cb03e7181483cce8a2f2cfd99d1ca41e710fdd3f68bfdc4d36dd24e14377656764f00b215b89cf6976e8

Debs per arch: 47 (3 PGDG + 44 Ubuntu); 30,428,248 bytes (amd64) and 29,440,882 bytes (arm64). Index digests at pin time (signed InRelease of 2026-10-11): jammy-pgdg main/binary-amd64/Packages.gz ca96279cfb8c49c2ac59dbdb083cb099223ad9e9f23313951eb8f715c5a1577c and main/binary-arm64/Packages.gz 911dc4a3e960d5df5679e29fe7756c6d0eee1f9ffb79fbc0a5d8cd3735f8f32b.

Assembled trees (this spike's assembly; M1-ASSETS re-pins its own output):

archraw byteszstd -19 bytessha256 of .tar.zst
amd6484,342,619 (pg bin 15.8 M, pg lib 5.7 M, sys libs 61.0 M of which libicudata 29.5 M, share 1.9 M)25,654,278467436b73669a7ca00ee3c5c44c468f892cabcf670dd529ebeeb99aeb63123fd
arm6481,912,39525,072,72339847c32e8c7d71667ce33c5b625a96d0a3273cb0f1bcfc9f0c42545e4eb12b2

Size lever for M0-SIZE-BUDGET: ICU is 30 MB of the 84 MB, and the builtin provider does not use it. PGDG links it, though, so it cannot be dropped without the fallback build.

5. Measurements on hat-8 (uid 1000, arbitrary path, kine v0.17.1 /usr/local/bin/kine)

Harness: initdb, pg_ctl on a unix socket, psql, kine against the socket, an etcd v3 put+get through kine (go.etcd.io/etcd/client/v3 v3.6.8), pg_dump, stop, port 0 attempt, then a leased TCP port. Commands, PGDG tree (B=<root>/usr/lib/postgresql/18/bin, LD_LIBRARY_PATH=<root>/usr/lib/sys):

$B/initdb -D $T/data -U postgres --auth=trust -E UTF8 --locale-provider=builtin --builtin-locale=C.UTF-8
$B/pg_ctl -D $T/data -l $T/pg.log -w -o "-c listen_addresses='' -c unix_socket_directories='$T/run' -p 5432" start
$B/psql -h $T/run -U postgres -d postgres -Atc 'select 1'
kine --endpoint "postgres://postgres@localhost/kine?host=$T/run&sslmode=disable" --listen-address 127.0.0.1:0
$B/pg_dump -h $T/run -U postgres -d kine -f $T/kine.sql
$B/pg_ctl -D $T/data -m fast -w stop
$B/postgres -D $T/data -c listen_addresses=127.0.0.1 -c unix_socket_directories='' -p 0
stepPGDG bundle (choice)source build (fallback prototype)
initdb0.338 s0.266 s
pg_ctl start, unix socket only (no TCP listener: 0)0.109 s0.103 s
first SELECT 1 after start returns0.009 s (0.123 s from start command)0.005 s (0.113 s)
kine on the socketannounced and bound 127.0.0.1:37867 (port 0)127.0.0.1:37055
etcd put+get through kineok, rev 3, 4.7 msok, rev 3, 5.2 ms
pg_dump of the kine db0.030 s, 3,385 bytes, has CREATE TABLE public.kine0.027 s, 3,329 bytes
pg_ctl stop -m fast0.102 s0.102 s
-p 0refused: 0 is outside the valid range for parameter "port" (1 .. 65535)same
leased TCP port33959 bound, read back from ss and postmaster.pid, inet_server_port()=3395938745, same
RSS, postmaster tree idle (sum of VmRSS)101,736 kB56,812 kB
RSS, postmaster tree with kine connected183,752 kB118,668 kB
RSS, kine36,696 kB36,872 kB
fresh data dir66.3 MB48.6 MB

Distro stand-ins (container images, uid 65534, --network none, tree bind-mounted read-only at /opt/any/where/...): initdb + pg_ctl on a unix socket + SELECT 1 + pg_dump + stop all passed for the PGDG bundle and for the source build on these images:

  • ubuntu:22.04@sha256:5ec03bb3441e8b0bf3b4f9cd4629a1ae763010dc3035bb8da3ae6cf026486401 (glibc 2.35, no tzdata)
  • ubuntu:24.04@sha256:534baea6a22c03a63003dbc8dbe78fe34bc0d7e595d9a9dc9834884ff530eb55 (2.39, no tzdata)
  • debian:12-slim@sha256:7c7b2c966bc9ee8cedfeef67e0e279108992c77681fa595db4a9d65c06ccc587 (2.36)
  • debian:13-slim@sha256:a29215f6a35e51e22adffa17f89e9d2ef06214e64a2bad10d765c46aea49f11f (2.41)
  • fedora:44@sha256:43b29f65a41eb9c35e1cd5323e3bdf3b655c2357a9f4f1ff2f9c2798e5045d80 (2.43)

On the images without tzdata, PGDG ran with TimeZone=UTC0 and refused SET timezone='UTC'. The source build carries its own share/timezone and accepted UTC and Europe/Berlin everywhere. arm64: the PGDG arm64 bundle passed the same test in debian:12-slim (linux/arm64) under hat-8's qemu-aarch64 binfmt (uname -m = aarch64).

Without the bundle's libraries, the bare PGDG debs on hat-8 failed: libldap-2.5.so.0: cannot open shared object file. libicu*.so.70 and libpq.so.5 were missing as well. On minimal images, libnuma, liburing, libxml2, readline, krb5 and OpenSSL 3 were also missing (debian:13 additionally lacked libgnutls30). That is why the bundle carries the whole jammy closure.

6. Fallback: build from the official source tarball (status: prototyped, not committed)

Use only if the user rejects section 2's costs: the 44 Ubuntu pins, LD_LIBRARY_PATH, host tzdata, 25 MB zstd and 100 MB RSS. Measured prototype, copy kept at $TASK_STATE_DIR/build-postgres.sh.fallback-prototype:

  • Source: https://ftp.postgresql.org/pub/source/v18.6/postgresql-18.6.tar.bz2, sha256 555610c24d53e4316da5b7d3fc25c279d96856d5e0e23ee308c328c5fa881d9f (matches the published .sha256; upstream publishes no PGP signature for source tarballs).

  • Since PG 17 the tarball ships no generated parser, so the build host needs bison, flex and perl. The prototype builds pinned host tools with zig itself:

    • m4-1.4.21: f25c6ab5...ab66, GPG Good, Eric Blake 71C2CC22B1C4602927D2F3AAA7A16B4A2527436A
    • bison-3.8.2: 9bba0214...5bf2, GPG Good, Akim Demaille 7DF84374B1EE1F9764BBE25D0DDCAA3278D5264E
    • flex-2.6.4: e87aae03...e995, GPG Good, Will Estes 56C67868E93390AA1039AD1CE4B29C8D64885307
  • Toolchain: zig 0.16.0, x86_64 sha256 70e49664a74374b48b51e6f3fdfbf437f6395d42509050588bd49abe52ba3d00, minisign Good with RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U; aarch64 sha256 ea4b09bfb22ec6f6c6ceac57ab63efb6b46e17ab08d21f69f3a48b38e1534f17. It targets <arch>-linux-gnu.2.28, so the glibc floor is 2.28 regardless of build host, and it cross-compiles arm64 on hat-8 with no container, no qemu and no apt.

  • Configure flags: --prefix=/opt/postgresql --without-icu --without-readline --without-zlib --without-openssl plus every other optional library off. It is not --with-systemd. The make variable rpathdir='$$ORIGIN/../lib' gives RUNPATH $ORIGIN/../lib. The prefix contains "postgres", so pkglibdir = lib/ and sharedir = share/.

  • Result: NEEDED only libc/libm/libpthread/libdl/librt, max GLIBC_2.27, own tzdata, no env vars.

    archrawzstd -19build time on hat-8
    amd6416.2 MB4,853,858 bytes96-180 s
    arm64-4,380,281 bytes (cross)206 s
  • Not yet byte-reproducible: two amd64 runs in different work directories differed in bin/postgres, because pg_config's compiled-in CC, CFLAGS and configure arguments embed the work path. The fix is a fixed build path. The dry-run test (--dry-run prints every pin) would be committed with the script.

7. Rejected candidates (facts recorded before the user ruled repackagers out)

  • zonky io.zonky.test.postgres:embedded-postgres-binaries-linux-{amd64,arm64v8}:18.6.0 (Maven Central, jar sha256 amd64 008ee189eaa7ca2b58bd01dd950291e638b998392cf982297acd4779ec898ac1, arm64 5f54e016723afa6213925a8acb939bac52944b1d348f65c7a20f0cd2928c31be). Problems:
    • Only initdb pg_ctl postgres: no pg_dump and no psql.
    • Bundles EOL OpenSSL 1.1 and ICU 60.
    • The maven .asc is signed by key 6B02ED0ED53F9FD3, which is not retrievable from keyserver.ubuntu.com or keys.openpgp.org, so it is unverifiable.
  • theseus-rs postgresql-18.6.0-{x86_64,aarch64}-unknown-linux-gnu.tar.gz (sha256 bb3d09f8...ca61 and 5d2b5e8b...ee13). Problems:
    • Only a same-channel .sha256. GitHub attestation API returns 404.
    • Built on Debian 12 gcc 12 with --without-icu --with-system-tzdata.
    • Links host libssl3, libxml2, krb5, lz4, zstd and readline (not bundled).
    • The musl variants need a musl host.

8. Proposed internal/versions/versions.json entry (the lead edits the file)

"postgres": {
  "version": "18.6",
  "how": "PGDG official debs (apt.postgresql.org jammy-pgdg 18.6-1.pgdg22.04+2: postgresql-18, postgresql-client-18, libpq5) plus their Ubuntu 22.04 shared-library closure (44 debs from jammy, jammy-updates, jammy-security), each verified by signed InRelease -> Packages.gz sha256 -> deb sha256, extracted without root (ar + tar) into <root>/usr/lib/postgresql/18/{bin,lib}, <root>/usr/share/postgresql/18, <root>/usr/lib/sys; see docs/research/2026-10-11-vm-lifecycle/pg-source.md for the 47 per-arch deb pins",
  "pgdgKeyFingerprint": "B97B0AFCAA1A47F044F244A07FCC7D46ACCC4CF8",
  "ubuntuArchiveKeyFingerprint": "F6ECB3762474EDA9D21B7022871920D1991BC93C",
  "debs": {
    "linux/amd64": {"postgresql-18": "2aab00b13babd3d9abc257bc5f6b00efa1f7c27cda071413f358d2e0cdb84420", "postgresql-client-18": "ad4e491adceaf1453162c62691473ace78ed81ab20f50d11b344a793d13ed4bd", "libpq5": "8af0b458834e219f3aa7c904fa1237ea484950486e3165a3a90204878e060530"},
    "linux/arm64": {"postgresql-18": "8a379f0684b480b60e79657ac8178e8b00c835e7575e85ae746c091d336563d3", "postgresql-client-18": "21f1b418621fc9c90785b18ec2d7fe4fd8ff111cc607fc3b3625464fc6e7886b", "libpq5": "fc0d787c9da82bd0146e5e365989f3c92dbb3d73c3a32c62a2e4d56ab90933a6"}
  },
  "glibcFloor": "2.35",
  "icu": "70.1 (unicode collversion 153.112; unused: initdb --locale-provider=builtin --builtin-locale=C.UTF-8, datcollversion 1)",
  "invariant": "Relocatable ONLY with the deb layout kept (<root>/usr/lib/postgresql/18/bin; PostgreSQL resolves share and pkglib relative to that tail) and LD_LIBRARY_PATH=<root>/usr/lib/sys set on the postgres/initdb/pg_dump exec alone, never on the core (it leaks jammy libs into any child: grep under it loaded jammy libpcre2). Timezone files are the HOST's /usr/share/zoneinfo (compiled-in absolute path): check-host requires /usr/share/zoneinfo/UTC. postgres REFUSES -p 0 (GUC minimum 1): the kcp store is unix-socket only (listen_addresses=''), tenant stores lease. Runs as non-root only. Any Ubuntu jammy security update changes the closure pins."
}

Replace the existing embedded-postgres entry ("the host's own binaries ... on PATH") when M2-POSTGRES lands. Its port and root invariants still hold.