Terminal-Browser, konfigurierbarer Admin-Port und Einstellungsmenue

Der NGINX Proxy Manager laesst sich jetzt auch dann einrichten, wenn
seine Oberflaeche auf Port 81 aus dem Netz nicht erreichbar ist.

browser
  Terminal-Browser in einem eigenen Container, gestartet mit
  "run --rm -it --network host" - damit erreicht er 127.0.0.1 genau wie
  der Proxy Manager selbst. Engines: browsh und carbonyl (rendern einen
  echten Browser und koennen JavaScript, das die Adminoberflaeche
  benoetigt) sowie links2/w3m/lynx und eine Shell mit curl/jq/openssl
  fuer Diagnose. Werkzeug-Image unter containers/browser/.
  Bewusst kein Compose-Dienst: ein Browser ist interaktiv, und
  podman-compose behandelt Profile unzuverlaessig.

npm-port
  Port der Adminoberflaeche frei waehlbar. Das Image bindet fest auf 81
  ("listen 81 default;"), eine Umgebungsvariable dafuer gibt es in 2.15.1
  noch nicht. Ein abweichender Port wird deshalb ueber den nginx-
  Erweiterungspunkt /data/nginx/custom/http.conf bereitgestellt. Nur der
  markierte Block wird verwaltet, eigene Eintraege bleiben erhalten.
  Port 81 lauscht weiterhin lokal und ist per Firewall zu sperren.

config
  Alle Werte der .env sind menuegefuehrt bzw. ueber config get/set
  aenderbar - der Editor bleibt als Menuepunkt erhalten. Geprueft wird
  beim Setzen: Portbereich und Kollisionen, Site-Namen, vollqualifizierte
  Image-Namen, installierte Runtime, Zahlen- und URL-Felder.

Fehlerbehebungen
  - ui_*-Funktionen initialisieren sich selbst; eine von aussen gesetzte
    UI_BIN fuehrte unter "set -u" zum Abbruch.
  - Eine nicht installierte CMK_RUNTIME machte das gesamte Werkzeug
    unbenutzbar, auch den Aufruf zum Korrigieren. Jetzt wird gewarnt und
    selbst gesucht.
  - env_set setzt Werte mit Leerzeichen in Anfuehrungszeichen und laesst
    optional leere Werte zu.

README auf 22 Kapitel erweitert: Kapitel 11 (Terminal-Browser inkl.
NPM-API als Fallback fuer den Zertifikats-Upload), Kapitel 12 (Admin-Port)
und Abschnitt 14.3 (Einstellungsmenue).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-24 10:48:42 +02:00
co-authored by Claude Opus 5
parent b4956f780f
commit 1693330162
12 changed files with 2015 additions and 113 deletions
+1202 -22
View File
File diff suppressed because it is too large Load Diff
+49 -10
View File
@@ -36,21 +36,42 @@ load_env() {
warn "Keine .env gefunden ($envfile) - es gelten die Standardwerte."
ENV_FILE=""
fi
# Defaults
# Rueckfallwerte, falls ein Schluessel in der .env fehlt.
# Die .env bleibt die massgebliche Konfiguration - hier steht nur,
# was gilt, wenn dort nichts eingetragen ist.
CMK_CONTAINER_NAME="${CMK_CONTAINER_NAME:-checkmk}"
NPM_CONTAINER_NAME="${NPM_CONTAINER_NAME:-nginx-proxy-manager}"
CMK_SITE_ID="${CMK_SITE_ID:-cmk}"
BACKUP_DIR="${BACKUP_DIR:-$PROJECT_DIR/backups}"
case "$BACKUP_DIR" in
/*) : ;;
*) BACKUP_DIR="$PROJECT_DIR/${BACKUP_DIR#./}" ;;
CMK_IMAGE="${CMK_IMAGE:-docker.io/checkmk/check-mk-raw:2.3.0-latest}"
NPM_ADMIN_PORT="${NPM_ADMIN_PORT:-81}"
# Leer = automatisch aus dem Admin-Port ableiten
NPM_ADMIN_URL="${NPM_ADMIN_URL:-http://127.0.0.1:$NPM_ADMIN_PORT}"
BACKUP_DIR="$(abs_path "${BACKUP_DIR:-$PROJECT_DIR/backups}")"
IMAGE_DIR="$(abs_path "${IMAGE_DIR:-$PROJECT_DIR/images}")"
}
# relativen Pfad (./foo) am Projektverzeichnis ausrichten
abs_path() {
case "$1" in
/*) printf '%s\n' "$1" ;;
*) printf '%s\n' "$PROJECT_DIR/${1#./}" ;;
esac
}
# .env-Wert dauerhaft setzen
# env_set KEY WERT [allow_empty]
env_set() {
local key="$1" val="$2" f="${ENV_FILE:-$PROJECT_DIR/.env}"
local key="$1" val="$2" allow_empty="${3:-}" f="${ENV_FILE:-$PROJECT_DIR/.env}"
[ -f "$f" ] || die "Keine .env vorhanden - kann '$key' nicht setzen."
# mehrzeilige Werte wuerden die .env zerstoeren
case "$val" in
*$'\n'*) die "Ungueltiger Wert fuer '$key' (mehrzeilig)." ;;
esac
[ -n "$val" ] || [ -n "$allow_empty" ] || die "Leerer Wert fuer '$key' - abgebrochen."
# Werte mit Leerzeichen in Anfuehrungszeichen setzen
case "$val" in
*" "*) case "$val" in \"*\") : ;; *) val="\"$val\"" ;; esac ;;
esac
if grep -qE "^[#[:space:]]*${key}=" "$f"; then
sed -i -E "s|^[#[:space:]]*${key}=.*|${key}=${val}|" "$f"
else
@@ -63,10 +84,15 @@ env_set() {
# Container-Runtime erkennen (docker / podman)
# ---------------------------------------------------------------------
detect_runtime() {
if [ -n "${CMK_RUNTIME:-}" ]; then
command -v "$CMK_RUNTIME" >/dev/null 2>&1 \
|| die "CMK_RUNTIME='$CMK_RUNTIME' ist nicht installiert."
if [ -n "${CMK_RUNTIME:-}" ] && command -v "$CMK_RUNTIME" >/dev/null 2>&1; then
RUNTIME="$CMK_RUNTIME"
elif [ -n "${CMK_RUNTIME:-}" ]; then
# Falsch gesetzter Wert darf das Werkzeug nicht unbenutzbar machen
warn "CMK_RUNTIME='$CMK_RUNTIME' ist nicht installiert - suche selbst.
Korrigieren mit: cmk-manage.sh config set CMK_RUNTIME auto"
CMK_RUNTIME=""
detect_runtime
return
elif command -v docker >/dev/null 2>&1 && docker info >/dev/null 2>&1; then
RUNTIME=docker
elif command -v podman >/dev/null 2>&1; then
@@ -187,11 +213,13 @@ primary_ip() {
UI_BACKTITLE="Checkmk Stack Manager - Container-Runtime: ${RUNTIME:-?}"
ui_init() {
# Geometrie IMMER setzen - sonst laeuft das Skript unter "set -u" auf
# eine unbound variable, wenn UI_BIN von aussen vorgegeben wurde.
UI_H="${UI_H:-22}"; UI_W="${UI_W:-78}"; UI_MH="${UI_MH:-13}"
[ -n "${UI_BIN:-}" ] && return 0
if command -v dialog >/dev/null 2>&1; then UI_BIN=dialog
elif command -v whiptail >/dev/null 2>&1; then UI_BIN=whiptail
else UI_BIN=""; fi
UI_H="${UI_H:-22}"; UI_W="${UI_W:-78}"; UI_MH="${UI_MH:-13}"
export DIALOGRC="${DIALOGRC:-}"
}
@@ -205,51 +233,61 @@ ui_require() {
}
ui_menu() { # title text tag item [tag item ...] -> gewaehlter tag auf stdout
ui_init
local title="$1" text="$2"; shift 2
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \
--menu "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3
}
ui_checklist() { # title text tag item status ...
ui_init
local title="$1" text="$2"; shift 2
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \
--checklist "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3
}
ui_radiolist() {
ui_init
local title="$1" text="$2"; shift 2
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$title" \
--radiolist "$text" "$UI_H" "$UI_W" "$UI_MH" "$@" 3>&1 1>&2 2>&3
}
ui_input() { # title text default
ui_init
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" \
--inputbox "$2" 10 "$UI_W" "${3:-}" 3>&1 1>&2 2>&3
}
ui_password() {
ui_init
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" \
--passwordbox "$2" 10 "$UI_W" 3>&1 1>&2 2>&3
}
ui_msg() { # title text
ui_init
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --msgbox "$2" 16 "$UI_W"
}
ui_yesno() { # title text -> exit 0 = ja
ui_init
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --yesno "$2" 14 "$UI_W"
}
ui_text() { # title file
ui_init
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --textbox "$2" "$UI_H" "$UI_W"
}
ui_info() { # title text (ohne OK-Button)
ui_init
"$UI_BIN" --backtitle "$UI_BACKTITLE" --title "$1" --infobox "$2" 8 "$UI_W"
}
# Kommando ausfuehren, Ausgabe live in Datei, danach in Textbox anzeigen
ui_run() { # title cmd...
ui_init
local title="$1"; shift
local logf; logf="$(mktemp)"
ui_info "$title" "Bitte warten ...\n\n$*"
@@ -266,6 +304,7 @@ ui_run() { # title cmd...
# Dateiauswahl im Midnight-Commander-Stil (funktioniert auch mit whiptail)
# ---------------------------------------------------------------------
ui_pick_file() { # startdir [glob] -> Dateipfad auf stdout
ui_init
local dir="${1:-$PWD}" glob="${2:-*}" sel
dir="$(cd "$dir" 2>/dev/null && pwd || echo "$PWD")"
while :; do
+13 -3
View File
@@ -206,9 +206,19 @@ SHA256 : $sum
Import auf dem Zielsystem (Container-Installation):
1) Bundle in das Verzeichnis ./backups des Projekts kopieren
2) In der .env die passende Checkmk-Version eintragen:
CMK_IMAGE_TAG=${version%.*}
und den Stack neu erstellen: ./scripts/cmk-manage.sh up
2) Passendes Image beschaffen (Version MUSS uebereinstimmen):
./scripts/cmk-manage.sh image pull --edition $(
case "$version" in
*.cre) echo raw ;;
*.cee) echo enterprise ;;
*.cce) echo cloud ;;
*.cme) echo managed ;;
*) echo raw ;;
esac) --version ${version%.*}
Die Enterprise-Edition liegt NICHT auf Docker Hub - dort zusaetzlich
--user/--password (Checkmk-Kundenportal) angeben oder
"image download" verwenden.
Danach: ./scripts/cmk-manage.sh up
3) Import ausfuehren:
./scripts/cmk-manage.sh import --file backups/$(basename "$outfile") --set-default-site