7.2 KiB
title, homepage, tagline
| title | homepage | tagline |
|---|---|---|
| Postgres | https://www.postgresql.org/ | PostgreSQL: The World's Most Advanced Open Source Relational Database. |
To update or switch versions, run webi postgres@stable (or @v10, @beta,
etc).
Files
These are the files / directories that are created and/or modified with this install:
~/.config/envman/PATH.env
~/.local/opt/postgres/
~/.local/share/postgres/var/postgresql.conf
# for psql (postgres client)
~/.pgpass
~/.psqlrc
~/.config/psql/
Cheat Sheet
Postgres is the all-in-one database for beginners and experts alike. It handles SQL, 'NoSQL', JSON, HSTORE, Full-Text Search, Messages Queues and more. Best bang for buck.
To enable Postgres as a Linux Service with serviceman:
(see macOS below)
sudo env PATH="$PATH" \
serviceman add --system --username "$(id -u -n)" --name 'postgres' -- \
postgres -D ~/.local/share/postgres/var -p 5432
sudo systemctl restart systemd-journald
To login:
(see creating remote app users below)
# as Postgres admin
psql "postgres://postgres:postgres@localhost:5432/postgres"
# as remote user
psql "postgres://db-xxxx@pg-1.example.com:5432/db-xxxx?sslmode=require&sslnegotiation=direct"
Table of Contents
- Server vs Client & PG Essentials
- Initialize a database with a password
- Start the Postgres Server
- development
- systemd (most Linuxes)
- OpenRC (container Linuxes)
- macOS
- Enable Secure Remote Access
- Create Secure Remote App (User/DB)
- Change an User's (App's) password
Where to Find the Postgres Client Cheat Sheet
This is exclusively a server-side cheat sheet.
For the client-side cheat sheet, see The PSQL (Client) Cheat Sheet.
For a collection of other helpful scripts, see PG Essentials:
- pg-register-service
- pg-addgroup
- pg-adduser
- pg-passwd
How to Initialize the Postgres Database (with password)
- Create a database directory, paired to the Postgres version
mkdir -p ~/.local/share/postgres-17/var/ - Use a password file and
initdbto create a new DB directoryecho 'postgres' > /tmp/pwfile && \ initdb -D ~/.local/share/postgres/var/ \ --username 'postgres' --pwfile /tmp/pwfile \ --auth-local=password --auth-host=password \ && rm /tmp/pwfile - Test that the server starts
(kill with
postgres -D ~/.local/share/postgres/var -p 5432ctrl+c)
How to run the Postgres server (daemon or foreground)
- foreground (development)
- systemd (Debian, Ubuntu, Redhat, etc)
- OpenRC (Alpine, Arch, Gentoo, etc)
- macOS (launchd)
To run in the foreground (for development):
postgres -D ~/.local/share/postgres/var -p 5432
Debian / Systemd
curl https://webi.sh/serviceman | sh
sudo env PATH="$PATH" \
serviceman add --system --username "$(id -u -n)" --name 'postgres' -- \
postgres -D ~/.local/share/postgres/var -p 5432
sudo systemctl restart systemd-journald
sudo journalctl -xefu postgres
Alpine / OpenRC
/etc/init.d/postgres:
#!/sbin/openrc-run
name="postgres"
description="postgres daemon"
command="/home/app/.local/opt/postgres/bin/postgres"
command_args="-D /home/app/.local/share/postgres/var -p 5432"
command_user="app:app"
supervisor="supervise-daemon"
output_log="/var/log/postgres"
error_log="/var/log/postgres"
depend() {
need net
}
start_pre() {
checkpath --directory --owner root /var/log/
checkpath --file --owner ${command_user} ${output_log} ${error_log}
}
start() {
ebegin "Starting ${name}"
supervise-daemon ${name} --start \
--stdout ${output_log} \
--stderr ${error_log} \
--pidfile /run/${RC_SVCNAME}.pid \
--respawn-delay 5 \
--respawn-max 10 \
-- \
${command} \
${command_args} \
eend $?
}
stop() {
ebegin "Stopping ${name}"
supervise-daemon ${name} --stop \
--pidfile /run/${RC_SVCNAME}.pid
eend $?
}
sudo rc-update add postgres
sudo rc-service postgres restart
sudo tail -f /var/log/postgres
macOS
serviceman add --name 'postgres' -- \
postgres -D ~/.local/share/postgres/var -p 5432
tail -f ~/.local/share/postgres/var/log/postgres.log
How to Enable Secure Remote Postgres Access
-
Create the
my_remote_usersgroup:echo 'CREATE ROLE "my_remote_users" NOLOGIN;' | psql "postgres://postgres:postgres@localhost:5432/postgres" -f - -
Update the hba permissions to enable App users (
sameuser):
~/.local/share/postgres/var/pg_hba.conf:# Allow 'my_remote_users' to connect remotely directly over the internet hostssl sameuser +my_remote_users 0.0.0.0/0 scram-sha-256 hostssl sameuser +my_remote_users ::0/0 scram-sha-256 # Allow 'my_remote_users' group to connect through a local TLS-terminating proxy hostnossl sameuser +my_remote_users 127.0.0.1/8 scram-sha-256 hostnossl sameuser +my_remote_users ::1/128 scram-sha-256 host sameuser +my_remote_users 10.0.0.0/8 scram-sha-256 host sameuser +my_remote_users 172.16.0.0/12 scram-sha-256 host sameuser +my_remote_users 192.168.0.0/16 scram-sha-256 host sameuser +my_remote_users fc00::/7 scram-sha-256 -
Create a 10-year Self-signed cert for your server name or IP
my_host=pg-1.example.com openssl req -new -x509 -days 3650 -nodes -text \ -out ./server.crt -keyout ./server.key -subj "/CN=$my_host" chmod 0600 ./server.key ./server.crt mv ./server.key ./server.crt ~/.local/share/postgres/var/ -
Update the main postgres config to allow secure connections:
~/.local/share/postgres/var/postgresql.conf:ssl = on password_encryption = scram-sha-256 listen_addresses = '*' -
Restart Postgres for the change to take effect
# all unixes killall postgres # systemd (Debian, Ubunut, RedHat, Suse, etc) sudo systemctl restart postgres # openrc (Alpine, Gentoo, Arch) rc-service postgres restart # macos launchctl unload ~/Library/LaunchAgents/postgres.plist launchctl load ~/Library/LaunchAgents/postgres.plist
How to Create Secure Remote Users
The sameuser database directive REQUIRES the user and db name to be the same.
my_app="foobar_xxxx"
# e.g. generate password / token with 'xxd -l16 -ps /dev/urandom'
my_token="db-token-for-the-app"
echo "
CREATE DATABASE \"$my_app\";
CREATE ROLE \"$my_app\" LOGIN INHERIT
IN ROLE \"my_remote_users\" ENCRYPTED PASSWORD '$my_token';
GRANT ALL PRIVILEGES ON DATABASE \"$my_app\" to \"$my_app\";
" | psql "postgres://postgres:postgres@localhost:5432/postgres" -f -
Notes:
- quote style matters:
- double quotes
"for identifiers (users, tables, groups, roles) - single quotes
'for values (password)
- double quotes
How to Change a DB's Password
my_app='foobar_xxxx'
my_token="$(xxd -l16 -ps /dev/urandom)"
echo "ALTER USER \"$my_app\" PASSWORD '$my_token';" |
psql 'postgres://postgres:postgres@localhost:5432/postgres' -f -