From 263e9b4565301f3ede51d7c0ebc602b9b408a6d6 Mon Sep 17 00:00:00 2001 From: chk <79915315+ChKendel@users.noreply.github.com> Date: Sat, 6 Jun 2026 17:14:11 +0200 Subject: [PATCH] Wieder anfassen nach Monaten --- .claude/launch.json | 11 + README.md | 352 ++++++++++++++++++ .../2026_03_21___q1_Auth.txt | 0 {dokumentation => doc}/2026_03_21___q2_WS.txt | 0 .../2026_03_21___q3_Auth.txt | 0 {dokumentation => doc}/AI_Gen.aux | 0 {dokumentation => doc}/AI_Gen.log | 0 {dokumentation => doc}/AI_Gen.out | 0 {dokumentation => doc}/AI_Gen.pdf | Bin {dokumentation => doc}/AI_Gen.synctex.gz | Bin {dokumentation => doc}/AI_Gen.tex | 0 {dokumentation => doc}/AI_Gen.txt | 0 doc/Architektur.svg | 97 +++++ doc/Portal.pdf | Bin 0 -> 79654 bytes doc/Portal.svg | 194 ++++++++++ forwarding_running_6_6_2026.conf | 51 +++ 16 files changed, 705 insertions(+) create mode 100644 .claude/launch.json create mode 100644 README.md rename {dokumentation => doc}/2026_03_21___q1_Auth.txt (100%) rename {dokumentation => doc}/2026_03_21___q2_WS.txt (100%) rename {dokumentation => doc}/2026_03_21___q3_Auth.txt (100%) rename {dokumentation => doc}/AI_Gen.aux (100%) rename {dokumentation => doc}/AI_Gen.log (100%) rename {dokumentation => doc}/AI_Gen.out (100%) rename {dokumentation => doc}/AI_Gen.pdf (100%) rename {dokumentation => doc}/AI_Gen.synctex.gz (100%) rename {dokumentation => doc}/AI_Gen.tex (100%) rename {dokumentation => doc}/AI_Gen.txt (100%) create mode 100644 doc/Architektur.svg create mode 100644 doc/Portal.pdf create mode 100644 doc/Portal.svg create mode 100644 forwarding_running_6_6_2026.conf diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000..83a9a2c --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,11 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "portal-static", + "runtimeExecutable": "python", + "runtimeArgs": ["-m", "http.server", "8099", "--directory", "public"], + "port": 8099 + } + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe446d0 --- /dev/null +++ b/README.md @@ -0,0 +1,352 @@ +# appServer Portal UI + +Übersichts-Webserver für **`server.schooltech.ch`**. Er fasst eine Reihe von +Web-Diensten (Roboter-Steuerungen, Guacamole-Remotedesktops, Portainer, +VS Code, Nextcloud …) unter **einer Domain** zusammen und macht sie über +sprechende Subdomains erreichbar. + +Alle Dienste laufen als Subdomain von `.server.schooltech.ch` – egal ob sie +auf dem Server selbst, auf einem Gerät im LAN oder hinter einem SSH-Tunnel +stehen. Ein nginx-Reverse-Proxy nimmt jede Subdomain auf 443 entgegen, +terminiert TLS (Let's Encrypt) und leitet an den passenden Upstream weiter. + +--- + +## Inhalt + +- [Architektur-Übersicht](#architektur-übersicht) +- [Die Portal-Seite (`server.schooltech.ch`)](#die-portal-seite-serverschooltechch) +- [Die Dienste / Subdomains](#die-dienste--subdomains) +- [`forwarding.conf` – das Herzstück](#forwardingconf--das-herzstück) +- [`connect-proxies.sh` – Konfig-Generator](#connect-proxiessh--konfig-generator) +- [Authentifizierung](#authentifizierung) +- [TLS / Let's Encrypt](#tls--lets-encrypt) +- [Container & Betrieb](#container--betrieb) +- [Neuen Dienst hinzufügen](#neuen-dienst-hinzufügen) +- [Dateiübersicht](#dateiübersicht) + +--- + +## Architektur-Übersicht + +Alles hängt unter `*.server.schooltech.ch`. Der Unterschied zwischen den +Diensten ist nicht die Domain, sondern **wohin der Upstream zeigt**: + +![Architektur-Übersicht](doc/Architektur.svg) + +> Diagramm-Quelle: [`doc/Architektur.svg`](doc/Architektur.svg) (daraus lässt +> sich bei Bedarf eine PDF/PNG erzeugen). + +**Bausteine (Docker-Container, siehe `docker-compose.yaml`):** + +| Container | Image | Rolle | +|---|---|---| +| `appServer_PortalUI` | `nginx:alpine` | Reverse-Proxy + Auslieferung der Portal-Seite (Ports 80/443) | +| `AppServerAuth` | `node:24-alpine` | Login-/Session-Service (`auth/auth.js`, Port 3000 intern) | +| `appServer_TunnelHead` | `linuxserver/openssh-server` | SSH-Hub: entfernte Geräte bauen Reverse-Tunnel hierher auf | +| `appServer_guacamole` | `abesnier/guacamole` | Lokaler Guacamole-Remotedesktop | +| `appServer_LetsEncryptFetcher` | `certbot/certbot` | Holt/erneuert die TLS-Zertifikate | + +Alle Container hängen im Docker-Netzwerk **`appRobotNet`** und sprechen sich +per Container-Namen an (z. B. `appserverauth:3000`). + +--- + +## Die Portal-Seite (`server.schooltech.ch`) + +Ruft man die nackte Domain `server.schooltech.ch` auf, erscheint die +**Portal-Oberfläche** – eine schlanke Single-Page-App aus `public/`: + +- **`public/index.html`** – Grundgerüst: oben eine **Navigationsleiste** + (`
` mit Logo *„schooltech“*, der Service-Navigation `#services` + und einem Login/Logout-Button), darunter ein **`