{"id":4456,"date":"2026-03-25T04:11:41","date_gmt":"2026-03-25T01:11:41","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=4456"},"modified":"2026-04-02T23:55:48","modified_gmt":"2026-04-02T20:55:48","slug":"install-postgresql-rocky-almalinux","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/install-postgresql-rocky-almalinux\/","title":{"rendered":"Install PostgreSQL 17 on RHEL 10 \/ Rocky Linux 10 \/ AlmaLinux 10"},"content":{"rendered":"\n<p>Rocky Linux 10 and RHEL 10 ship with PostgreSQL 16 in the base AppStream, but the PGDG (PostgreSQL Global Development Group) repository has PostgreSQL 17 ready to go. This guide uses the PGDG repo because it gives you the latest upstream release with full control over major version upgrades.<\/p>\n\n\n\n<p>Covered here: installing PostgreSQL 17 from PGDG on Rocky Linux 10 (same steps work on AlmaLinux 10 and RHEL 10), initializing the cluster, enabling remote connections, configuring firewalld and SELinux, and creating your first database. For Debian-based systems, see the guide on <a href=\"https:\/\/computingforgeeks.com\/install-postgresql-on-debian\/\" target=\"_blank\" rel=\"noreferrer noopener\">installing PostgreSQL on Debian<\/a>.<\/p>\n\n\n\n<p><em>Verified working: <strong>March 2026<\/strong> on Rocky Linux 10.1 (kernel 6.12), SELinux enforcing, PostgreSQL 17.9<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Rocky Linux 10, AlmaLinux 10, or RHEL 10 (minimal or server install)<\/li>\n\n\n\n<li>Root or sudo access<\/li>\n\n\n\n<li>Firewall port 5432\/tcp for remote client connections<\/li>\n\n\n\n<li>SELinux in enforcing mode (we won&#8217;t disable it)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Add the PGDG Repository<\/h2>\n\n\n\n<p>Install the PGDG repository RPM for RHEL 10 compatible systems:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y https:\/\/download.postgresql.org\/pub\/repos\/yum\/reporpms\/EL-10-x86_64\/pgdg-redhat-repo-latest.noarch.rpm<\/code><\/pre>\n\n\n\n<p>Rocky Linux 10 no longer uses the traditional dnf module system for PostgreSQL, so there&#8217;s no need to disable a built-in module. The PGDG packages take priority automatically.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install PostgreSQL 17<\/h2>\n\n\n\n<p>Install the server and client packages:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo dnf install -y postgresql17-server postgresql17<\/code><\/pre>\n\n\n\n<p>The install pulls in <code>postgresql17-libs<\/code> as a dependency. Three packages total:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Installed:\n  postgresql17-17.9-1PGDG.rhel10.1.x86_64\n  postgresql17-libs-17.9-1PGDG.rhel10.1.x86_64\n  postgresql17-server-17.9-1PGDG.rhel10.1.x86_64<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Initialize the Database Cluster<\/h2>\n\n\n\n<p>PostgreSQL requires an initial database cluster before it can start. Run the setup script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo \/usr\/pgsql-17\/bin\/postgresql-17-setup initdb<\/code><\/pre>\n\n\n\n<p>You should see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Initializing database ... OK<\/code><\/pre>\n\n\n\n<p>This creates the data directory at <code>\/var\/lib\/pgsql\/17\/data\/<\/code> with the default locale and encoding (UTF-8).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Start and Enable PostgreSQL<\/h2>\n\n\n\n<p>Start the service and enable it to survive reboots:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl enable --now postgresql-17<\/code><\/pre>\n\n\n\n<p>Verify the service is running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl status postgresql-17<\/code><\/pre>\n\n\n\n<p>The output should show active (running):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u25cf postgresql-17.service - PostgreSQL 17 database server\n     Loaded: loaded (\/usr\/lib\/systemd\/system\/postgresql-17.service; enabled; preset: disabled)\n     Active: active (running) since Wed 2026-03-25 04:08:20 EAT\n       Docs: https:\/\/www.postgresql.org\/docs\/17\/static\/<\/code><\/pre>\n\n\n\n<p>Check the exact version from the psql client:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -u postgres \/usr\/pgsql-17\/bin\/psql -c 'SELECT version();'<\/code><\/pre>\n\n\n\n<p>Confirmed PostgreSQL 17.9 compiled with GCC 14.3.1 on Rocky Linux 10:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> PostgreSQL 17.9 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.3.1 20250617 (Red Hat 14.3.1-2), 64-bit<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Enable Remote Connections<\/h2>\n\n\n\n<p>By default, PostgreSQL only listens on localhost. To allow connections from other servers or workstations, edit the main configuration file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/var\/lib\/pgsql\/17\/data\/postgresql.conf<\/code><\/pre>\n\n\n\n<p>Find the <code>listen_addresses<\/code> line and change it to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>listen_addresses = '*'<\/code><\/pre>\n\n\n\n<p>Next, configure client authentication in <code>pg_hba.conf<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo vi \/var\/lib\/pgsql\/17\/data\/pg_hba.conf<\/code><\/pre>\n\n\n\n<p>Add a line at the end to allow password-based connections from any IP (restrict to your subnet in production):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>host    all    all    0.0.0.0\/0    scram-sha-256<\/code><\/pre>\n\n\n\n<p>Set a password for the <code>postgres<\/code> superuser:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -u postgres \/usr\/pgsql-17\/bin\/psql -c \"ALTER USER postgres WITH PASSWORD 'YourSecurePassword';\"<\/code><\/pre>\n\n\n\n<p>Restart PostgreSQL to apply the configuration changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo systemctl restart postgresql-17<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configure the Firewall<\/h2>\n\n\n\n<p>Open port 5432 in firewalld for remote PostgreSQL connections:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo firewall-cmd --permanent --add-port=5432\/tcp\nsudo firewall-cmd --reload<\/code><\/pre>\n\n\n\n<p>Verify the port is open:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo firewall-cmd --list-ports<\/code><\/pre>\n\n\n\n<p>You should see <code>5432\/tcp<\/code> in the output.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">SELinux Configuration<\/h2>\n\n\n\n<p>PostgreSQL from PGDG works with SELinux enforcing out of the box on Rocky Linux 10 because the PGDG packages include the correct file contexts. No <code>setsebool<\/code> commands are needed for the default setup.<\/p>\n\n\n\n<p>If you change the data directory to a non-standard location, you will need to set the correct SELinux context:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo semanage fcontext -a -t postgresql_db_t \"\/custom\/pgdata(\/.*)?\"\nsudo restorecon -Rv \/custom\/pgdata<\/code><\/pre>\n\n\n\n<p>If you change PostgreSQL&#8217;s port from the default 5432, tell SELinux:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo semanage port -a -t postgresql_port_t -p tcp 5433<\/code><\/pre>\n\n\n\n<p>Check for any AVC denials after changes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ausearch -m avc -ts recent<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Create a Database and User<\/h2>\n\n\n\n<p>Connect to the PostgreSQL shell:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -u postgres \/usr\/pgsql-17\/bin\/psql<\/code><\/pre>\n\n\n\n<p>Create a new database and user:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>CREATE DATABASE appdb;\nCREATE USER appuser WITH ENCRYPTED PASSWORD 'AppPass2026';\nGRANT ALL PRIVILEGES ON DATABASE appdb TO appuser;\n\\q<\/code><\/pre>\n\n\n\n<p>List all databases to confirm:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -u postgres \/usr\/pgsql-17\/bin\/psql -l<\/code><\/pre>\n\n\n\n<p>The output shows the new database alongside the defaults:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype\n-----------+----------+----------+-----------------+-------------+-------------\n appdb     | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8\n postgres  | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8\n template0 | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8\n template1 | postgres | UTF8     | libc            | en_US.UTF-8 | en_US.UTF-8<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">RHEL Family Path Reference<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Item<\/th><th>Path \/ Value<\/th><\/tr><\/thead><tbody><tr><td>Binaries<\/td><td><code>\/usr\/pgsql-17\/bin\/<\/code><\/td><\/tr><tr><td>Data directory<\/td><td><code>\/var\/lib\/pgsql\/17\/data\/<\/code><\/td><\/tr><tr><td>Config file<\/td><td><code>\/var\/lib\/pgsql\/17\/data\/postgresql.conf<\/code><\/td><\/tr><tr><td>HBA config<\/td><td><code>\/var\/lib\/pgsql\/17\/data\/pg_hba.conf<\/code><\/td><\/tr><tr><td>Log directory<\/td><td><code>\/var\/lib\/pgsql\/17\/data\/log\/<\/code><\/td><\/tr><tr><td>Service name<\/td><td><code>postgresql-17<\/code><\/td><\/tr><tr><td>Default port<\/td><td>5432\/tcp<\/td><\/tr><tr><td>System user<\/td><td><code>postgres<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>On Ubuntu\/Debian, the paths are different: binaries in <code>\/usr\/lib\/postgresql\/17\/bin\/<\/code>, config in <code>\/etc\/postgresql\/17\/main\/<\/code>, and the service name is just <code>postgresql<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Production Hardening<\/h2>\n\n\n\n<p>A few things to tighten before running in production:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Restrict <code>pg_hba.conf<\/code><\/strong>: Replace <code>0.0.0.0\/0<\/code> with your actual application subnet (e.g., <code>10.0.1.0\/24<\/code>)<\/li>\n\n\n\n<li><strong>Tune <code>shared_buffers<\/code><\/strong>: Set to 25% of total RAM. The default 128 MB is too low for production<\/li>\n\n\n\n<li><strong>Enable WAL archiving<\/strong> for point-in-time recovery<\/li>\n\n\n\n<li><strong>Set up automated backups<\/strong> using <a href=\"https:\/\/computingforgeeks.com\/borgbackup-borgmatic-linux\/\" target=\"_blank\" rel=\"noreferrer noopener\">BorgBackup<\/a>, pg_basebackup, or a full <a href=\"https:\/\/computingforgeeks.com\/postgresql-mariadb-backup-pitr\/\" target=\"_blank\" rel=\"noreferrer noopener\">backup with point-in-time recovery<\/a> strategy<\/li>\n\n\n\n<li><strong>Monitor with pg_stat_statements<\/strong>: Add <code>shared_preload_libraries = 'pg_stat_statements'<\/code> to track slow queries<\/li>\n<\/ul>\n\n\n\n<p>For monitoring your PostgreSQL server alongside the rest of your infrastructure, consider setting up <a href=\"https:\/\/computingforgeeks.com\/install-nagios-rocky-almalinux\/\" target=\"_blank\" rel=\"noreferrer noopener\">Nagios<\/a> or a similar monitoring stack with PostgreSQL-specific checks.<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>Rocky Linux 10 and RHEL 10 ship with PostgreSQL 16 in the base AppStream, but the PGDG (PostgreSQL Global Development Group) repository has PostgreSQL 17 ready to go. This guide uses the PGDG repo because it gives you the latest upstream release with full control over major version upgrades. Covered here: installing PostgreSQL 17 from &#8230; <a title=\"Install PostgreSQL 17 on RHEL 10 \/ Rocky Linux 10 \/ AlmaLinux 10\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/install-postgresql-rocky-almalinux\/\" aria-label=\"Read more about Install PostgreSQL 17 on RHEL 10 \/ Rocky Linux 10 \/ AlmaLinux 10\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":4457,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[461,36301,299,50,37631,73,35910],"tags":[688],"class_list":["post-4456","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-databases","category-almalinux","category-how-to","category-linux-tutorials","category-postgresql","category-rhel","category-rocky-linux","tag-postgresql"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/4456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=4456"}],"version-history":[{"count":4,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/4456\/revisions"}],"predecessor-version":[{"id":165193,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/4456\/revisions\/165193"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/4457"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=4456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=4456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=4456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}