# Homenas Landing Page Angular-basierte Homelab-Startseite für das lokale Netzwerk (`neugasse.lan`). Zeigt Self-Hosted-Services aus Directus als Link-Karten an und ermöglicht die Steuerung von Tasmota-Steckdosen direkt aus dem Browser. --- ## Features - **Service-Übersicht** — Links zu allen Self-Hosted-Diensten, Bilder und Beschreibungen werden dynamisch aus Directus geladen - **Tasmota-Steuerung** — Ein/Aus-Toggle für Tasmota-Steckdosen direkt über die Web-UI - **Nginx-Container** — Auslieferung des Angular-Builds über `nginx:stable-alpine` via Docker Compose --- ## Stack | Komponente | Technologie | |---|---| | Frontend | Angular 17.1, Bootstrap 5 | | CMS / API | Directus | | Steckdosen | Tasmota (HTTP-API) | | Webserver | nginx:stable-alpine (Docker) | | Reverse Proxy | Nginx Proxy Manager | --- ## Architektur ``` Browser (Angular SPA) │ │ GET /api/items/landingpage (kein Token im Frontend) │ GET /api/assets/ │ GET http://stecker1.neugasse.lan/cm?cmnd=Power │ GET http://stecker2.neugasse.lan/cm?cmnd=Power ▼ Nginx Proxy Manager │ injiziert: Authorization: Bearer → Directus │ Tasmota-Geräte werden direkt vom Browser angesprochen (LAN) ▼ Nginx-Container (Port 9999) └── dist/ (Angular Production Build) ``` Der Directus API-Token verlässt niemals den Browser — er wird ausschließlich im **Nginx Proxy Manager** als `proxy_set_header` konfiguriert. --- ## Nginx Proxy Manager — Konfiguration Im Proxy Host der Landing Page unter **Advanced → Custom Nginx Configuration**: ```nginx location /api/items/landingpage { proxy_pass http://directus.neugasse.lan/items/landingpage; proxy_set_header Authorization "Bearer "; proxy_set_header Host directus.neugasse.lan; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /api/assets/ { proxy_pass http://directus.neugasse.lan/assets/; proxy_set_header Authorization "Bearer "; proxy_set_header Host directus.neugasse.lan; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ``` --- ## Deployment ### Voraussetzungen - Node.js 20 LTS (via nvm empfohlen) - Angular CLI 21.x (`npm install -g @angular/cli`) - Docker + Docker Compose auf dem Zielhost (Synology NAS) ### Node.js installieren (einmalig) ```bash # nvm installieren curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc # Node 20 LTS installieren und als Default setzen nvm install 20 nvm alias default 20 # Angular CLI installieren npm install -g @angular/cli ``` ### Ersteinrichtung nach Clone ```bash # Debian-ng aus dem Weg räumen (falls vorhanden) sudo mv /usr/bin/ng /usr/bin/ng-editor # Dependencies installieren npm install # Dev-Proxy einrichten cp proxy.conf.example.json proxy.conf.json # Token in proxy.conf.json eintragen ``` ### Production Build & Deploy ```bash ./deploy.sh ``` Das Script führt `ng build` aus und überträgt den Build via rsync auf den NAS. ```bash #!/bin/bash set -e echo "==> Build..." ng build echo "==> Deploy..." rsync -av --delete dist/ang-university-httpclient/browser/ \ hans@nas.neugasse.lan:/volume1/docker/landingpage/dist/ echo "==> Fertig." ``` ### Docker-Container starten ```bash cd webserver-docker docker compose up -d ``` Der Container lauscht auf Port `9999` und wird vom Nginx Proxy Manager nach außen exponiert. --- ## Lokale Entwicklung ### Dev-Proxy `proxy.conf.json` wird nicht ins Repository committed (siehe `.gitignore`). Vorlage kopieren und Token eintragen: ```bash cp proxy.conf.example.json proxy.conf.json # Token eintragen ``` Der Proxy ist in `angular.json` unter `serve.options.proxyConfig` eingetragen. ### Dev-Server starten ```bash ng serve ``` Der Directus-Token wird über `proxy.conf.json` injiziert — nicht im Code hinterlegt. `src/environments/environment.ts` ist ebenfalls in `.gitignore` und wird nicht committed. --- ## Tasmota-Steckdosen Die Steckdosen werden direkt vom Browser über ihre lokalen DNS-Namen angesprochen. Konfiguration in `src/app/tasmota.service.ts`: | ID | Name | Adresse | |---|---|---| | 1 | Aktiv Kohle Lüfter | `http://stecker1.neugasse.lan` | | 2 | Bambu P1P | `http://stecker2.neugasse.lan` | Weitere Steckdosen können im `sockets`-Array in `tasmota.service.ts` ergänzt werden. --- ## Projektstruktur ``` ├── src/ │ ├── app/ │ │ ├── links/ # Service-Karten-Komponente │ │ ├── tasmota-control/ # Steckdosen-Toggle-Komponente │ │ ├── links.service.ts # Directus API-Anbindung │ │ ├── tasmota.service.ts # Tasmota HTTP-API │ │ ├── links.ts # Interfaces: Links, LinksResponse │ │ └── socket.interface.ts # Interface: TasmotaSocket │ └── environments/ │ ├── environment.ts # Dev (in .gitignore) │ ├── environment.example.ts # Vorlage ohne Token │ └── environment.prod.ts # Prod (kein Token) ├── webserver-docker/ │ ├── docker-compose.yml # nginx:stable-alpine, Port 9999 │ └── nginx.conf # SPA-Routing, Gzip, Cache-Header ├── deploy.sh # Build + Deploy auf NAS ├── proxy.conf.example.json # Dev-Proxy Vorlage (ohne Token) └── apacheconfs/ # Veraltet — nicht mehr verwendet ``` > `apacheconfs/` ist historisch und wird nicht mehr aktiv genutzt. Der Reverse Proxy wird vollständig über den Nginx Proxy Manager abgebildet. --- ## Sicherheitshinweise - Der Directus API-Token gehört **ausschließlich** in die NPM-Konfiguration — nie in den Quellcode oder ins Repository - `proxy.conf.json` und `environment.ts` sind in `.gitignore` eingetragen und werden nicht committed - Tasmota-Geräte sind nur im LAN erreichbar (`*.neugasse.lan`) - Directus-Items müssen auf `published` gesetzt sein, damit die API sie ohne zusätzliche Filter liefert