fix(nexus-db): enforce UTF8 encoding at install time (issue #8)
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 1s
CI / Shell-Lint (bash -n, source-check, Validierungs-Tests) (pull_request) Successful in 1s
A PostgreSQL cluster/database freezes its encoding at initdb / CREATE DATABASE time; a C (non-UTF-8) locale yields a SQL_ASCII cluster, which makes psycopg3 return bytes and crashes SQLAlchemy. Harden the installer and add a reusable pattern for future DB installers: - ensure_utf8_locale_active: generate AND activate en_US.UTF-8 for the install process before the server package runs initdb; abort if the locale is not actually available - create the database explicitly with TEMPLATE template0 ENCODING 'UTF8' LC_COLLATE/LC_CTYPE 'en_US.UTF-8' instead of inheriting the cluster default - assert_db_encoding_utf8: post-install guard, abort with an actionable message if pg_encoding_to_char is not UTF8 (catches old SQL_ASCII DBs on re-run too) - credentials/README docs use su - postgres -c (minimal LXCs have no sudo)
This commit is contained in:
@@ -47,6 +47,12 @@ else
|
||||
msg_warn "PGDG repo already present, skipping"
|
||||
fi
|
||||
|
||||
# The server package runs initdb for the `main` cluster on install — its
|
||||
# encoding is frozen there. Make a UTF-8 locale active for THIS process first
|
||||
# so the cluster is never created as SQL_ASCII (issue #8: a pre-fix LXC was
|
||||
# provisioned under LANG=C and ended up SQL_ASCII).
|
||||
ensure_utf8_locale_active en_US.UTF-8
|
||||
|
||||
msg_info "Installing PostgreSQL $PG_MAJOR + pgvector..."
|
||||
apt-get install -y -qq "postgresql-$PG_MAJOR" "postgresql-$PG_MAJOR-pgvector" >/dev/null
|
||||
msg_ok "PostgreSQL $(psql --version | awk '{print $3}') installed"
|
||||
@@ -114,14 +120,22 @@ else
|
||||
fi
|
||||
|
||||
if [[ "$(run_psql -c "SELECT 1 FROM pg_database WHERE datname='$DB_NAME'")" != "1" ]]; then
|
||||
run_psql -c "CREATE DATABASE $DB_NAME OWNER $DB_USER"
|
||||
# Explicit encoding/collation from template0 — never inherit the cluster
|
||||
# default, which may be SQL_ASCII if initdb ran under a broken locale
|
||||
# (issue #8). template0 is required to override LC_COLLATE/LC_CTYPE.
|
||||
run_psql -c "CREATE DATABASE $DB_NAME OWNER $DB_USER ENCODING 'UTF8' LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8' TEMPLATE template0"
|
||||
# Only the owner may connect — no PUBLIC access.
|
||||
run_psql -c "REVOKE CONNECT ON DATABASE $DB_NAME FROM PUBLIC"
|
||||
msg_ok "Database $DB_NAME created (owner $DB_USER, PUBLIC revoked)"
|
||||
msg_ok "Database $DB_NAME created (UTF8, owner $DB_USER, PUBLIC revoked)"
|
||||
else
|
||||
msg_warn "Database $DB_NAME already exists, skipping"
|
||||
msg_warn "Database $DB_NAME already exists, skipping creation"
|
||||
fi
|
||||
|
||||
# Encoding guard (issue #8): catch both a freshly mis-created DB and a
|
||||
# pre-existing SQL_ASCII database from an old provisioning. Abort before the
|
||||
# app ever connects — a wrong encoding is DB damage, not a warning.
|
||||
assert_db_encoding_utf8 "$DB_NAME"
|
||||
|
||||
# pgvector: CREATE EXTENSION needs superuser; installed now (per ADR-0002:
|
||||
# "Extension ab Tag 1 installiert, ungenutzt bis Phase 2").
|
||||
run_psql -d "$DB_NAME" -c "CREATE EXTENSION IF NOT EXISTS vector" >/dev/null
|
||||
@@ -141,9 +155,12 @@ Password: $DB_PASS
|
||||
DSN for /etc/nexus/env on the nexus LXC (NEXUS_DATABASE_URL):
|
||||
postgresql+psycopg://$DB_USER:$DB_PASS@$IP_SELF:$DB_PORT/$DB_NAME
|
||||
|
||||
Encoding: UTF8 (LC_COLLATE/LC_CTYPE en_US.UTF-8) — verified at install time.
|
||||
|
||||
Access policy (pg_hba): only $NEXUS_APP_IP/32 may connect; all other
|
||||
hosts are rejected. Local socket stays peer-auth for maintenance:
|
||||
pct exec <CTID> -- runuser -u postgres -- psql -d $DB_NAME
|
||||
hosts are rejected. Local socket stays peer-auth for maintenance (these
|
||||
minimal LXCs have no sudo — use su, not sudo):
|
||||
pct exec <CTID> -- su - postgres -c "psql -d $DB_NAME"
|
||||
EOF
|
||||
chmod 600 "$CRED_FILE"
|
||||
msg_ok "Credentials written to $CRED_FILE (chmod 600)"
|
||||
|
||||
Reference in New Issue
Block a user