Dev & EngARTICLE

PostgreSQL RPM repository reduces EPEL dependency on RHEL

Devrim Gündüz, maintainer of the official PostgreSQL RPM repository, removed most of the EPEL dependencies in RHEL 8, 9, and 10. PostGIS, pgBackRest, patroni, and dozens of Python tools now install using only PGDG and RHEL's own repositories.

PostgreSQL RPM repository reduces EPEL dependency on RHEL
Image: Roberto Diniz

For years, installing much of the official PostgreSQL RPM repository's packages on RHEL (and its rebuilds, such as Rocky Linux and AlmaLinux) started with dnf install epel-release. PostGIS, pgBackRest, pgcli, patroni, pg_statviz, ora2pg, and dozens of extensions pulled in at least one EPEL dependency.

According to a report by Devrim Gündüz, maintainer of the PostgreSQL RPM repository (PGDG), published on Planet PostgreSQL, this changed over the past few weeks. In RHEL 8, 9, and 10, the GIS stack, the most popular extensions, and nearly all of the project's Python tools now install using only the PGDG repositories and the operating system's own repositories (BaseOS, AppStream, and CRB).

For those who administer databases in enterprise environments, this is an infrastructure change, not a feature change: fewer points of failure, fewer corporate firewall exceptions to open, and a more predictable upgrade path.

Why EPEL became a problem

EPEL (Extra Packages for Enterprise Linux) is maintained by the Fedora community and remains a solid project. The problem, according to Gündüz, is not EPEL's quality, but the structural dependency it created in PostgreSQL's packaging:

EPEL is a great project, and this is not a complaint about it. But relying on it caused us real problems.

Devrim Gündüz, maintainer of the PostgreSQL RPM repository

The friction points listed in the post are specific to those who operate databases in production:

  • Blocked access: many companies only allow the operating system vendor's repository plus PGDG, and do not authorize enabling EPEL due to internal policy.
  • Mismatched lifecycles: EPEL packages are updated, rebuilt with new sonames, or discontinued on EPEL's own schedule, which broke PGDG packages without any change on PostgreSQL's side.
  • Old versions with known CVEs: EPEL 8 and 9 distribute hdf5 versions 1.10 and 1.12, Apache Arrow 8 and 9, and netCDF 4.7 and 4.8, all behind upstream.
  • EPEL 10 by minor release: EPEL 10 follows RHEL 10's minor releases (10.2, 10.3...), which makes it harder to know which EPEL package the user is actually getting.

What changed: GIS, extensions, and Python tools

The largest share of the work was in the geospatial stack. GDAL depended on more than 20 EPEL libraries: hdf4, hdf5, netCDF, cfitsio, freexl, Apache Arrow, libkml, xerces-c, armadillo, libdeflate, GPSBabel, and others. All of them are now packaged by PGDG itself, in more recent upstream versions than the ones EPEL distributed, including Apache Arrow 26, which brought the Parquet driver for GDAL as a bonus.

No GDAL driver was removed in this process, which the post highlights as a contrast with a recent change in RHEL itself. PostGIS versions 3.3 through 3.7, SFCGAL (now compiled against PGDG's own CGAL packages), osm2pgsql, and pointcloud no longer need EPEL on any supported version of RHEL.

Outside of GIS, the list of changes is extensive:

  • pgBackRest now uses libssh2 packaged by PGDG itself (with Fedora's CVE patches), keeping SFTP repositories working without EPEL.
  • pgsodium and pg_pwhash use their own libsodium, libargon2, and libscrypt; as a side effect, pgsodium's ipcrypt functions now also work on RHEL 8 and 9, and pg_pwhash gains scrypt support on RHEL 10.
  • mongo_fdw and postgresbson use mongo-c-driver 1.30 compiled by the repository itself.
  • pg_top and pgmoneta no longer depend on libbsd and cJSON.

Python was, according to Gündüz himself, the most laborious part. On RHEL 8, pgcli, patroni, and other Python tools now run on a Python 3.12 stack built entirely by PGDG. On RHEL 9, the pgcli stack, the typing-extensions used by psycopg 3, and pillow (compiled against its own libimagequant) leave EPEL. On RHEL 10, around 35 Python modules, from boto3 and pydantic to matplotlib and pandas, are now maintained by PGDG, covering pg_statviz, patroni, barman, pgcli, pg_activity, pgldapsync, pghoard, rohmu, and sshtunnel.

How coexistence with EPEL was solved technically

Most of the new libraries are installed under their own prefix, such as /usr/pgdg-hdf5 or /usr/pgdg-libarrow. PGDG packages find these libraries via rpath, without using files in ld.so.conf.d and without appearing in the RPM's provides. In practice, this means the two worlds do not collide: anyone who keeps EPEL enabled continues using EPEL's libraries for whatever they installed from there, while PGDG packages use their own.

On RHEL 10 the solution is different, because a Python module can only exist once in the system. PGDG's python3.12- packages obsolete the equivalent python3- packages from EPEL, and their release numbers start at 42, so that a regular dnf upgrade with both repositories enabled migrates the system to PGDG's packages automatically.

There are two documented caveats worth noting before running the upgrade in production:

  1. python3-snappy goes from EPEL's version 0.7.2 to PGDG's 0.6.1, because PGDG's package carries a higher Epoch, which in RPM takes precedence over the version number.
  2. EPEL packages also obsolete PGDG's equivalent names, up to EPEL's own version; PGDG keeps its RHEL 10 versions always equal to or above EPEL's precisely so that an EPEL update doesn't reverse the choice.

CRB (PowerTools in earlier RHEL versions) is still required as before; this part hasn't changed.

What still depends on EPEL

Not everything left EPEL, and the author's own list is straightforward about why: either the dependency is a project too large to repackage, or it's EPEL-only by nature.

PGDG packageDepends onNote
check_patroni, check_pgactivity, check_pgbackrestnagios-pluginsNagios monitoring
plr, dbt2, dbttoolsRstatistical language
firebird_fdw, libfqFirebirdFirebird database
tds_fdw, pgloaderFreeTDSconnectivity with SQL Server/Sybase
pg_snakeoilClamAVantivirus
pgbadgerperl-Text-CSV_XSlog analysis
postgresql_autodocperl-HTML-Templateautomatic documentation
pgpool-II, pgmemcache (RHEL 10)libmemcached-awesomedistributed cache
pgcopydb (RHEL 10)gcC garbage collector
pgmodeler (RHEL 9)Qt 6visual modeling

Anyone who depends on one of these packages and wants to see it migrate out of EPEL can file the request in the pgdg-packaging/pgdg-rpms repository on GitHub; Gündüz himself asks for feedback there, and the full work is documented in issue 422 of the same repository.

What changes for those running PostgreSQL on production RHEL

This change doesn't alter any PostgreSQL functionality itself, but it reduces the external dependency surface of a stack that, in enterprise environments, usually goes through case-by-case security approval. Three practical effects are worth noting:

  • Less third-party approval: companies that only allow the vendor's repository and PGDG no longer need to negotiate EPEL's approval to install PostGIS, pgBackRest, or Patroni.
  • Less risk of breakage from someone else's lifecycle: since the support libraries now follow PGDG's own release schedule, an EPEL update no longer breaks a PostgreSQL extension out of the blue.
  • Attention to the upgrade on RHEL 10: since PGDG's Python packages replace EPEL's via obsoletes, it's worth reviewing provisioning scripts that pin an exact Python package version (such as the python3-snappy case) before running a mass dnf upgrade.

The angle that remains open concerns those who operate packages not covered by the list above: Firebird, FreeTDS, R, and Qt still pull in EPEL, so a dnf install epel-release remains routine in specific database integration scenarios. For the rest of the more common stack, the external dependency has become the exception, not the rule.

Translated from the Brazilian Portuguese original · Read the original