Point pf.sh at the DB_* env vars the server actually reads

server.js builds its pg pool from DB_HOST/DB_PORT/DB_NAME/DB_USER/
DB_PASSWORD, and that is what install.sh writes, but pf.sh had been
written against a DATABASE_URL/PF_USER scheme that nothing consumes.
The consequences were real: `status` always reported the database
unreachable, and `config` rewrote .env with cat >, replacing a working
connection with keys the server ignores.

Connect through a run_psql helper built from the DB_* vars, and have
config prompt for those six keys instead. Each prompt defaults to the
current value so entering through changes nothing, the password prompt
is hidden and keeps the stored one when left blank, and any other key
already in .env is carried over rather than dropped.

PF_USER goes away with it — pf_user reaches the server in the request
body, never from the environment.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Paul Trowbridge 2026-09-14 22:08:49 -04:00
parent b1eb68a475
commit 146961cc17

99
pf.sh
View File

@ -67,13 +67,33 @@ require_service() {
service_installed || die "systemd service not installed. Run: ./pf.sh install-service"
}
# The keys cmd_config manages; anything else in .env is left alone.
ENV_KEYS=(DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD PORT)
env_get() {
[[ -f "$ENV_FILE" ]] || return 0
grep -E "^$1=" "$ENV_FILE" | tail -1 | cut -d= -f2- | tr -d '"' || true
}
# psql against the DB_* connection in .env; extra args are passed through.
run_psql() {
PGPASSWORD="${DB_PASSWORD:-}" psql \
-h "${DB_HOST:-localhost}" \
-p "${DB_PORT:-5432}" \
-U "${DB_USER}" \
-d "${DB_NAME}" \
"$@"
}
db_ping() {
load_env
local url="${DATABASE_URL:-}"
[[ -z "$url" ]] && { warn "DATABASE_URL not set in .env"; return 1; }
if [[ -z "${DB_NAME:-}" || -z "${DB_USER:-}" ]]; then
warn "DB_NAME / DB_USER not set in .env"
return 1
fi
# Use psql if available for a real connectivity check
if command -v psql &>/dev/null; then
psql "$url" -c "SELECT 1" &>/dev/null && return 0 || return 1
run_psql -tAc "SELECT 1" &>/dev/null && return 0 || return 1
else
warn "psql not in PATH — skipping live DB check"
return 0
@ -168,8 +188,7 @@ cmd_logs() {
cmd_db_setup() {
require_env; load_env
local url="${DATABASE_URL:-}"
[[ -z "$url" ]] && die "DATABASE_URL not set in .env"
[[ -n "${DB_NAME:-}" && -n "${DB_USER:-}" ]] || die "DB_NAME / DB_USER not set in .env — run: ./pf.sh config"
command -v psql &>/dev/null || die "psql not found — install postgresql-client"
echo
@ -178,7 +197,7 @@ cmd_db_setup() {
read -rp " Continue? [y/N] " confirm
[[ "$confirm" =~ ^[Yy]$ ]] || { echo "Aborted."; return; }
psql "$url" -f "${APP_DIR}/setup_sql/01_schema.sql"
run_psql -v ON_ERROR_STOP=1 -f "${APP_DIR}/setup_sql/01_schema.sql"
success "Schema applied."
}
@ -188,38 +207,62 @@ cmd_config() {
echo " File: $ENV_FILE"
echo
local current_url=""
local current_port=""
local current_user=""
local cur_host cur_port cur_name cur_user cur_pass cur_app_port
cur_host=$(env_get DB_HOST)
cur_port=$(env_get DB_PORT)
cur_name=$(env_get DB_NAME)
cur_user=$(env_get DB_USER)
cur_pass=$(env_get DB_PASSWORD)
cur_app_port=$(env_get PORT)
if [[ -f "$ENV_FILE" ]]; then
current_url=$(grep -E '^DATABASE_URL=' "$ENV_FILE" | cut -d= -f2- | tr -d '"' || true)
current_port=$(grep -E '^PORT=' "$ENV_FILE" | cut -d= -f2- | tr -d '"' || true)
current_user=$(grep -E '^PF_USER=' "$ENV_FILE" | cut -d= -f2- | tr -d '"' || true)
local input
read -rp " DB_HOST [${cur_host:-localhost}]: " input
local host="${input:-${cur_host:-localhost}}"
read -rp " DB_PORT [${cur_port:-5432}]: " input
local port="${input:-${cur_port:-5432}}"
read -rp " DB_NAME [${cur_name:-not set}]: " input
local name="${input:-$cur_name}"
[[ -z "$name" ]] && die "DB_NAME is required."
read -rp " DB_USER [${cur_user:-$USER}]: " input
local user="${input:-${cur_user:-$USER}}"
if [[ -n "$cur_pass" ]]; then
read -rsp " DB_PASSWORD [keep existing]: " input; echo
else
read -rsp " DB_PASSWORD: " input; echo
fi
local pass="${input:-$cur_pass}"
read -rp " DATABASE_URL [${current_url:-not set}]: " input_url
local url="${input_url:-$current_url}"
[[ -z "$url" ]] && die "DATABASE_URL is required."
read -rp " PORT (app) [${cur_app_port:-3010}]: " input
local app_port="${input:-${cur_app_port:-3010}}"
read -rp " PORT [${current_port:-3010}]: " input_port
local port="${input_port:-${current_port:-3010}}"
read -rp " PF_USER [${current_user:-$USER}]: " input_user
local pf_user="${input_user:-${current_user:-$USER}}"
cat > "$ENV_FILE" <<EOF
DATABASE_URL=${url}
PORT=${port}
PF_USER=${pf_user}
# Rewrite the managed keys, carrying over any other lines already in .env.
local tmp
tmp=$(mktemp)
cat > "$tmp" <<EOF
DB_HOST=${host}
DB_PORT=${port}
DB_NAME=${name}
DB_USER=${user}
DB_PASSWORD=${pass}
PORT=${app_port}
EOF
if [[ -f "$ENV_FILE" ]]; then
local managed
managed=$(IFS='|'; echo "${ENV_KEYS[*]}")
grep -vE "^(${managed})=" "$ENV_FILE" | grep -vE '^[[:space:]]*$' >> "$tmp" || true
fi
mv "$tmp" "$ENV_FILE"
chmod 600 "$ENV_FILE"
success ".env written."
if db_ping; then
success "Database connection verified."
else
warn "Could not reach the database — double-check DATABASE_URL."
warn "Could not reach the database — double-check the DB_* settings."
fi
}
@ -303,7 +346,7 @@ interactive_menu() {
echo " 5) status service + DB + git info"
echo " 6) logs tail journald logs"
echo " 7) db-setup apply setup_sql/01_schema.sql"
echo " 8) config set DATABASE_URL / PORT / PF_USER"
echo " 8) config set DB connection + app PORT"
echo " 9) install-service create systemd unit file"
echo " 10) uninstall-service remove systemd unit file"
echo " q) quit"