Overview

A local Postgres instance backs the other backend guides on this site. This guide installs it, creates a dedicated role and database, and connects over TCP with a password, which avoids the peer authentication errors most first installs hit. Production hardening is in postgres-prod. PostgreSQL 18 is the current major release; any supported version works for these steps.

Prerequisites

  • Ubuntu or Debian with sudo, macOS with Homebrew, or Windows 11 with WSL2 (use the Ubuntu steps).
  • Package-manager repositories ship one major version; on Ubuntu apt install postgresql installs the distribution default. Add the PostgreSQL apt repository if you need a specific newer major.

Steps

1. Install and start

# Ubuntu / Debian
sudo apt update && sudo apt install -y postgresql postgresql-contrib
sudo systemctl enable --now postgresql
 
# macOS (Homebrew)
brew install postgresql@18 && brew services start postgresql@18
 
psql --version && pg_isready      # accepting connections

On macOS, put the formula’s bin directory on your PATH (brew info postgresql@18 prints the line).

2. Create a role and database

Do not run application code as postgres.

sudo -u postgres psql        # on macOS: psql postgres
CREATE ROLE myapp WITH LOGIN CREATEDB;
\password myapp
CREATE DATABASE myapp_dev OWNER myapp;

\password keeps the password out of shell history and of the server log.

3. Connect over TCP

psql -U myapp -d myapp_dev -h localhost

-h localhost forces a TCP connection, which uses the host rules in pg_hba.conf; without it psql uses the Unix socket and the local rules, where Ubuntu defaults to peer (OS user must equal the role). Default host rules use scram-sha-256. Edit pg_hba.conf only if you need password auth on the socket; find it with SHOW hba_file;, change peer to scram-sha-256 on the local line, and run sudo systemctl reload postgresql.

4. Set DATABASE_URL

export DATABASE_URL="postgresql://myapp:<password>@localhost:5432/myapp_dev"

Put it in a gitignored .env file. prisma and most frameworks read this single variable; see migrations for how migrations use it.

Verify it worked

psql "$DATABASE_URL" -c "SELECT current_user, current_database();"   # myapp | myapp_dev
sudo systemctl restart postgresql && pg_isready

Common errors

  • Peer authentication failed for user "myapp". You connected through the Unix socket; add -h localhost.
  • password authentication failed. The role has no password, or pg_hba.conf lists the wrong method for that connection type. Run \password myapp.
  • could not connect to server. The service is stopped; read sudo systemctl status postgresql or brew services list.
  • port 5432 already in use. Another Postgres instance is running. sudo lsof -i :5432 finds it.
  • MD5 password warnings. PostgreSQL 18 deprecates MD5 passwords; re-set the password so it is stored as SCRAM.

FAQ

How do I fix “Peer authentication failed” in Postgres?

You connected through the Unix socket, where Ubuntu defaults to peer auth; add -h localhost to connect over TCP with scram-sha-256 password auth.

Should my app connect to Postgres as the postgres user?

No; create a dedicated login role and a database it owns, and run application code as that role.

Which Postgres version should I install locally?

PostgreSQL 18 is the current major release, but any supported version works for these steps. On Ubuntu, apt install postgresql installs the distribution default.

Why does Postgres warn about MD5 passwords?

PostgreSQL 18 deprecates MD5 passwords; re-set the password with \password so it is stored as SCRAM.