Databases

Install PostgreSQL on Fedora 45 / 44 (18, 17 or 16)

Fedora packages PostgreSQL itself, so the first decision is whether to use those packages or the PGDG repository from the PostgreSQL project. On Fedora 45 that choice is already made, because PGDG has not published a Fedora 45 tree yet. The distribution packages are also the only path that survives a release upgrade without manual surgery.

Original content from computingforgeeks.com - post 33905

We install PostgreSQL from the default repositories, initialise the cluster and fix the Ident authentication failed error every fresh install hits. Then we open the server to an application subnet and test from a second host.

After that come PGDG on Fedora 44 and its two traps, a major upgrade from 16 to 18, the collation warning after a Fedora 44 to 45 upgrade, and a data directory move with SELinux enforcing. Every command ran in October 2026 on Fedora 45 and Fedora 44 with SELinux in enforcing mode.

Choose a PostgreSQL version

Both releases default to PostgreSQL 18 and ship the two previous majors as versioned packages. Upstream support dates come from the PostgreSQL versioning policy.

PostgreSQL majorFedora 45 packageFedora 44 packageUpstream support ends
18postgresql-server (default)postgresql-server (default)November 2030
17postgresql17-serverpostgresql17-serverNovember 2029
16postgresql16-serverpostgresql16-serverNovember 2028

List the server packages your release offers.

dnf list --available 'postgresql*-server'

Fedora 45 returns the three supported majors plus a development build of the next one.

Available packages
postgresql-server.i686     18.3-12.fc45   fedora
postgresql-server.x86_64   18.3-12.fc45   fedora
postgresql16-server.i686   16.14-5.fc45   fedora
postgresql16-server.x86_64 16.14-5.fc45   fedora
postgresql17-server.i686   17.9-10.fc45   fedora
postgresql17-server.x86_64 17.9-10.fc45   fedora
postgresql19-server.i686   19beta1-6.fc45 fedora
postgresql19-server.x86_64 19beta1-6.fc45 fedora

Leave postgresql19-server alone on anything that holds real data. On Fedora 44 the same query returned 18.6, 17.11 and 16.15 from updates.

Unlike PGDG, Fedora’s packages are not parallel installs. Every server package provides postgresql-server-any and conflicts with the others. All of them use the same postgresql.service unit and the same /var/lib/pgsql/data directory, so asking for 17 next to an installed 18 fails.

Failed to resolve the transaction:
Problem: problem with installed package
  - installed package postgresql-server-18.3-12.fc45.x86_64 conflicts with postgresql-server-any provided by postgresql17-server-17.9-10.fc45.x86_64 from fedora

New servers should take 18. Pick 17 or 16 only when an application or extension is certified for nothing newer, and replace postgresql-server with that package name in the commands below.

Install PostgreSQL server

Install the server and the contrib modules. Contrib carries pg_stat_statements, pgcrypto and amcheck, which most production setups end up loading.

sudo dnf install -y postgresql-server postgresql-contrib

Its client comes in as a dependency.

Installing:
 postgresql-contrib      x86_64 0:18.3-12.fc45   fedora       3.6 MiB
 postgresql-server       x86_64 0:18.3-12.fc45   fedora      32.1 MiB
Installing dependencies:
 libxslt                 x86_64 0:1.1.43-10.fc45 fedora     471.8 KiB
 postgresql              x86_64 0:18.3-12.fc45   fedora       8.3 MiB
 postgresql-private-libs x86_64 0:18.3-12.fc45   fedora     379.9 KiB
 uuid                    x86_64 0:1.6.2-70.fc45  fedora     128.4 KiB

Fedora does not create a cluster at install time. Initialise it with the packaged helper, which runs initdb with the right paths, SELinux labels and log directory.

sudo postgresql-setup --initdb

It reports where the cluster and its log went.

 * Initializing database in '/var/lib/pgsql/data'
 * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log

Start the service and enable it at boot.

sudo systemctl enable --now postgresql

Then confirm the unit is running and ask the server for its version.

systemctl status postgresql --no-pager
sudo -u postgres psql -c 'SELECT version();'

Those three io worker processes are new in 18. They are the default asynchronous I/O method, so seeing them is expected.

PostgreSQL 18 service active on Fedora 45 with io worker processes and the version query output

A new cluster uses UTF8, stores passwords as scram-sha-256, keeps data in /var/lib/pgsql/data and listens on localhost only. Data checksums are on by default from 18, which matters later during upgrades.

Create a database and fix “Ident authentication failed”

Create an application role with a password, then a database it owns. createuser prompts for the password twice.

sudo -u postgres createuser --pwprompt appuser
sudo -u postgres createdb -O appuser appdb

Now try to log in as that role, first over the socket and then over TCP.

psql -U appuser -d appdb -c 'SELECT 1;'
psql -h 127.0.0.1 -U appuser -d appdb -c 'SELECT 1;'

Neither works. Both errors confuse anyone who has not read the default Fedora pg_hba.conf.

psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL:  Peer authentication failed for user "appuser"
psql: error: connection to server at "127.0.0.1", port 5432 failed: FATAL:  Ident authentication failed for user "appuser"

Below is the same session in the terminal, with the matching server log lines.

psql on Fedora failing with Peer authentication failed and Ident authentication failed for a new PostgreSQL role

The server log names the culprit. postgresql-setup runs initdb --auth=ident, so local socket logins use peer and TCP logins on localhost use ident.

sudo grep -Ev '^#|^$' /var/lib/pgsql/data/pg_hba.conf

Out of the box the file holds six rules.

local   all             all                                     peer
host    all             all             127.0.0.1/32            ident
host    all             all             ::1/128                 ident
local   replication     all                                     peer
host    replication     all             127.0.0.1/32            ident
host    replication     all             ::1/128                 ident

peer only lets an operating system user in as the database role of the same name. That’s why sudo -u postgres psql works.

ident asks an identd daemon on port 113, and Fedora does not run one, so it always fails. Keep peer on the socket for administration and switch the TCP rules to passwords.

sudo sed -i -E '/^host/ s/ident$/scram-sha-256/' /var/lib/pgsql/data/pg_hba.conf

A reload or restart applies the change. We restart in the next section anyway, so the login test follows there.

Allow remote connections

Two settings control remote access. listen_addresses decides which interfaces the server binds to, and pg_hba.conf decides who may log in.

Add a rule for the application subnet first. It only admits appuser to appdb.

echo 'host    appdb           appuser         10.0.1.0/24             scram-sha-256' | sudo tee -a /var/lib/pgsql/data/pg_hba.conf

Set listen_addresses with ALTER SYSTEM instead of editing postgresql.conf. It lands in postgresql.auto.conf, which is easy to audit. Changing it needs a restart.

sudo -u postgres psql -c "ALTER SYSTEM SET listen_addresses = '*';"
sudo systemctl restart postgresql

Check the rules as the server parsed them. A typo shows up in the error column instead of silently locking people out.

sudo -u postgres psql -c 'SELECT type, database, user_name, address, netmask, auth_method, error FROM pg_hba_file_rules;'

All seven rules loaded, and the error column is empty.

 type  |   database    | user_name |  address  |                 netmask                 |  auth_method  | error
-------+---------------+-----------+-----------+-----------------------------------------+---------------+-------
 local | {all}         | {all}     |           |                                         | peer          |
 host  | {all}         | {all}     | 127.0.0.1 | 255.255.255.255                         | scram-sha-256 |
 host  | {all}         | {all}     | ::1       | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | scram-sha-256 |
 local | {replication} | {all}     |           |                                         | peer          |
 host  | {replication} | {all}     | 127.0.0.1 | 255.255.255.255                         | scram-sha-256 |
 host  | {replication} | {all}     | ::1       | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | scram-sha-256 |
 host  | {appdb}       | {appuser} | 10.0.1.0  | 255.255.255.0                           | scram-sha-256 |
(7 rows)

Confirm the listener moved off localhost and that a password login over TCP now works.

ss -tln | grep 5432
psql -h 127.0.0.1 -U appuser -d appdb -c 'SELECT current_user, inet_server_addr();'

Now the server binds every IPv4 and IPv6 address, and appuser gets in with its password.

LISTEN 0      200          0.0.0.0:5432      0.0.0.0:*
LISTEN 0      200             [::]:5432         [::]:*
 current_user | inet_server_addr
--------------+------------------
 appuser      | 127.0.0.1
(1 row)

Open port 5432 in firewalld

What the firewall does depends on the Fedora edition. The Workstation zone, FedoraWorkstation, already allows ports 1025 to 65535, so 5432 is reachable the moment PostgreSQL listens on it.

On Fedora Server, the FedoraServer zone doesn’t open that range. On Server, --get-default-zone prints FedoraServer.

Cloud images ship without firewalld at all, so either rely on the provider security group or install it. The public zone keeps SSH on port 22 open, so enabling it won’t lock you out. If sshd listens on a different port, add that port first. On a Cloud image, run this.

sudo dnf install -y firewalld
sudo systemctl enable --now firewalld

Check the active zone and what it allows.

sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-services

On our Cloud-based test server, only SSH, mDNS and DHCPv6 were allowed.

public
dhcpv6-client mdns ssh

From the application host app01 (10.0.1.51), a connection to the server at 10.0.1.50 is rejected. “No route to host” is what a firewalld reject looks like from the client side. It is not a routing problem.

psql: error: connection to server at "10.0.1.50", port 5432 failed: No route to host
	Is the server running on that host and accepting TCP/IP connections?

firewalld ships a postgresql service definition. Add it permanently and reload.

sudo firewall-cmd --permanent --add-service=postgresql
sudo firewall-cmd --reload

Adding the service opens 5432 to the whole zone, and only pg_hba.conf narrows it. To admit just the application subnet at the firewall as well, replace the service with a rich rule.

sudo firewall-cmd --permanent --remove-service=postgresql
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.1.0/24" service name="postgresql" accept'
sudo firewall-cmd --reload

On Workstation the port is already open, so tighten instead. Bind listen_addresses to the one interface the application uses, or move that interface to a stricter zone. The firewalld guide covers zones and rich rules.

Run the test again from app01. It only needs the client package, sudo dnf install -y postgresql.

psql -h 10.0.1.50 -U appuser -d appdb -c 'SELECT current_user, inet_client_addr(), version();'

Our server sees the client address and answers.

 current_user | inet_client_addr |                                                   version
--------------+------------------+--------------------------------------------------------------------------------------------------------------
 appuser      | 10.0.1.51        | PostgreSQL 18.3 on x86_64-redhat-linux-gnu, compiled by gcc (GCC) 16.2.1 20260819 (Red Hat 16.2.1-2), 64-bit
(1 row)

Our pg_hba.conf rule is scoped to one database, so the same user asking for postgres is refused. Expect this error whenever a rule is missing.

psql: error: connection to server at "10.0.1.50", port 5432 failed: FATAL:  no pg_hba.conf entry for host "10.0.1.51", user "appuser", database "postgres", no encryption

“no encryption” means the session would be plain text. For anything that leaves the host, add TLS with the PostgreSQL SSL guide and switch the rule type from host to hostssl.

Use the PGDG repository instead

PGDG publishes every minor release on the day it ships. It installs each major side by side, under /usr/pgsql-18 with its own postgresql-18 unit and /var/lib/pgsql/18/data, and it carries extension builds Fedora does not.

On Fedora 45 it isn’t an option yet. Its repository package URL returns 404.

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/F-$(rpm -E %fedora)-x86_64/pgdg-fedora-repo-latest.noarch.rpm

Fedora 45 gets nothing back.

Failed to download files
 Librepo error: Status code: 404 for https://download.postgresql.org/pub/repos/yum/reporpms/F-45-x86_64/pgdg-fedora-repo-latest.noarch.rpm

That same command works on Fedora 44 and adds one repository per major from 14 to 18. Before installing anything from it, exclude PostgreSQL from the Fedora repositories.

sudo dnf config-manager setopt fedora.excludepkgs='postgresql*' updates.excludepkgs='postgresql*'

Skip that line and you hit two problems. The Fedora postgresql-server also provides postgresql18-server, and the Fedora client package obsoletes the PGDG postgresql18.

On a host that already has the Fedora psql, dnf install postgresql18-server quietly installs the Fedora server and skips PGDG.

Installing:
 postgresql-server   x86_64 0:18.6-1.fc44  updates     32.2 MiB
Skipping packages with broken dependencies:
 postgresql18-server x86_64 18.6-4PGDG.f44 pgdg18      31.1 MiB

It gets worse in reverse. On a working PGDG server, installing the Fedora postgresql client, directly or as another package’s dependency, replaces the PGDG server binaries.

Installing:
 postgresql                       x86_64 0:18.6-1.fc44    updates      8.4 MiB
   replacing postgresql18         x86_64 0:18.6-4PGDG.f44 pgdg18      11.1 MiB
 postgresql-contrib               x86_64 0:18.6-1.fc44    updates      3.6 MiB
   replacing postgresql18-contrib x86_64 0:18.6-4PGDG.f44 pgdg18       2.7 MiB
 postgresql-server                x86_64 0:18.6-1.fc44    updates     32.2 MiB
   replacing postgresql18-server  x86_64 0:18.6-4PGDG.f44 pgdg18      31.1 MiB

With the exclude in place, install and initialise the PGDG build. Its setup script and unit names carry the major version.

sudo dnf install -y postgresql18-server postgresql18-contrib
sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
sudo systemctl enable --now postgresql-18

Ask the server for its version with sudo -u postgres psql -c 'SELECT version();'. You’ll see x86_64-pc-linux-gnu for the PGDG build, where Fedora’s says redhat-linux-gnu.

 PostgreSQL 18.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 16.2.1 20260819 (Red Hat 16.2.1-2), 64-bit

Remember what you signed up for when it’s time to upgrade Fedora 44 to 45. The PGDG repositories are skipped as unavailable, and the transaction stops on a PGDG package linked against the Fedora 44 Perl library.

Failed to resolve the transaction:
Problem: installed package postgresql18-contrib-18.6-4PGDG.f44.x86_64 requires libperl.so.5.42()(64bit), but none of the providers can be installed
  - perl-libs-4:5.42.3-525.fc44.x86_64 does not belong to a distupgrade repository

A PGDG host stays on Fedora 44 until PGDG publishes fedora-45-x86_64, or until you move it to the Fedora packages with a dump and restore. Check https://download.postgresql.org/pub/repos/yum/18/fedora/ for that directory before planning the upgrade.

Upgrade PostgreSQL 16 or 17 to 18

Fedora handles major upgrades with postgresql-setup --upgrade, which wraps pg_upgrade. The old binaries come from postgresql-upgrade, which bundles the 16 and 17 engines.

Our test server ran postgresql16-server with a 100,000 row table. Take a pg_dumpall first. The PostgreSQL backup and PITR guide covers the full approach. Then stop the server and swap packages.

sudo systemctl stop postgresql
sudo dnf swap -y postgresql16-server postgresql-server --allowerasing
sudo dnf install -y postgresql-upgrade postgresql-contrib

Swapping removes the old contrib package and disables the service. The scriptlet says so.

>>> Running %post scriptlet: postgresql-server-0:18.3-12.fc45.x86_64
>>> Finished %post scriptlet: postgresql-server-0:18.3-12.fc45.x86_64
>>> Scriptlet output:
>>> Removed '/etc/systemd/system/multi-user.target.wants/postgresql.service'.

List the upgrade sources. The ID for 16 is postgresql16, and plain postgresql means 17.

sudo postgresql-setup --upgrade-ids

Two sources are available.

postgresql - Upgrade data from system PostgreSQL version (PostgreSQL 17)
postgresql16 - Upgrade data from system PostgreSQL version (PostgreSQL 16)

The obvious command fails on any cluster created before 18. New clusters get data checksums by default, and pg_upgrade will not mix the two.

postgresql-setup upgrade from PostgreSQL 16 to 18 on Fedora failing on data checksums, then succeeding with the data-checksums flag

Pass --data-checksums to enable them on the old cluster before the upgrade, or --no-data-checksums to keep them off. Enabling them reads and rewrites every data page.

It took seconds on our test set, but it scales with database size. Checksums catch silent storage corruption, so take the time unless the maintenance window cannot absorb it.

sudo postgresql-setup --upgrade --upgrade-from=postgresql16 --data-checksums

Read the warning it prints. The upgrade installs fresh postgresql.conf and pg_hba.conf files and leaves yours in /var/lib/pgsql/data-old. Bring your access rules back before starting the service, or remote clients lose access.

listen_addresses was set with ALTER SYSTEM, so it lives in postgresql.auto.conf, not postgresql.conf. Copy both files, then review postgresql.auto.conf for parameters the new major no longer accepts.

sudo -u postgres cp /var/lib/pgsql/data-old/pg_hba.conf /var/lib/pgsql/data-old/postgresql.auto.conf /var/lib/pgsql/data/

Edits made directly in the old postgresql.conf need the same treatment. Compare it with diff against the new file and carry the changes over by hand. Then enable the service again and rebuild planner statistics, which pg_upgrade does not carry over in full.

sudo systemctl enable --now postgresql
sudo -u postgres vacuumdb --all --analyze-in-stages --missing-stats-only

Our upgraded server reported 18.3 with checksums on, and all 100,000 rows were present. Once the application has run cleanly for a while, run /var/lib/pgsql/delete_old_cluster.sh as postgres to reclaim the space held by data-old.

Fix the collation version mismatch after Fedora 45

Fedora 44 and 45 both default to PostgreSQL 18, so a release upgrade needs no pg_upgrade. It does change glibc from 2.43 to 2.44, and PostgreSQL records the glibc version each database was created with.

We put a Fedora 44 server holding a database with 50,000 rows and a text index through dnf system-upgrade. On that day, the Fedora 45 repository carried 18.3 while Fedora 44 updates had 18.6, so the transaction listed the server under “Downgrading”.

Minor releases share the on-disk format, and the cluster came up without complaint. sudo dnf upgrade moves it forward again once newer builds reach Fedora 45.

Your first connection to each database after the reboot prints a warning.

WARNING:  database "shop" has a collation version mismatch
DETAIL:  The database was created using collation version 2.43, but the operating system provides version 2.44.
HINT:  Rebuild all objects in this database that use the default collation and run ALTER DATABASE shop REFRESH COLLATION VERSION, or build PostgreSQL with the right library version.

Don’t treat that warning as noise. If glibc changed the sort order of any characters in your data, B-tree indexes on text columns are now ordered differently from what the server expects.

Lookups can then miss rows that exist, and unique constraints can let duplicates through. Rebuild the indexes in every database, then record the new version.

sudo -u postgres reindexdb --all
for db in $(sudo -u postgres psql -Atc 'SELECT datname FROM pg_database WHERE datallowconn' 2>/dev/null); do sudo -u postgres psql -qc "ALTER DATABASE \"$db\" REFRESH COLLATION VERSION;" 2>&1 | grep -v -e WARNING -e DETAIL -e HINT; done

Each database reports the version change, and the stored and actual versions match afterwards.

PostgreSQL collation version mismatch warning after upgrading Fedora 44 to 45, fixed with reindexdb and REFRESH COLLATION VERSION

reindexdb takes locks that block writes to each table while its indexes rebuild. On a large database, schedule it, or use reindexdb --all --concurrently. That avoids the write lock, but it skips system catalogs and takes longer.

Indexes are the usual casualty, but the PostgreSQL docs ask for every object that depends on the collation to be rebuilt. That includes text range or list partition keys, CHECK constraints that compare strings, and materialized views.

Don’t just run REFRESH COLLATION VERSION to silence the warning. It only updates the stored number, and any misordered index stays broken.

Move the data directory with SELinux enforcing

Moving the cluster to a dedicated disk is common, and SELinux is where it goes wrong. The service reads PGDATA from its unit, so point it there with a drop-in after copying the data.

sudo systemctl stop postgresql
sudo mkdir -p /srv/pgsql
sudo cp -a /var/lib/pgsql/data /srv/pgsql/
sudo mkdir -p /etc/systemd/system/postgresql.service.d
printf '[Service]\nEnvironment=PGDATA=/srv/pgsql/data\n' | sudo tee /etc/systemd/system/postgresql.service.d/datadir.conf
sudo systemctl daemon-reload
sudo systemctl start postgresql

It starts, and that’s the trap. cp -a copied the postgresql_db_t label along with the files, but the policy has no rule for /srv/pgsql. The next restorecon or full relabel resets the files to var_t, and the following restart fails.

postgres: could not access the server configuration file "/srv/pgsql/data/postgresql.conf": Permission denied
postgresql.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
postgresql.service: Failed with result 'exit-code'.

Make the label permanent by declaring /srv/pgsql equivalent to /var/lib/pgsql. semanage comes from policycoreutils-python-utils, which minimal installs lack.

sudo dnf install -y policycoreutils-python-utils
sudo semanage fcontext -a -e /var/lib/pgsql /srv/pgsql
sudo restorecon -R /srv/pgsql
sudo systemctl restart postgresql

Our equivalence rule survives relabels. Confirm it, and confirm the server runs from the new path.

sudo semanage fcontext -l -C
sudo -u postgres psql -Atc 'SHOW data_directory;'

Both checks agree.


SELinux Local fcontext Equivalence 

/srv/pgsql = /var/lib/pgsql
/srv/pgsql/data

Remove /var/lib/pgsql/data only after a restart from the new location has worked. postgresql-setup --upgrade reads the same PGDATA, so the drop-in also covers the next major upgrade.

From here, this single server is the base for most of what follows. Add vector search with pgvector, or build out PostgreSQL high availability with Patroni, etcd and HAProxy when one node isn’t enough.

For a GUI, pgAdmin in Podman runs well on the same Fedora host. If the application needs MySQL compatibility instead, see MariaDB on Fedora.

Keep reading

How to Upgrade Fedora 44 to Fedora 45 (GUI, CLI and Rollback) Fedora How to Upgrade Fedora 44 to Fedora 45 (GUI, CLI and Rollback) Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Fedora Enable RPM Fusion and Install Multimedia Codecs on Fedora 45 / 44 / 43 Harden Fedora 45 / 44 for Desktop and Server: Complete Guide Fedora Harden Fedora 45 / 44 for Desktop and Server: Complete Guide Switch Fedora From GRUB to systemd-boot With bootctl Fedora Switch Fedora From GRUB to systemd-boot With bootctl DNF5 Cheatsheet for Fedora 45 / 44: Tested Commands and Fixes Fedora DNF5 Cheatsheet for Fedora 45 / 44: Tested Commands and Fixes How To Install PostgreSQL 15 on CentOS 7 / RHEL 7 Databases How To Install PostgreSQL 15 on CentOS 7 / RHEL 7

Leave a Comment

Press ESC to close