Choosing the Right PostgreSQL Deployment Method
Setting up a database server on Fedora isn’t just about running an install command. Depending on your needs for stability versus new features, I usually consider these three approaches:
| Method | Pros | Cons |
|---|---|---|
| AppStream (Default) | High stability, perfect SELinux compatibility. | Versions are usually 6 months to a year behind upstream. |
| PGDG Repo (Official) | Instant updates for patches and the latest features. | Requires manual repo management; can cause conflicts if misconfigured. |
| Podman (Container) | Excellent isolation, runs multiple versions side-by-side. | I/O performance may drop by 3-5% due to the network virtualization layer. |
After two years of running Fedora for real-world projects, I prefer the PGDG Repo. This method gives you early access to improvements like JSONB or Logical Replication without the wait. Here is a production deployment process that ensures both performance and security.
Step 1: Installing from the Official Repository
Fedora comes with a default PostgreSQL module. To avoid any version conflicts, you need to disable this module before adding the repo from the official PostgreSQL site.
# Disable the default module to avoid conflicts
sudo dnf -qy module disable postgresql
# Add PGDG Repo for Fedora
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/F-$(rpm -E %fedora)-x86_64/pgdg-fedora-repo-latest.noarch.rpm
# Install version 16 (currently the most stable)
sudo dnf install -y postgresql16-server postgresql16-contrib
Once installed, initialize the database cluster. This command sets up the directory structure and necessary system files.
sudo /usr/pgsql-16/bin/postgresql-16-setup initdb
Step 2: Configuring Firewalld – Opening Ports Only When Necessary
Fedora Server is very strict with port management. Instead of opening port 5432 to the entire network, only allow trusted IPs (such as your App Server) to access it.
# Secure method: Only allow IP 10.0.0.5 (e.g., your Web Server)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" port protocol="tcp" port="5432" accept'
# If used within a trusted local network
sudo firewall-cmd --add-service=postgresql --permanent
sudo firewall-cmd --reload
Step 3: Mastering SELinux Instead of Disabling It
Many administrators choose to disable SELinux to avoid “Permission Denied” errors. This is a major security mistake. If you move the data storage to another drive (e.g., /mnt/data/postgres), SELinux will block the service due to incorrect labels.
Use the following commands to assign the correct labels, allowing PostgreSQL to run smoothly while remaining secure:
# Assign security labels to the new data directory
sudo semanage fcontext -a -t postgresql_db_t "/mnt/data/postgres(/.*)?"
sudo restorecon -Rv /mnt/data/postgres
If the application needs to send email notifications or connect externally, you need to enable this permission:
sudo setsebool -P postgresql_can_network_connect 1
Step 4: Configuring Secure Remote Access
The default configuration file only allows local connections. You need to adjust it so the server listens for external connections while ensuring encryption.
1. Editing postgresql.conf
Change localhost to * to listen on all network interfaces:
listen_addresses = '*'
2. Configuring Authentication in pg_hba.conf
Never use trust or password (plaintext). Use scram-sha-256 to protect login credentials.
# Allow internal IP range access with strong encrypted passwords
host all all 10.0.0.0/24 scram-sha-256
Enable the service to apply changes:
sudo systemctl enable --now postgresql-16
Optimization Experience from Operations
After some time managing these systems, I’ve found that a few small tweaks can make a big difference in performance:
- Leverage Huge Pages: For servers with over 16GB of RAM, set
huge_pages = try. This reduces CPU memory management overhead, speeding up queries by about 10-15%. - Log Management: PostgreSQL can generate tens of gigabytes of log files if left unchecked. Configure
log_rotation_age = 1dandlog_rotation_size = 100MBto prevent the disk from filling up unexpectedly. - Troubleshooting: If the database fails to start, instead of guessing, run
journalctl -u postgresql-16or check SELinux logs usingausearch -m avc -ts recent.
Deploying PostgreSQL on Fedora requires attention to detail regarding SELinux and Firewalld. However, once configured correctly, you will have an extremely robust system capable of handling critical production applications.

