PostgreSQL: install and configure
In this article you'll install PostgreSQL on your mHost VPS, enable it as a systemd service, create a dedicated role and database, learn the basic psql commands, and configure access to the server — local and, if needed, remote — via pg_hba.conf, listen_addresses, and the firewall.
What you'll need
- An mHost VPS running Ubuntu 22.04/24.04, Debian 11/12, or AlmaLinux/Rocky Linux 8/9.
- SSH access as root or a user with sudo.
- The IP address of the computer or server you'll connect from remotely — only needed if you want access to the database from outside this VPS (the "Remote access" section in step 5).
Step 1. Install PostgreSQL
Ubuntu / Debian
apt update
apt install postgresqlapt installs the version pinned to your distro release — for example, PostgreSQL 14 on Ubuntu 22.04, 16 on Ubuntu 24.04, 13 on Debian 11, 15 on Debian 12. That's enough for most needs.
Check the installation:
psql --versionIf you need a specific, newer version than your distro's repository offers, add the official PGDG apt repository:
apt install -y postgresql-common ca-certificates
/usr/share/postgresql-common/pgdg/apt.postgresql.org.shThe script shows what it's about to do and asks for confirmation — accept it. Then install the version you need:
apt update
apt install postgresql-16Replace 16 with the version you need.
AlmaLinux / Rocky Linux
dnf install postgresql-serverThe AppStream version often lags behind current PostgreSQL releases. To see which version is the default (and which others are available), run:
dnf module list postgresqlFor a specific, newer version, add the official PGDG repository instead of using AppStream (example for AlmaLinux/Rocky Linux 9 — for version 8, replace EL-9 with EL-8 in the URL):
dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
dnf -qy module disable postgresql
dnf install -y postgresql16-serverReplace 16 with the version you need in the package name and in every path and service name later in this article.
Step 2. Enable and start PostgreSQL via systemd
AlmaLinux / Rocky Linux: initialize the cluster first
Unlike Debian/Ubuntu, the RPM package doesn't create a database cluster automatically — you need to initialize the data directory first.
For the AppStream package (postgresql-server):
postgresql-setup --initdb
systemctl enable --now postgresqlFor a versioned PGDG package (replace 16 with your version):
/usr/pgsql-16/bin/postgresql-16-setup initdb
systemctl enable --now postgresql-16Ubuntu / Debian
The package already creates a cluster (named main by default) and enables and starts its systemd service during installation, so this step usually just confirms the state:
systemctl enable --now postgresqlCheck that the server is accepting connections:
pg_isreadyThe expected output ends with accepting connections.
Step 3. Connect and create a role and a database
On install, PostgreSQL creates a system user named postgres and a matching superuser role inside the database. Local connections use peer authentication by default: it matches your OS system user against the PostgreSQL role name, so you can only log in as the postgres system user — and without a password:
sudo -u postgres psqlYou'll land in a psql prompt connected to the postgres maintenance database as the postgres role. You shouldn't use the superuser for your application's day-to-day work — create a dedicated role and a database owned by it instead:
CREATE ROLE myuser WITH LOGIN PASSWORD 'change_me';
CREATE DATABASE mydb OWNER myuser;Replace myuser and mydb with your own names, and change_me with a strong password of your own — this one is a placeholder.
Exit the session:
\qStep 4. psql basics
The general syntax for invoking psql from the shell:
psql [option...] [dbname [username]]The main flags: -U — role, -d — database, -h — host (without it, psql connects over a Unix socket instead of TCP), -p — port (5432 by default). The sudo -u postgres psql command from step 3 is equivalent to sudo -u postgres psql -U postgres -d postgres.
Inside psql, alongside regular SQL, meta-commands are available — they all start with a backslash. Connect as postgres and try the basics:
sudo -u postgres psql\l
\du\l lists databases — mydb should be among them; \du lists roles — myuser and postgres itself should be there (with superuser privileges marked for the latter).
Switch to the database you created and list its tables:
\c mydb
\dtA fresh database has no tables yet, so \dt will reply Did not find any relations. — that's expected.
A few more useful meta-commands:
\x— toggle expanded (vertical) output, handy for wide rows with long values;\password myuser— set or change a role's password: it's prompted for interactively, twice, and never shows up in plaintext in your command history, unlikePASSWORD '...'insideCREATE ROLE/ALTER ROLE;\conninfo— show which database, user, host, and port you're currently connected to;\i file.sql— run SQL commands from a file;\?— list all meta-commands,\h COMMAND_NAME— syntax for a specific SQL command, e.g.\h CREATE ROLE.
End the session:
\qLogging in as myuser with a password (psql -U myuser -d mydb -h 127.0.0.1) will work once you've configured access in the next step.
Step 5. Configure access: pg_hba.conf and listen_addresses
Two settings control who can connect to the server and how: listen_addresses in postgresql.conf — which network interfaces the server listens on at all — and pg_hba.conf — which addresses, databases, roles, and authentication methods are allowed to connect. By default, a fresh server only listens on localhost — that's enough if your application runs on this same VPS. You only need to change both files if you need access from outside.
Where the files live depends on the distro and install method:
- Ubuntu/Debian:
/etc/postgresql/16/main/postgresql.confand/etc/postgresql/16/main/pg_hba.conf(the number is the PostgreSQL version; thepostgresql-commonpackage keeps configuration separate from the data directory). - AlmaLinux/Rocky, AppStream package:
/var/lib/pgsql/data/postgresql.confand/var/lib/pgsql/data/pg_hba.conf. - AlmaLinux/Rocky, PGDG package:
/var/lib/pgsql/16/data/postgresql.confand/var/lib/pgsql/16/data/pg_hba.conf.
Local access (within this VPS)
On AlmaLinux/Rocky, open pg_hba.conf, find the lines for 127.0.0.1/32 and ::1/128, and change ident to scram-sha-256 so they read:
host all all 127.0.0.1/32 scram-sha-256
host all all ::1/128 scram-sha-256Apply the change:
systemctl reload postgresqlTest logging in as your new role, with a password, over TCP:
psql -U myuser -d mydb -h 127.0.0.1 -W-h forces psql to connect over TCP — through the host line in pg_hba.conf — rather than the Unix socket (the local line, which still uses peer), which is why this, and not sudo -u postgres psql, is how you test password login. -W guarantees a password prompt.
Remote access
If your application, or you yourself, will connect from somewhere other than this VPS — another server or your own computer — two more changes are needed.
Let PostgreSQL listen on external interfaces — in postgresql.conf, change:
listen_addresses = 'localhost'to:
listen_addresses = '*'(or set a specific IP address of the VPS instead of * if it has more than one interface). listen_addresses only takes effect at server start — reload won't apply it, you need a full restart:
systemctl restart postgresqlAdd a dedicated line to pg_hba.conf for the address you'll connect from:
host mydb myuser 203.0.113.10/32 scram-sha-256Replace 203.0.113.10/32 with the client's real IP address (or subnet).
Reload the configuration:
systemctl reload postgresqlUnlike listen_addresses, pg_hba.conf only needs a reload — no full restart required.
Step 6. Open port 5432 in the firewall — only if you need remote access
If all access to the database is local (the application runs on this same VPS and connects over the Unix socket or 127.0.0.1), you don't need to open the port at all — PostgreSQL is already unreachable from outside as long as pg_hba.conf has no lines for external addresses from the "Remote access" section above. Only open the port if you just set up remote access.
Ubuntu / Debian (ufw)
If ufw isn't set up on the server yet, go through the "Setting up the UFW firewall" article first — it installs ufw, allows SSH, and enables the firewall. If ufw is already running, allow access to the port only from the client IP address from the previous step:
ufw allow from 203.0.113.10 to any port 5432 proto tcpAlmaLinux / Rocky (firewalld)
firewall-cmd --permanent --add-port=5432/tcp
firewall-cmd --reloadWhat's next
A database without backups is eventually lost along with the VPS — set up regular automated backups, see the "Database backups" article.