You installed the package but the database won't accept connections
You run sudo dnf install postgresql-server and the terminal spits out a success message. You try to connect with psql and get could not connect to server: Connection refused. You check the service status and see it is inactive. You feel like you missed a step, but the package manager said it was done. This is the standard PostgreSQL installation pattern on Fedora. The package manager drops the binaries and configuration templates. It deliberately leaves the database cluster uninitialized until you explicitly tell it to proceed.
What the installation actually leaves behind
PostgreSQL separates the software installation from the data initialization. The postgresql-server package contains the postgres daemon, the psql client, and the default configuration templates. It does not create the data directory. The data directory holds the actual database files, the system catalogs, and the authentication rules. Fedora treats this separation as a security and flexibility feature. You get to choose where the data lives, what the default encoding is, and whether you want to enable case-sensitive identifiers before the first byte of user data touches the disk.
Think of the package installation like buying a filing cabinet. The dnf install command delivers the empty metal frame and the instruction manual. The initialization step is where you install the drawers, label the folders, and set the combination lock. You cannot store files until the drawers exist.
Fedora also follows the standard Linux convention for service management. The postgresql systemd unit is disabled by default. This prevents the database from starting automatically on a fresh install, which saves resources on servers that might only need PostgreSQL occasionally or might need configuration tweaks before going live. The configuration files ship in /usr/lib/pgsql/data/ as read-only templates. You should never edit files in /usr/lib/. Any custom configuration belongs in /var/lib/pgsql/data/ after initialization, or in /etc/ if the package provides a drop-in directory. PostgreSQL overrides the standard Linux /etc convention here because the database engine reads its configuration directly from the data directory at startup.
Run the initialization before you touch systemd. The daemon will refuse to start without a valid data directory.
Initialize the cluster and start the service
Here is how to create the data directory and bring the service online. Run these commands in order. The initialization step must complete before systemd can start the daemon.
sudo dnf install postgresql postgresql-server
# Install the client tools and the server daemon. The client tools are required for psql and createuser.
sudo postgresql-setup --initdb
# Creates the /var/lib/pgsql/data directory, generates system catalogs, and sets default locale and encoding.
sudo systemctl enable --now postgresql
# Registers the service to start on boot and launches it immediately.
The postgresql-setup script is a Fedora-specific wrapper around the upstream initdb binary. It handles the correct ownership permissions for the postgres user and points to the default Fedora data path. If you ever need to move the data directory to a separate mount point, you would run initdb manually with the -D flag instead. The wrapper also applies Fedora's default shared_buffers and work_mem settings, which are tuned for typical desktop and small server workloads.
After the service starts, check the state before assuming it is ready. Systemd units sometimes mask or fail silently if a port is already bound.
systemctl status postgresql
# Shows the active state, recent log lines, and the main PID. Always check status before restarting.
You should see Active: active (running) in green. If the unit shows failed, run journalctl -xeu postgresql to read the exact failure reason. The x flag adds explanatory context and the e flag jumps to the end of the journal. Most boot failures trace back to a missing data directory or a permission mismatch. The u flag scopes the output to the specific unit, which saves you from scrolling through unrelated kernel messages.
Run systemctl status first. Read the actual state before guessing at the cause.
Create your first application user
PostgreSQL does not use the Linux root account for database administration. It uses a dedicated system user named postgres that maps to the database superuser. You must switch to this user to create roles and databases. Direct root access to the database cluster is intentionally blocked. This separation prevents accidental privilege escalation and keeps database permissions independent from operating system permissions.
Here is how to create a new role with the ability to create databases. This is the standard pattern for application accounts.
sudo -u postgres createuser --createdb --interactive
# Switches to the postgres system user and runs the role creation utility.
# The --createdb flag grants the new role permission to create databases.
# The --interactive flag prompts for the role name and password confirmation.
The interactive prompt will ask for the role name, then whether the role should be a superuser, and whether it can create databases or roles. Answer n to superuser unless you are building a test environment. Production applications should run with the least privileges required. The --createdb flag is enough for most deployment scripts. The utility will also prompt you to set a password. Store that password securely. PostgreSQL uses scram-sha-256 by default, which means passwords are hashed and never stored in plaintext.
After creating the role, you can create a database owned by that role.
sudo -u postgres createdb --owner=<your_new_role> myapp_db
# Creates the database schema and assigns ownership to the role you just created.
PostgreSQL stores authentication rules in /var/lib/pgsql/data/pg_hba.conf. The default Fedora configuration uses peer authentication for local connections and scram-sha-256 for remote TCP connections. This means the postgres system user can log in without a password over Unix sockets, but any network connection will require the password you set during createuser.
Create the role before you attach it to a database. Ownership cannot be assigned to a non-existent role.
Verify the connection and check the logs
Test the connection using the psql client. This confirms the service is listening, the authentication rules are working, and the new role can access the database.
sudo -u postgres psql -d myapp_db -c "SELECT current_user, current_database();"
# Connects to the target database and runs a quick query to verify the active role and database name.
The output should list your new role name and myapp_db. If you get FATAL: password authentication failed for user, check your pg_hba.conf file. The configuration lives in /var/lib/pgsql/data/, not in /etc/. PostgreSQL overrides the standard Linux convention here. The data directory contains the runtime configuration. Any edits to pg_hba.conf or postgresql.conf require a service reload to take effect.
sudo systemctl reload postgresql
# Applies configuration changes without dropping active connections. Always reload after editing pg_hba.conf.
If the connection succeeds but your application still cannot reach the database, verify the listening address. The default Fedora configuration binds to localhost only. Remote applications will need the listen_addresses parameter updated in postgresql.conf and a corresponding host entry in pg_hba.conf. Remember to run firewall-cmd --reload after opening port 5432 in the firewall. Otherwise the runtime config and the persistent config diverge, and your application will hang on connection attempts.
Test the connection from the same machine before opening ports to the network. Local verification isolates configuration errors from firewall rules.
Common pitfalls and what the error looks like
The most common failure happens when users skip the initialization step and try to start the service immediately. Systemd will refuse to launch the daemon and the journal will show a clear refusal.
postgresql.service: Main process exited, code=exited, status=1/FAILURE
postgresql-setup: error: data directory is not initialized
Run sudo postgresql-setup --initdb to fix it. The service will start normally on the next systemctl start command.
Another frequent issue involves authentication mismatches. You create a role with a password, but psql still asks for a password even when running as the postgres user. This happens because pg_hba.conf prioritizes peer authentication for local Unix socket connections. The peer method trusts the operating system user and ignores database passwords. Switch to the postgres system user with sudo -u postgres to bypass the password prompt, or change the local line in pg_hba.conf to scram-sha-256 if you want password authentication for local connections.
Port conflicts also cause silent failures. If another service is already bound to port 5432, PostgreSQL will fail to bind and exit. Check for conflicting services with ss -tlnp | grep 5432. Stop the conflicting service or change the PostgreSQL port in postgresql.conf before restarting. SELinux denials occasionally block non-standard ports. Check journalctl -t setroubleshoot for a one-line summary before disabling SELinux. The audit log usually points to a missing boolean or a port labeling issue that can be fixed with semanage port.
Check the journal before editing configuration files. Half the time the symptom is a missing dependency or a bound port, not a broken config.
When to use this vs alternatives
Use the default Fedora PostgreSQL package when you need a stable, security-patched database server managed by systemd. Use postgresql-setup --initdb when you want the standard Fedora data layout and default configuration templates. Use manual initdb with custom flags when you need a specific locale, encoding, or data directory path that differs from the defaults. Use pg_hba.conf peer authentication for local administrative tasks and scram-sha-256 for application connections. Use systemctl reload after configuration changes and systemctl restart only when you need to apply parameter changes that require a full daemon restart. Use dnf upgrade --refresh for weekly maintenance and dnf system-upgrade when crossing major Fedora releases. Trust the package manager. Manual file edits drift, snapshots stay.