#!/usr/bin/env bash # 006-install-postgres - PostgreSQL 18 from the official PGDG apt repository # (https://www.postgresql.org/download/linux/debian/ - "Manual configuration"). # Debian 13's own repo only ships PG 17, hence the PGDG repo. # Must run after 005: with /var/lib/postgresql already being the dedicated # disk, the 18/main cluster is created directly on it - no data_directory # changes needed. (Contrib modules ship in the server package since PG 10.) # up: add PGDG repo (GPG key + deb822 sources) + install postgresql-18 # down: stop + purge packages/config + remove PGDG repo; disk data is kept set -euo pipefail export DEBIAN_FRONTEND=noninteractive PGROOT=/var/lib/postgresql PGVER=18 KEY=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc SRC=/etc/apt/sources.list.d/pgdg.sources case "${1:-}" in up) if command -v pg_lsclusters >/dev/null 2>&1 \ && pg_lsclusters --no-header | awk -v v="$PGVER" '$1==v' | grep -q .; then echo " postgres $PGVER cluster already present - skipping" exit 0 fi # --- PGDG repository: official "Manual configuration" steps --- apt-get update -qq apt-get install -y curl ca-certificates postgresql-common >/dev/null install -d "$(dirname "$KEY")" curl --fail -o "$KEY" https://www.postgresql.org/media/keys/ACCC4CF8.asc . /etc/os-release cat > "$SRC" </dev/null chown postgres:postgres "$PGROOT" systemctl enable --now postgresql >/dev/null pg_isready -q datadir=$(pg_lsclusters --no-header | awk -v v="$PGVER" '$1==v {print $6; exit}') if [[ $(findmnt -rn -o TARGET -T "$datadir") == "$PGROOT" ]]; then echo " cluster data on dedicated disk: $datadir" else echo "FATAL: $datadir is NOT on the dedicated disk - aborting" >&2 exit 1 fi pg_lsclusters --no-header ;; status) command -v pg_lsclusters >/dev/null 2>&1 \ || { echo "DRIFT postgresql-common not installed"; exit 1; } line=$(pg_lsclusters --no-header | awk -v v="$PGVER" '$1==v' | head -1) [[ -n $line ]] || { echo "DRIFT no PG $PGVER cluster"; exit 1; } read -r _ name _ st _ datadir _ <<<"$line" [[ $st == online ]] || { echo "DRIFT cluster $PGVER/$name is '$st'"; exit 1; } [[ $(findmnt -rn -o TARGET -T "$datadir") == "$PGROOT" ]] \ || { echo "DRIFT $datadir not on $PGROOT"; exit 1; } [[ -f $SRC ]] || { echo "DRIFT PGDG repo file $SRC missing"; exit 1; } echo "OK PG $PGVER/$name online, data on $PGROOT, PGDG repo present" ;; down) { pg_lsclusters --no-header 2>/dev/null || true; } | while read -r ver name _; do pg_ctlcluster "$ver" "$name" stop 2>/dev/null || true done apt-get purge -y 'postgresql*' >/dev/null apt-get autoremove --purge -y >/dev/null rm -rf /etc/postgresql rm -f "$SRC" "$KEY" echo " postgres stopped + packages purged + PGDG repo removed (data kept under $PGROOT)" ;; esac