Isometric illustration of a database installed on a server, a Windows desktop and a container

How to Install PostgreSQL 18 on Ubuntu, Windows and Docker: Step by Step

A step-by-step guide to installing PostgreSQL 18 on Ubuntu 24.04, Windows and Docker, with secure roles, remote access, Turkish ICU locale and fixes for common errors.

November 2, 2026

We recommend three ways to install PostgreSQL 18: the official PGDG package repository for Linux servers in production, the postgresql.org installer for Windows servers, and the official Docker image for development and test environments. Whichever you choose, the important part comes afterwards: a separate role for the application, tight network access and the right locale chosen on day one.

This guide walks through the three installation methods step by step, then moves on to the settings that make a new server production-ready: roles and passwords, remote access (listen_addresses and pg_hba.conf), TLS, language-specific sorting and the errors you are most likely to hit on day one. We tested the commands with PostgreSQL 18.6 on a clean Ubuntu 24.04 system and the official postgres:18 Docker image.

PostgreSQL Setup

Get a production-ready PostgreSQL build

Aryasoft's senior PostgreSQL experts configure installation, authentication and network access, backups and monitoring for your environment and hand everything over in writing.

Contact Us

Which Installation Method Should You Choose?

All four methods install the same PostgreSQL server. The difference is which version you can get and how updates arrive.

Method PostgreSQL version Updates Best fit
Ubuntu + PGDG repository All supported versions, including 18 Minor releases arrive with normal apt updates Linux servers in production (recommended)
Ubuntu’s own package Only 16 on Ubuntu 24.04 With Ubuntu updates Servers where PostgreSQL 16 is enough
Windows installer All supported versions Run a new installer for each minor release Windows servers and developer machines
Docker (postgres:18) The tag you choose Pull a new image and recreate the container Development, CI and test environments

Which version? PostgreSQL 18 is the current major version (18.6 as of October 2026) and is supported until November 14, 2030. Unless your application vendor or an extension requires an older release, start new installations on 18.

Installing PostgreSQL on Ubuntu 24.04

The steps below follow the official instructions on postgresql.org. Run the commands as a user with sudo rights.

1. Add the PGDG repository

The postgresql-common package ships a script that adds the PostgreSQL community’s (PGDG) official package repository and signing key. The script asks for confirmation; add -y for unattended installs.

sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh

After this step, apt-cache madison postgresql lists the 18.x packages from the PGDG repository alongside Ubuntu’s own 16.x package.

2. Install PostgreSQL 18

sudo apt update
sudo apt install -y postgresql-18

The package creates and starts a database cluster named 18/main automatically. In our test the cluster came with these settings:

Setting Default value
Local connections peer authentication (Linux user name = database role)
TCP connections scram-sha-256 password authentication
Data checksums On
Locale Taken from the server environment (C.UTF-8 on a clean system)
Configuration files /etc/postgresql/18/main/ (postgresql.conf, pg_hba.conf)
Data directory /var/lib/postgresql/18/main
Server log /var/log/postgresql/postgresql-18-main.log

3. Check the service

pg_lsclusters
sudo pg_ctlcluster 18 main status
sudo pg_ctlcluster 18 main restart
sudo pg_ctlcluster 18 main reload

pg_lsclusters shows the version, port, status and directories of every cluster on the machine. Each cluster is also a systemd service named postgresql@18-main, so systemctl works as well.

Knowing what each change requires avoids unnecessary restarts: a reload is enough for pg_hba.conf changes, while settings such as listen_addresses and port need a restart.

4. Create the application role and database

After installation the only database role is postgres, and it has no password. Because local connections use peer authentication, you run administrative tasks as the postgres operating system user:

sudo -u postgres psql -c "SELECT version();"
sudo -u postgres psql -c "CREATE ROLE appuser WITH LOGIN PASSWORD 'ChangeMe-Str0ng!';"
sudo -u postgres psql -c "CREATE DATABASE appdb OWNER appuser;"

Never run applications as the postgres role. Give each application its own role that owns its database, and grant extra privileges only when they are really needed.

5. Verify password security

PostgreSQL 18 stores passwords with SCRAM-SHA-256 by default. The old MD5 method is deprecated; do not go back to it. The commands below confirm that the password is stored correctly and that a password login over TCP works:

sudo -u postgres psql -c "SELECT rolname, left(rolpassword, 14) AS hash_prefix FROM pg_authid WHERE rolname = 'appuser';"
PGPASSWORD='ChangeMe-Str0ng!' psql -h 127.0.0.1 -U appuser -d appdb -c "SELECT current_user, current_database(), inet_server_addr();"

The first query should return the SCRAM-SHA-256$ prefix. In scripts, use a ~/.pgpass file instead of PGPASSWORD so the password does not show up on the command line.

Open Remote Access Safely

A new installation accepts connections only from the server itself. Two settings control remote access together:

Setting What it controls After a change
listen_addresses Which network interfaces the server accepts connections on Restart
pg_hba.conf Who can connect, from which address, to which database and with which method Reload

The example below opens appdb only to the appuser role, only from the 10.10.20.0/24 application network and only over encrypted connections:

sudo -u postgres psql -c "ALTER SYSTEM SET listen_addresses = '*';"
echo "hostssl appdb    appuser    10.10.20.0/24    scram-sha-256" | sudo tee -a /etc/postgresql/18/main/pg_hba.conf
sudo pg_ctlcluster 18 main restart
sudo -u postgres psql -c "SELECT line_number, type, database, user_name, address, auth_method, error FROM pg_hba_file_rules;"

The last query shows the rules the server loaded and any lines with errors; check it after every change. pg_hba.conf rules are read from top to bottom and the first matching rule applies. If authentication fails on that rule, the following lines are not tried.

About TLS: hostssl accepts only encrypted connections. The Ubuntu package enables TLS with a self-signed certificate, so encryption works immediately. In our test a client on the allowed network connected with TLS 1.3; the same client was rejected with “no pg_hba.conf entry” when it turned encryption off. If clients must verify the server’s identity (sslmode=verify-full), replace the self-signed certificate with one issued by your organization’s certificate authority.

Warning

Do not add broad rules such as “host all all 0.0.0.0/0 trust” to get past a connection error. Name a database, a role and the narrowest possible network in every rule, and open port 5432 in the firewall only to application servers. A database port reachable from the internet is the first target of password-guessing attacks.

Installing PostgreSQL on Windows

The Windows page on postgresql.org points to an installer that sets up the PostgreSQL server, the pgAdmin management tool and StackBuilder (a tool for downloading extensions and drivers) together. The PostgreSQL 18 installer is tested on Windows Server 2025 and 2022.

  1. Download the PostgreSQL 18 installer from postgresql.org/download/windows/ and run it as administrator.
  2. Confirm the installation directory.
  3. Select components: PostgreSQL Server, pgAdmin 4, Stack Builder and Command Line Tools. Keep Command Line Tools selected; it installs tools such as psql and pg_dump.
  4. Choose the data directory. On servers, use the disk set aside for the database instead of the system disk.
  5. Set the password of the postgres superuser role and keep it in your corporate password manager.
  6. Keep the default port 5432 unless another PostgreSQL installation exists.
  7. Choose the locale. This choice sets the default sorting rules of your databases.
  8. Finish the installation. PostgreSQL then runs as a Windows service.

Watch for three Windows-specific points:

Topic What to do
User and computer names Use ASCII characters only. Names with non-ASCII characters can cause installation errors.
pg_hba.conf changes On Windows they apply to new connections immediately, without a reload.
Firewall For remote clients, add an inbound rule for port 5432 open only to application servers.

After installation you can connect with the bundled psql:

psql "host=127.0.0.1 port=5432 dbname=postgres user=postgres"

Roles, databases and pg_hba.conf rules work the same as on Linux.

PostgreSQL 18 with Docker

For development and test environments, the official image gives you a running server in seconds. A named volume keeps the data even if the container is removed or replaced.

docker run -d --name pg18 \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD='ChangeMe-Str0ng!' \
  -e POSTGRES_DB=appdb \
  -p 127.0.0.1:5432:5432 \
  -v pg18data:/var/lib/postgresql \
  --restart unless-stopped \
  postgres:18
docker logs pg18
docker exec -it pg18 psql -U appuser -d appdb

On first start the image creates the cluster and the role and database you specified. Wait for “PostgreSQL init process complete; ready for start up.” in the docker logs output before connecting. The -p 127.0.0.1:5432:5432 option publishes the port only on the host itself. In our test, a table we created was still there after the container was removed and started again on the same volume.

Note

The PostgreSQL 18 image keeps data under /var/lib/postgresql/18/docker and declares /var/lib/postgresql as the volume. Mount your volume at that directory. The /var/lib/postgresql/data examples common on the internet are for PostgreSQL 17 and earlier.

The Docker image has three behaviors that matter in practice:

Behavior Consequence
Environment variables apply only on first start Changing POSTGRES_PASSWORD on an existing volume has no effect; change the password with ALTER ROLE.
Connections inside the container need no password Anyone who can run docker exec is effectively a database administrator.
The latest tag moves to the new major version Use a fixed tag such as postgres:18; a new major version cannot start on an old data directory.

Choosing the Right Locale for Language-Specific Data

If your data is in a language with special case and sorting rules, decide on the locale before creating the cluster or database. Turkish is the classic example: the default C.UTF-8 locale upper-cases “istanbul ılık” to “ISTANBUL ILIK” and loses the dotted capital İ. The ICU-based tr-TR locale returns the correct “İSTANBUL ILIK” and sorts ç, ğ, ı, ö, ş and ü in Turkish alphabetical order.

A database’s locale provider cannot be changed later, so make the choice at creation time:

# Ubuntu: a new cluster with an ICU Turkish default (options after -- go to initdb)
sudo pg_createcluster 18 trmain --port 5433 --start -- --locale-provider=icu --icu-locale=tr-TR --locale=C.UTF-8

# Docker: pass the same options to initdb on first start
docker run -d --name pg18tr -e POSTGRES_PASSWORD='ChangeMe-Str0ng!' \
  -e POSTGRES_INITDB_ARGS="--locale-provider=icu --icu-locale=tr-TR" \
  -v pg18trdata:/var/lib/postgresql postgres:18

On an existing cluster, you can create a single database with Turkish rules and check the result:

CREATE DATABASE trdb TEMPLATE template0 ENCODING 'UTF8'
  LOCALE_PROVIDER icu ICU_LOCALE 'tr-TR' LOCALE 'C.UTF-8';
-- connect to trdb, then:
SELECT datname, datlocprovider, datlocale FROM pg_database WHERE datname = 'trdb';
SELECT upper('istanbul ılık') AS upper_tr, lower('İSTANBUL IŞIK') AS lower_tr;

Tip

On a freshly installed Ubuntu server with no data loaded yet, recreating the main cluster with the right locale is the cleanest path: first sudo pg_dropcluster 18 main –stop, then pg_createcluster 18 main with the ICU options above. On a cluster that already holds data, create a new ICU database and move the data with dump and restore.

Post-Installation Checklist

Check Expected result
Version SELECT version(); returns 18.6 or later; a schedule for minor updates is in place.
Authentication SHOW password_encryption; returns scram-sha-256; no role uses MD5 passwords.
Network Every remote rule names a specific database, role and narrow network; pg_hba_file_rules shows no errors.
TLS Remote rules use hostssl; a corporate certificate is planned if needed.
Locale The right provider and locale for your data were chosen (ICU tr-TR for Turkish).
Data checksums SHOW data_checksums; returns on.
Memory and connections Defaults (shared_buffers 128 MB, max_connections 100) resized for the hardware and workload.
Backup Backups are scheduled, copies are kept off the server and a restore has been tested.
Monitoring Server log, disk space, connection count and backup status are monitored from day one.

For what comes after installation, see our PostgreSQL best practices guide.

Common Errors and Fixes

We ran into every one of these errors while testing this guide.

Error message Cause Fix
FATAL: Peer authentication failed for user "appuser" psql connected over the local socket and your Linux user name differs from the role name. Connect over TCP with a password (psql -h 127.0.0.1 -U appuser -d appdb) or use sudo -u postgres psql for administration.
FATAL: password authentication failed for user "appuser" The password is wrong or the role has no password yet. Set the password with ALTER ROLE appuser WITH PASSWORD '...';
FATAL: no pg_hba.conf entry for host ... No rule matches the client address, database and user, or the rule is hostssl and the client did not use encryption. Add or fix the rule and reload; connect with sslmode=require for hostssl rules.
Connection refused The server is stopped or listens only on localhost. Check the status with pg_lsclusters; set listen_addresses and restart; check the firewall.
connection to server on socket ... No such file or directory No local server is running on that port. Start the cluster with sudo pg_ctlcluster 18 main start; if it does not start, read the server log.
FATAL: database "appdb" does not exist (Docker) The container was stopped before the first initialization finished, or the volume already held a cluster. Wait for the first start to complete; on a new install remove the volume and start again, otherwise create the database with CREATE DATABASE.

When Should You Bring in an Expert?

A test server is a few hours of work. In the following situations we recommend working with an experienced team:

  • The server will hold production data and needs a defined backup and point-in-time recovery plan.
  • High availability is required: standby servers, automatic failover or a second site. See our guide to building a high-availability PostgreSQL environment with Autobase.
  • Applications connect from different networks or through a connection pooler, and access must pass a security audit.
  • The workload is large enough that memory, checkpoint and autovacuum settings directly determine performance.
  • The new server replaces SQL Server, Oracle or a PostgreSQL version whose support has ended.

Aryasoft’s senior-only team offers every service it provides for SQL Server for PostgreSQL as well, from installation and hardening to performance tuning and version upgrades. Take a look at our PostgreSQL services, and if you want your new server looked after by a remote DBA under 8×5 or 24/7 maintenance-support, see our managed database services.

Frequently Asked Questions

Install 18 for new production systems. The first release candidate of PostgreSQL 19 came out on October 15, 2026, and general availability is planned for November 19, 2026. Extensions, drivers and cloud services usually take a few months to support a new major version; you can move from 18 to 19 later with a planned upgrade.
On Ubuntu 24.04 it installs PostgreSQL 16, which is supported until November 9, 2028. If 16 is enough for your application, it is a valid choice. For PostgreSQL 18, or several versions on one server, use the PGDG repository.
On Ubuntu there is none; local logins go through the postgres operating system user. On Windows you set the password during installation, and in Docker it comes from the POSTGRES_PASSWORD variable.
You can, but the container is the easy part. Production needs a reliable storage layer, backups kept outside the container, monitoring, a tested upgrade path and a failover plan. A common approach is Docker for development and test, and dedicated servers or a managed cloud service for production.
On Ubuntu with the PGDG repository, updates such as 18.6 to 18.7 arrive with normal apt updates; then restart the service. On Windows, run the new installer; in Docker, pull the new image and recreate the container on the same volume. Minor updates never need a dump or pg_upgrade.

Sources

The technical details in this guide were checked against the official documentation below in October and November 2026. Versions and package details can change; confirm them on the relevant page before you install.

  1. PostgreSQL: Linux downloads (Ubuntu)
  2. PostgreSQL Wiki: Apt repository
  3. PostgreSQL: Windows installers
  4. PostgreSQL: Versioning Policy
  5. PostgreSQL 18 release notes
  6. PostgreSQL 18 documentation: The pg_hba.conf File
  7. PostgreSQL 18 documentation: Peer Authentication
  8. PostgreSQL 18 documentation: Password Authentication
  9. PostgreSQL 18 documentation: Connections and Authentication
  10. PostgreSQL 18 documentation: Secure TCP/IP Connections with SSL
  11. PostgreSQL 18 documentation: ALTER SYSTEM
  12. PostgreSQL 18 documentation: CREATE DATABASE
  13. PostgreSQL 18 documentation: initdb
  14. PostgreSQL 18 documentation: Collation Support
  15. PostgreSQL 18 documentation: Authentication Problems
  16. Ubuntu Server documentation: Install and configure PostgreSQL
  17. Docker Hub: official postgres image

PostgreSQL Setup

Build your PostgreSQL servers on solid foundations

Talk to Aryasoft’s senior PostgreSQL team. We install and harden your servers, put backups and monitoring in place and document every decision in writing.

4.7/5