How to Install PostgreSQL on Debian 13

When you deploy an application that uses PostgreSQL, you need a running database server and a role that the application can use to connect. Debian 13 Trixie includes PostgreSQL 17 in its default repositories, so you can install it with apt without adding another repository.
This guide explains how to install PostgreSQL on Debian 13, log in to the default database, create roles and databases, and open the server to remote connections when the deployment requires it.
Quick Reference
For a printable quick reference, see the PostgreSQL cheatsheet .
| Task | Command |
|---|---|
| Install PostgreSQL | sudo apt install postgresql |
| Open psql shell | sudo -u postgres psql |
| Create an application role | sudo -u postgres createuser appuser |
| Set the role password | sudo -u postgres psql -c '\password appuser' |
| Create a database | sudo -u postgres createdb --owner=appuser appdb |
| Show clusters and ports | pg_lsclusters |
| Restart the default cluster | sudo systemctl restart postgresql@17-main |
| Show the server version | sudo -u postgres psql -c "SHOW server_version;" |
| Show all databases | \l (inside psql) |
| Show all roles | \du (inside psql) |
Prerequisites
You will need a Debian 13 server and a user with sudo privileges . The default installation accepts connections from the same host only. You can skip the remote access section if your application runs on the database server.
Step 1: Install PostgreSQL from the Debian Archive
The instructions below use PostgreSQL 17 from the Debian repositories. If your application requires another major version, use the PGDG installation method instead.
Start by updating the local package index:
sudo apt updateInstall the PostgreSQL server:
sudo apt install postgresqlThe postgresql package is a metapackage that installs postgresql-17. The contrib extensions, such as pg_trgm and hstore, are already part of postgresql-17. On Debian 13, postgresql-contrib is only a virtual package, so there is nothing extra to install.
On a fresh server, the installation creates a postgres system user and a cluster named main on port 5432. A cluster is a collection of databases managed by one PostgreSQL server process. The service starts automatically.
Check the installed client version:
psql --versionThe version should begin with 17. The minor version and Debian package revision depend on the updates available when you install it. This command shows the client version; we will check the server version after connecting.
Step 2: Verify the Service
PostgreSQL runs under systemd. Confirm the service is active:
systemctl status postgresql● postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; preset: enabled)
Active: active (exited)The active (exited) state is normal for this unit. It manages the PostgreSQL clusters together, while each cluster runs under its own service, such as postgresql@17-main. Check the cluster status with:
pg_lsclustersVer Cluster Port Status Owner Data directory Log file
17 main 5432 online postgres /var/lib/postgresql/17/main /var/log/postgresql/postgresql-17-main.logThe online state means the server is running. Notice that the data directory and log file paths include the major version. The examples below use version 17 and the main cluster. If you installed another version from PGDG, replace 17 with that version and check its port with pg_lsclusters.
Step 3: Connect to PostgreSQL
PostgreSQL on Debian uses peer authentication for Unix socket connections. This checks that the operating system username matches the database role name. The installation creates both a system user and a database superuser named postgres.
Open the psql shell as that system user:
sudo -u postgres psqlThe prompt changes to indicate you are inside the database:
postgres=#The postgres=# prompt means you are connected to the postgres database as a superuser. To check the server version, run:
SELECT version();The result includes the server version, package revision, and build information. On the Debian archive installation, the major version should be 17. Type \q to leave psql and return to your terminal.
Step 4: Create a Role and a Database
Applications should connect with a dedicated role instead of the postgres superuser. We will create a role named appuser and a database named appdb. Replace these names with your own, keeping them consistent in the commands below.
Create the application role:
sudo -u postgres createuser appuserBy default, createuser creates a role that can log in, without superuser, database creation, or role creation privileges.
Create a database owned by the new role:
sudo -u postgres createdb --owner=appuser appdbSet a password so the role can log in over TCP:
sudo -u postgres psql -c '\password appuser'The \password command prompts you to enter the new password twice. It keeps the password out of your shell history and SQL command text. Do not commit application credentials to version control. If you store them in a .env file, add that file to .gitignore.
Connect as the new role from the same host:
psql -h localhost -U appuser -d appdbEnter the password when prompted. Debian already enables scram-sha-256 password authentication for loopback TCP connections, so this works without editing pg_hba.conf. The -h localhost option selects TCP instead of the Unix socket.
Because appuser owns appdb, it can create tables in the default public schema. For more about roles and privileges, see our guide to PostgreSQL user management
. Type \q to return to your terminal.
Step 5: Configure Socket Password Authentication (Optional)
You can skip this step if you connect with -h localhost. Without -h, psql uses a Unix socket, where Debian defaults to peer authentication. To let appuser authenticate with a password over that socket, open pg_hba.conf:
sudo nano /etc/postgresql/17/main/pg_hba.confAdd the following rule above the existing local all all peer rule. PostgreSQL uses the first matching rule, so the order matters:
# TYPE DATABASE USER METHOD
local appdb appuser scram-sha-256Reload PostgreSQL so the changes take effect:
sudo systemctl reload postgresql@17-mainYou can now connect with psql -U appuser -d appdb and enter the password. This rule only changes socket authentication for appuser connecting to appdb; the postgres administrator can still use peer authentication.
Step 6: Allow Remote Connections (Optional)
PostgreSQL listens on localhost by default. To accept connections from other hosts, edit postgresql.conf:
sudo nano /etc/postgresql/17/main/postgresql.confFind the listen_addresses line, remove the leading # if present, and set it to the addresses the server should listen on. The following setting listens on every interface:
listen_addresses = '*'Next, open the authentication configuration:
sudo nano /etc/postgresql/17/main/pg_hba.confAdd a rule that allows the application role to connect to its database from your private subnet. Replace 10.0.0.0/24 with your own subnet, or use a single client address such as 10.0.0.15/32:
host appdb appuser 10.0.0.0/24 scram-sha-256Restart the cluster to apply the listening address change. A reload alone is not enough for listen_addresses:
sudo systemctl restart postgresql@17-mainIf you use UFW and it is already enabled, allow TCP connections from the same source range:
sudo ufw allow proto tcp from 10.0.0.0/24 to any port 5432If you use another firewall or a cloud provider firewall, add the equivalent rule there. Restrict access to the smallest source range your application needs.
Debian enables TLS with a self-signed certificate, and psql uses it by default. The connection is encrypted, but the client does not verify the server’s identity. On an untrusted network, configure a trusted server certificate and connect with sslmode=verify-full, or use an SSH tunnel
.
From the client machine, connect using the server’s address. For example, if the server uses 10.0.0.10:
psql -h 10.0.0.10 -U appuser -d appdbEnter the role password when prompted. If the client does not have psql, install the postgresql-client package on a Debian client first.
Installing Another Version from PGDG
The PostgreSQL Global Development Group repository provides other supported major versions. Use this method instead of Step 1 on a fresh server when you need a version such as PostgreSQL 18.
Update the package index and install postgresql-common:
sudo apt update
sudo apt install postgresql-commonThe package includes a script that sets up the PGDG repository. Run it:
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.shThe script asks you to press Enter before it makes any changes. It adds the signing key and the repository definition, then refreshes the package index.
Install the major version your application requires, for example:
sudo apt install postgresql-18Continue from Step 2, replacing version 17 in the paths and service names with 18. On a fresh server, the new cluster normally uses port 5432.
If PostgreSQL is already installed, installing another major version does not create a cluster for it. Create the cluster manually:
sudo pg_createcluster 18 main --startThe new cluster uses the next free port, normally 5433. Check pg_lsclusters and use the matching version, cluster name, and port.
Installing another version does not migrate your existing databases, and stopping the older cluster does not change the new cluster’s port. Back up your data and plan a migration before replacing an existing installation.
Useful psql Commands
The psql client has its own meta-commands for working with the database:
\llists every database.\c dbnameconnects to another database in the same session.\dtlists tables in the current database.\dulists every role.\dnlists schemas.\dflists functions.\timingtoggles query timing.\?opens the help for meta-commands.\qquits the shell.
Troubleshooting
psql: error: connection to server on socket ... failed
Check pg_lsclusters to see whether the cluster is running and which port it uses. Start the default cluster with sudo systemctl start postgresql@17-main if it is down. If the cluster uses another port, pass it to psql with -p. Check /var/log/postgresql/postgresql-17-main.log if startup fails.
Peer authentication failed
You connected over a Unix socket with an operating system username that does not match the database role. Use sudo -u postgres psql for administration, or psql -h localhost -U appuser -d appdb to connect as the application role with a password. You do not need to change a local rule to use TCP.
Role exists but cannot log in
The role lacks the LOGIN attribute. Grant it with ALTER ROLE appuser LOGIN; from a superuser session.
Port 5432 closed from a remote host
Check the listening address with ss -ltn | grep ':5432'. The output should include the server’s network interface or a wildcard address, rather than only loopback addresses. Confirm the cluster port with pg_lsclusters, then check the host and cloud firewall rules. A pg_hba.conf rejection produces a PostgreSQL error after the connection reaches the server.
Password authentication failed
Check that you are connecting to the intended server, port, database, and role. Review the first matching pg_hba.conf rule and the server log before resetting the password with sudo -u postgres psql -c '\password appuser'. A fresh installation stores passwords as SCRAM hashes, so an MD5 hash is a likely cause only for a role migrated from an older server.
In that case, set the password encryption method before assigning a new password. Open an administrator session:
sudo -u postgres psqlSelect SCRAM for this session:
SET password_encryption = 'scram-sha-256';Then enter the new password through the prompt:
\password appuserThe new password is stored as a SCRAM hash. Type \q to leave the session, then reconnect as appuser.
Conclusion
Once your application can connect, set up regular backups with pg_dump and pg_restore . For configuration options beyond this guide, consult the PostgreSQL 17 documentation .
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page