From 16391463d6ed24761b4ed6da04887e6d9bf74643 Mon Sep 17 00:00:00 2001 From: Jim Lancaster <40281233+zoltan57@users.noreply.github.com> Date: Wed, 2 Sep 2026 11:43:07 -0500 Subject: [PATCH] V6.1 yet more backup/.env cleanup --- .env.production.example | 18 ++++----- deploy/backup/create_postgres_backup.sh | 38 ++++++++++--------- docker-compose.production.yml | 6 +-- docs/backup_restore.md | 11 +++--- docs/ui/pages/settings.md | 4 +- .../ui/runtime_settings_store.py | 10 ++--- tests/test_meta_contract_guards.py | 3 -- 7 files changed, 45 insertions(+), 45 deletions(-) diff --git a/.env.production.example b/.env.production.example index 1da72a8..cf01413 100644 --- a/.env.production.example +++ b/.env.production.example @@ -25,15 +25,20 @@ DEFAULT_PROMPT_NAME=transcribe_document.md # TRANSCRIPTION_TOP_P= # --- persistence --- +# Common database settings: DATABASE__DRIVER=postgres -# DATABASE__PATH=./data/transcription.db -DATABASE__HOST=postgres -DATABASE__PORT=5432 DATABASE__DATABASE=transcription DATABASE__USER=transcription DATABASE__PASSWORD=replace-with-strong-password BOOTSTRAP_SCHEMA_ON_STARTUP=false -SQLITE_CHECK_SAME_THREAD=false + +# SQLite-specific settings: +# DATABASE__PATH=./data/transcription.db +# SQLITE_CHECK_SAME_THREAD=false + +# Postgres-specific settings: +DATABASE__HOST=postgres +DATABASE__PORT=5432 # --- filesystem paths --- UPLOAD_DIR=/app/uploads @@ -53,11 +58,6 @@ WORKER_MIN_TRANSCRIPTION_CHARS=0 WORKER_MIN_TRANSCRIPTION_LINES=0 WORKER_FAIL_ON_FINISH_REASON_LENGTH=false -# --- postgres container --- -POSTGRES_DB=transcription -POSTGRES_USER=transcription -POSTGRES_PASSWORD=replace-with-strong-password - # --- cloudflare tunnel --- # Required for token-based tunnel startup. CLOUDFLARE_TUNNEL_TOKEN=replace-with-cloudflare-tunnel-token diff --git a/deploy/backup/create_postgres_backup.sh b/deploy/backup/create_postgres_backup.sh index 673ce2d..752bc7e 100644 --- a/deploy/backup/create_postgres_backup.sh +++ b/deploy/backup/create_postgres_backup.sh @@ -5,27 +5,35 @@ BACKUP_DIR="${BACKUP_DIR:-./data/backups}" RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-14}" UPLOAD_DIR="${UPLOAD_DIR:-/app/uploads}" PROMPT_DIR="${PROMPT_DIR:-/app/prompts}" +DATABASE_DRIVER="${DATABASE__DRIVER:-postgres}" +DATABASE_HOST="${DATABASE__HOST:-postgres}" +DATABASE_PORT="${DATABASE__PORT:-5432}" +DATABASE_NAME="${DATABASE__DATABASE:-}" +DATABASE_USER="${DATABASE__USER:-}" +DATABASE_PASSWORD="${DATABASE__PASSWORD:-}" timestamp="$(date -u +%Y%m%d-%H%M%S)" postgres_file="postgres-${timestamp}.dump" manifest_file="backup-${timestamp}.manifest" mkdir -p "${BACKUP_DIR}" -: "${POSTGRES_HOST:=postgres}" -: "${POSTGRES_PORT:=5432}" -if [ -z "${POSTGRES_DB:-}" ] || [ -z "${POSTGRES_USER:-}" ] || [ -z "${POSTGRES_PASSWORD:-}" ]; then - echo "POSTGRES_DB, POSTGRES_USER, and POSTGRES_PASSWORD must be set." >&2 +if [ "${DATABASE_DRIVER}" != "postgres" ]; then + echo "create_postgres_backup.sh requires DATABASE__DRIVER=postgres." >&2 + exit 1 +fi +if [ -z "${DATABASE_NAME}" ] || [ -z "${DATABASE_USER}" ] || [ -z "${DATABASE_PASSWORD}" ]; then + echo "DATABASE__DATABASE, DATABASE__USER, and DATABASE__PASSWORD must be set." >&2 exit 1 fi if ! command -v pg_dump >/dev/null 2>&1; then echo "pg_dump is not installed in this environment." >&2 exit 1 fi -PGPASSWORD="${POSTGRES_PASSWORD}" pg_dump \ - -h "${POSTGRES_HOST}" \ - -p "${POSTGRES_PORT}" \ - -U "${POSTGRES_USER}" \ - -d "${POSTGRES_DB}" \ +PGPASSWORD="${DATABASE_PASSWORD}" pg_dump \ + -h "${DATABASE_HOST}" \ + -p "${DATABASE_PORT}" \ + -U "${DATABASE_USER}" \ + -d "${DATABASE_NAME}" \ -Fc \ > "${BACKUP_DIR}/${postgres_file}" @@ -43,15 +51,9 @@ find "${BACKUP_DIR}" -type f \( \ \) -mtime +"${RETENTION_DAYS}" -delete uploads_backup_dir="${BACKUP_DIR}/uploads" -mkdir -p "${uploads_backup_dir}/documents" "${uploads_backup_dir}/photos" -if [ -f "${UPLOAD_DIR}/homepage.md" ] && [ ! -f "${uploads_backup_dir}/homepage.md" ]; then - cp "${UPLOAD_DIR}/homepage.md" "${uploads_backup_dir}/homepage.md" -fi -if [ -d "${UPLOAD_DIR}/documents" ]; then - cp -an "${UPLOAD_DIR}/documents/." "${uploads_backup_dir}/documents/" -fi -if [ -d "${UPLOAD_DIR}/photos" ]; then - cp -an "${UPLOAD_DIR}/photos/." "${uploads_backup_dir}/photos/" +mkdir -p "${uploads_backup_dir}" +if [ -d "${UPLOAD_DIR}" ]; then + cp -an "${UPLOAD_DIR}/." "${uploads_backup_dir}/" fi prompts_backup_dir="${BACKUP_DIR}/prompts" diff --git a/docker-compose.production.yml b/docker-compose.production.yml index b78f4a0..cef1030 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -51,9 +51,9 @@ services: env_file: - .env.production environment: - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${DATABASE__DATABASE} + POSTGRES_USER: ${DATABASE__USER} + POSTGRES_PASSWORD: ${DATABASE__PASSWORD} volumes: - postgres_data:/var/lib/postgresql/data restart: unless-stopped diff --git a/docs/backup_restore.md b/docs/backup_restore.md index fa3cbbf..b7724ed 100644 --- a/docs/backup_restore.md +++ b/docs/backup_restore.md @@ -30,11 +30,12 @@ Environment variables used by the backup script: - `BACKUP_RETENTION_DAYS` (default `14`) - `UPLOAD_DIR` (default `/app/uploads`) - `PROMPT_DIR` (default `/app/prompts`) -- `POSTGRES_HOST` (default `postgres`) -- `POSTGRES_PORT` (default `5432`) -- `POSTGRES_DB` (required) -- `POSTGRES_USER` (required) -- `POSTGRES_PASSWORD` (required) +- `DATABASE__DRIVER` (must be `postgres`) +- `DATABASE__HOST` (default `postgres`) +- `DATABASE__PORT` (default `5432`) +- `DATABASE__DATABASE` (required) +- `DATABASE__USER` (required) +- `DATABASE__PASSWORD` (required) Recommended production setup: diff --git a/docs/ui/pages/settings.md b/docs/ui/pages/settings.md index fcca39b..db45f69 100644 --- a/docs/ui/pages/settings.md +++ b/docs/ui/pages/settings.md @@ -24,13 +24,13 @@ Settings manages installation-local registries, safe runtime .env settings, and - Runtime Settings exposes an allowlisted set of non-secret fields synchronized with `Settings` model fields except excluded secret/unsafe fields. - Runtime Settings is rendered as a compact two-column editor (**Setting**, **Value**) in a centered, narrower responsive container. - Runtime Settings persists changes to the resolved runtime env file, validates by constructing a `Settings` instance, and reports validation failures through the shared UI error presenter. -- The write target resolution order is: explicit function override (tests/tools), `RUNTIME_SETTINGS_ENV_FILE` environment variable (deployment override), then `Settings.model_config.env_file` (default `.env`). +- The write target resolution order is: explicit function override (tests/tools), `RUNTIME_SETTINGS_ENV_FILE` environment variable (deployment override), then `Settings.model_config.env_file` (default `.env.production`). - Runtime Settings changes require application restart to take effect. - Runtime Settings renders a host-side restart command (`docker compose -f docker-compose.production.yml up -d --force-recreate app worker`) so operators can apply saved values without granting Docker control to the app container. - Runtime Settings includes an explicit "Other settings not shown here" markdown table listing: - secrets (`OPENROUTER_API_KEY`, `DATABASE__PASSWORD`) - high-risk database connection settings (`DATABASE__DRIVER`, `DATABASE__PATH`, `DATABASE__HOST`, `DATABASE__PORT`, `DATABASE__DATABASE`, `DATABASE__USER`) - and deployment/helper keys (`POSTGRES_*`, `CLOUDFLARE_TUNNEL_TOKEN`, `BACKUP_DIR`, `BACKUP_RETENTION_DAYS`, `RUNTIME_SETTINGS_ENV_FILE`, `ENV_FILE`, `COMPOSE_FILE`) plus legacy/deprecated keys (`DATABASE_BACKUP_DIR`, `APP_DATA_BACKUP_DIR`, `UPLOADS_BACKUP_DIR`, `SYNOLOGY_BACKUP_DIR`), and directs edits for those keys to the resolved runtime env file path. + and deployment/helper keys (`CLOUDFLARE_TUNNEL_TOKEN`, `BACKUP_DIR`, `BACKUP_RETENTION_DAYS`, `RUNTIME_SETTINGS_ENV_FILE`, `ENV_FILE`, `COMPOSE_FILE`) plus legacy/deprecated keys (`POSTGRES_*`, `DATABASE_BACKUP_DIR`, `APP_DATA_BACKUP_DIR`, `UPLOADS_BACKUP_DIR`, `SYNOLOGY_BACKUP_DIR`), and directs edits for those keys to the resolved runtime env file path. - Document Types, Person Roles, and Tags support Add/Edit/Delete with existing guardrails. - Prompts exposes only `transcribe_document.md` for editing and restore-from-backup. - Home Page Text edits the same Markdown content rendered on `/homepage`. diff --git a/src/transcription/ui/runtime_settings_store.py b/src/transcription/ui/runtime_settings_store.py index 953d396..b45aa15 100644 --- a/src/transcription/ui/runtime_settings_store.py +++ b/src/transcription/ui/runtime_settings_store.py @@ -91,17 +91,17 @@ HIDDEN_SETTINGS_CATEGORIES: tuple[HiddenSettingsCategory, ...] = ( "intentionally edited outside the Runtime Settings UI." ), env_keys=( - "POSTGRES_DB", - "POSTGRES_USER", - "POSTGRES_PASSWORD", - "POSTGRES_HOST", - "POSTGRES_PORT", "CLOUDFLARE_TUNNEL_TOKEN", "RUNTIME_SETTINGS_ENV_FILE", "BACKUP_DIR", "BACKUP_RETENTION_DAYS", "ENV_FILE", "COMPOSE_FILE", + "POSTGRES_DB", + "POSTGRES_USER", + "POSTGRES_PASSWORD", + "POSTGRES_HOST", + "POSTGRES_PORT", "DATABASE_BACKUP_DIR", "APP_DATA_BACKUP_DIR", "UPLOADS_BACKUP_DIR", diff --git a/tests/test_meta_contract_guards.py b/tests/test_meta_contract_guards.py index 2f35bd8..6e34957 100644 --- a/tests/test_meta_contract_guards.py +++ b/tests/test_meta_contract_guards.py @@ -135,9 +135,6 @@ def test_env_production_example_keys_match_runtime_settings_contract(): "DATABASE__PASSWORD", } deployment_helper_keys = { - "POSTGRES_DB", - "POSTGRES_USER", - "POSTGRES_PASSWORD", "CLOUDFLARE_TUNNEL_TOKEN", "RUNTIME_SETTINGS_ENV_FILE", "BACKUP_DIR",