#!/usr/bin/env bash # MABEA – Server-Setup (Debian 13). Installiert PostgreSQL + nginx, legt DB/Rolle an, # richtet nginx als Reverse-Proxy vor dem späteren FastAPI/Uvicorn-Backend ein. # Idempotent: mehrfacher Aufruf überschreibt keine bestehende DB-Rolle/DB. # # Ausführung auf dem Zielserver als root: # DB_PASSWORD=... APP_DOMAIN=mabea.example.org ./install_server.sh # Ohne DB_PASSWORD wird ein zufälliges Passwort erzeugt und am Ende ausgegeben # (sofort sichern, z. B. in backend/.env auf dem Server – nicht committen). set -euo pipefail DB_NAME="${DB_NAME:-mabea}" DB_USER="${DB_USER:-mabea}" DB_PASSWORD="${DB_PASSWORD:-$(openssl rand -base64 24)}" JWT_SECRET_KEY="${JWT_SECRET_KEY:-$(openssl rand -base64 48)}" APP_DOMAIN="${APP_DOMAIN:-_}" # "_" = nginx catch-all, solange keine Domain feststeht # Kein sudo-Dependency: minimale LXC-Images haben sudo oft nicht vorinstalliert, # Skript läuft ohnehin als root (Ausführung dokumentiert das oben). # SQL wird bewusst über stdin an psql gepiped statt als su-Argument übergeben – # vermeidet doppelte Shell-Quoting-/Word-Splitting-Fallstricke (Bugfix nach Testlauf). run_psql() { local db="$1" sql="$2" printf '%s\n' "${sql}" | su -s /bin/bash postgres -c "psql -tA -d '${db}'" } echo "== apt update/install ==" export DEBIAN_FRONTEND=noninteractive apt-get update -qq apt-get install -y -qq postgresql nginx python3-venv python3-pip git openssl echo "== PostgreSQL: Rolle + Datenbank ==" if [ "$(run_psql postgres "SELECT 1 FROM pg_roles WHERE rolname='${DB_USER}';")" != "1" ]; then run_psql postgres "CREATE ROLE ${DB_USER} WITH LOGIN PASSWORD '${DB_PASSWORD}';" echo "Rolle ${DB_USER} angelegt." else echo "Rolle ${DB_USER} existiert bereits, überspringe." fi if [ "$(run_psql postgres "SELECT 1 FROM pg_database WHERE datname='${DB_NAME}';")" != "1" ]; then run_psql postgres "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};" echo "Datenbank ${DB_NAME} angelegt." else echo "Datenbank ${DB_NAME} existiert bereits, überspringe." fi # gen_random_uuid() ist seit PG13 built-in, aber pgcrypto schadet nicht und macht es # explizit/robust gegen ältere Backports (Review-Fund postgres-expert). run_psql "${DB_NAME}" "CREATE EXTENSION IF NOT EXISTS pgcrypto;" echo "== PostgreSQL: Speicher-Tuning für kleinen VPS (4GB RAM) ==" PG_CONF_DIR=$(run_psql postgres "SHOW config_file;" | xargs dirname) mkdir -p "${PG_CONF_DIR}/conf.d" cat > "${PG_CONF_DIR}/conf.d/mabea-tuning.conf" <<'PGCONF' # MABEA: konservatives Tuning für ~4GB RAM VPS, nicht enterprise-scale. shared_buffers = 1GB effective_cache_size = 3GB maintenance_work_mem = 256MB work_mem = 8MB max_connections = 50 PGCONF grep -q "conf.d/\*.conf" "${PG_CONF_DIR}/postgresql.conf" || \ echo "include_dir = 'conf.d'" >> "${PG_CONF_DIR}/postgresql.conf" echo "== nginx Reverse-Proxy Config (inkl. Security-Header) ==" sed -e "s/__APP_DOMAIN__/${APP_DOMAIN}/g" \ "$(dirname "$0")/nginx_mabea.conf.template" > /etc/nginx/sites-available/mabea.conf ln -sf /etc/nginx/sites-available/mabea.conf /etc/nginx/sites-enabled/mabea.conf rm -f /etc/nginx/sites-enabled/default nginx -t echo "== Dienste aktivieren ==" systemctl enable --now postgresql systemctl restart postgresql # Tuning-Konfiguration laden systemctl enable --now nginx systemctl reload nginx echo "== Zugangsdaten sichern ==" CRED_FILE="/root/mabea_db_credentials.env" umask 077 cat > "${CRED_FILE}" <