feat(nexus-db): PostgreSQL 16 + pgvector LXC template (nexus-hub K-102)
webapp-pattern ct/install pair: PGDG repo, database nexus with least-privilege owner role, pg_hba allowlist restricted to the nexus app LXC (explicit reject for everything else), pgvector created by the installer, credentials/DSN summary in /root/nexus-db.credentials. Idempotent re-runs keep role/db and do not rotate the password.
This commit is contained in:
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env bash
|
||||
# nexus-db — PostgreSQL 16 (+pgvector) for nexus (Family Knowledge Hub)
|
||||
#
|
||||
# Creates an unprivileged Debian 12 LXC that:
|
||||
# - runs PostgreSQL 16 from the PGDG repo with the pgvector extension
|
||||
# - hosts database `nexus` owned by a least-privilege role `nexus`
|
||||
# - accepts connections ONLY from the nexus app LXC (pg_hba allowlist);
|
||||
# every other host is rejected
|
||||
#
|
||||
# Companion card: nexus-hub K-102. Run on a Proxmox VE host:
|
||||
# bash -c "$(curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/ct/nexus-db.sh)"
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
APP="nexus-db"
|
||||
APP_DESCRIPTION="PostgreSQL 16 + pgvector for nexus (access restricted to the nexus LXC)"
|
||||
|
||||
LIB_URL="${LIB_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib}"
|
||||
INSTALL_SCRIPT_URL="${INSTALL_SCRIPT_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/install/nexus-db-install.sh}"
|
||||
|
||||
# LXC defaults (DB only: small CPU, RAM matters for shared_buffers/cache)
|
||||
DEFAULT_HOSTNAME="nexus-db"
|
||||
DEFAULT_DISK="16"
|
||||
DEFAULT_CORES="2"
|
||||
DEFAULT_RAM="4096"
|
||||
|
||||
DEFAULT_DB_NAME="nexus"
|
||||
DEFAULT_DB_USER="nexus"
|
||||
DEFAULT_DB_PORT="5432"
|
||||
|
||||
# ── app-specific prompts (host TTY; each skipped if the var is preset) ───────
|
||||
prompt_app_config() {
|
||||
echo
|
||||
echo "── nexus-db configuration ───────────────────────────────────"
|
||||
# The ONLY host that may connect (pg_hba allowlist) — the nexus app LXC.
|
||||
if [[ -z "${NEXUS_APP_IP:-}" ]]; then
|
||||
read -rp "IP of the nexus app LXC (sole allowed client): " NEXUS_APP_IP
|
||||
fi
|
||||
[[ -n "${NEXUS_APP_IP:-}" ]] || { msg_err "NEXUS_APP_IP is required (pg_hba allowlist)"; exit 1; }
|
||||
|
||||
DB_NAME="${DB_NAME:-$DEFAULT_DB_NAME}"
|
||||
DB_USER="${DB_USER:-$DEFAULT_DB_USER}"
|
||||
DB_PORT="${DB_PORT:-$DEFAULT_DB_PORT}"
|
||||
|
||||
echo " → database: $DB_NAME role: $DB_USER port: $DB_PORT"
|
||||
echo " → allowed client: $NEXUS_APP_IP/32 (everything else is rejected)"
|
||||
}
|
||||
|
||||
# ── push gathered config into the container for the installer to consume ─────
|
||||
push_app_config() {
|
||||
msg_info "Pushing db config into container..."
|
||||
local tmpf; tmpf=$(mktemp)
|
||||
cat >"$tmpf" <<EOF
|
||||
NEXUS_APP_IP='$NEXUS_APP_IP'
|
||||
DB_NAME='$DB_NAME'
|
||||
DB_USER='$DB_USER'
|
||||
DB_PORT='$DB_PORT'
|
||||
EOF
|
||||
pct push "$CTID" "$tmpf" /root/nexus-db.deploy.env --perms 600
|
||||
rm -f "$tmpf"
|
||||
}
|
||||
|
||||
# ── trailing summary ─────────────────────────────────────────────────────────
|
||||
print_app_summary() {
|
||||
local pg_state
|
||||
pg_state=$(pct exec "$CTID" -- systemctl is-active postgresql 2>/dev/null | tr -d '\r\n')
|
||||
cat <<EOF
|
||||
PostgreSQL 16: $IP_CT:$DB_PORT — $pg_state
|
||||
Database: $DB_NAME (owner: $DB_USER, extension: vector)
|
||||
Allowed client: $NEXUS_APP_IP/32 — all other hosts are rejected
|
||||
Credentials + DSN: /root/nexus-db.credentials (inside the LXC)
|
||||
|
||||
Smoke test FROM THE NEXUS LXC (uses the DSN from the credentials file):
|
||||
psql "postgresql://$DB_USER:<password>@$IP_CT:$DB_PORT/$DB_NAME" -c "SELECT extname FROM pg_extension;"
|
||||
|
||||
Negative test from any OTHER host (must fail):
|
||||
psql "postgresql://$DB_USER:<password>@$IP_CT:$DB_PORT/$DB_NAME" -c "SELECT 1;"
|
||||
|
||||
Logs: pct exec $CTID -- journalctl -u postgresql -f
|
||||
EOF
|
||||
}
|
||||
|
||||
# ── orchestrate ───────────────────────────────────────────────────────────────
|
||||
trap _on_error ERR
|
||||
preflight_pve
|
||||
show_header "$APP" "$APP_DESCRIPTION"
|
||||
prompt_lxc_config
|
||||
prompt_app_config
|
||||
resolve_debian_template
|
||||
create_lxc
|
||||
push_app_config
|
||||
bootstrap_install_script "$INSTALL_SCRIPT_URL"
|
||||
print_summary
|
||||
Reference in New Issue
Block a user