Installer: .env-Hinweis + Beispiel-.env + Backend-Health-Check; freundlichere API-Fehler

- install.sh: ensure_example legt .env.example an falls fehlend; env_hint weist
  klar auf die anpassbare .env hin; wait_for_backend pollt /api/health und meldet
  502-Ursachen mit Log-Hinweis.
- web/api.js: HTML-Fehlerseiten (z.B. nginx 502) nicht mehr roh anzeigen,
  stattdessen verständliche Meldung.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-22 09:35:14 +02:00
parent 575dd1a354
commit f0f652ddbe
2 changed files with 82 additions and 9 deletions

View File

@@ -11,6 +11,7 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="$SCRIPT_DIR/.env"
EXAMPLE_FILE="$SCRIPT_DIR/.env.example"
ASSUME_YES=0
[[ "${1:-}" == "--yes" || "${1:-}" == "-y" ]] && ASSUME_YES=1
@@ -105,14 +106,57 @@ ensure_docker() {
fi
}
# --- Beispiel-.env sicherstellen ----------------------------------------------
ensure_example() {
if [[ -f "$EXAMPLE_FILE" ]]; then
return
fi
info "Lege Beispiel-Konfiguration an: $EXAMPLE_FILE"
cat > "$EXAMPLE_FILE" <<'EOF'
# Kopiere diese Datei zu ".env" und passe die Werte an.
# install.sh erzeugt eine .env automatisch mit sicheren Zufallswerten.
# Port, unter dem die Web-UI erreichbar ist
WEB_PORT=8080
# Datenbank
POSTGRES_USER=project_good
POSTGRES_PASSWORD=project_good
POSTGRES_DB=project_good
# Sicherheit im Betrieb unbedingt ändern!
JWT_SECRET=change-me-please
# Erster Admin-Benutzer (wird nur beim allerersten Start angelegt)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=changeme
# CORS (bei Betrieb hinter dem mitgelieferten nginx nicht nötig)
CORS_ORIGINS=*
EOF
}
# --- Hinweis auf die Konfigurationsdatei --------------------------------------
env_hint() {
echo
info "Konfiguration liegt in: $ENV_FILE"
echo " Vorlage/Beispiel: $EXAMPLE_FILE"
warn "Dort kannst du bei Bedarf Werte anpassen: WEB_PORT (Port der Web-UI),"
warn "ADMIN_USERNAME/ADMIN_PASSWORD sowie die Datenbank- und JWT-Secrets."
warn "Nach Änderungen an der .env neu starten: $COMPOSE --env-file .env up -d"
}
# --- .env erzeugen ------------------------------------------------------------
create_env() {
ensure_example
if [[ -f "$ENV_FILE" ]]; then
info ".env existiert bereits bestehende Konfiguration wird verwendet."
env_hint
return
fi
info "Erzeuge Konfiguration (.env) …"
info "Erzeuge Konfiguration (.env) aus den Beispiel-Vorgaben …"
local web_port="8080"
local admin_user="admin"
@@ -141,6 +185,25 @@ EOF
GENERATED_ADMIN_USER="$admin_user"
GENERATED_ADMIN_PASS="$admin_pass"
GENERATED_WEB_PORT="$web_port"
env_hint
}
# --- Warten bis das Backend über die Web-UI erreichbar ist --------------------
wait_for_backend() {
local port="$1" tries=30 i
ensure_curl
info "Warte darauf, dass das Backend bereit ist …"
for ((i = 1; i <= tries; i++)); do
if curl -fsS "http://localhost:${port}/api/health" >/dev/null 2>&1; then
info "Backend ist erreichbar. ✅"
return 0
fi
sleep 2
done
warn "Backend antwortet nach ~$((tries * 2))s noch nicht das erklärt einen 502 in der Web-UI."
warn "Bitte die Logs prüfen: ( cd \"$SCRIPT_DIR\" && $COMPOSE logs backend )"
return 1
}
# --- Start --------------------------------------------------------------------
@@ -161,6 +224,8 @@ main() {
web_port="$(grep -E '^WEB_PORT=' "$ENV_FILE" | cut -d= -f2-)"
admin_user="$(grep -E '^ADMIN_USERNAME=' "$ENV_FILE" | cut -d= -f2-)"
wait_for_backend "$web_port" || true
echo
info "Fertig! 🎉"
echo " Web-UI: http://localhost:${web_port} (bzw. http://<server-ip>:${web_port})"

View File

@@ -49,14 +49,22 @@ async function request(path, { method = "GET", body, form } = {}) {
}
if (!resp.ok) {
const detail =
(data && data.detail) ||
(typeof data === "string" ? data : null) ||
`Fehler ${resp.status}`;
throw new ApiError(
Array.isArray(detail) ? detail.map((d) => d.msg).join(", ") : detail,
resp.status
);
let detail;
if (data && data.detail) {
detail = Array.isArray(data.detail)
? data.detail.map((d) => d.msg).join(", ")
: data.detail;
} else if (resp.status === 502 || resp.status === 503 || resp.status === 504) {
detail = `Server nicht erreichbar (${resp.status}). Läuft der Backend-Dienst? Prüfe: docker compose logs backend`;
} else if (typeof data === "string" && data.trim().startsWith("<")) {
// HTML-Fehlerseite (z.B. von nginx) nicht roh anzeigen
detail = `Server-Fehler (${resp.status}).`;
} else if (typeof data === "string" && data) {
detail = data;
} else {
detail = `Fehler ${resp.status}`;
}
throw new ApiError(detail, resp.status);
}
return data;
}