Docker: Test-Setup für self-hosted Betrieb (ohne Änderung des App-Teils)
Neuer Ordner docker/ (Dockerfile, docker-entrypoint.sh, docker-compose.yml, README). Der bestehende App-/Client-Teil (Start.ps1, src/, www/) bleibt unverändert und wird nur ins Image kopiert. Container-Spezifika laufen ohne Codeeingriff: - socat-Bridge 0.0.0.0:8080 -> 127.0.0.1:8077 (App bindet weiter nur loopback) - Datenpfad via XDG_CONFIG_HOME=/data (Volume) - Get-AppDataDir nutzt das auf Linux - Login über den vorhandenen Device-Code-Flow (WAM/Loopback geht im Container nicht) Kein Caddy: der vorhandene Reverse-Proxy zieht Port 8080 an. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
# Intune Manager - Test-Image (self-hosted).
|
||||||
|
# WICHTIG: Der bestehende App-/Client-Teil wird NICHT veraendert - Start.ps1, src/
|
||||||
|
# und www/ werden nur unveraendert ins Image kopiert. Die einzigen Container-
|
||||||
|
# Spezifika (Bridge fuer den localhost-Listener, Datenpfad, Login) laufen ueber
|
||||||
|
# Env-Variablen bzw. das Entrypoint-Script - ohne Codeaenderung.
|
||||||
|
FROM mcr.microsoft.com/powershell:7.4-debian-12
|
||||||
|
|
||||||
|
# socat = Bridge 0.0.0.0:BRIDGE_PORT -> 127.0.0.1:APP_PORT (App bindet nur loopback).
|
||||||
|
# git = fuer das optionale Policy-Git-Snapshot-Feature.
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends socat git ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* \
|
||||||
|
&& pwsh -NoProfile -Command "Install-Module Microsoft.Graph.Authentication -Scope AllUsers -Force"
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Bestehende App unveraendert ins Image kopieren (Build-Kontext = Repo-Root).
|
||||||
|
COPY Start.ps1 ./
|
||||||
|
COPY src/ ./src/
|
||||||
|
COPY www/ ./www/
|
||||||
|
|
||||||
|
# Entrypoint (neu, nur fuer den Container).
|
||||||
|
COPY docker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||||
|
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||||
|
|
||||||
|
# Datenverzeichnis: Get-AppDataDir nutzt auf Linux $XDG_CONFIG_HOME ->
|
||||||
|
# Settings/Policy-Exporte landen im Volume /data. Kein Codeeingriff noetig.
|
||||||
|
ENV XDG_CONFIG_HOME=/data \
|
||||||
|
APP_PORT=8077 \
|
||||||
|
BRIDGE_PORT=8080
|
||||||
|
|
||||||
|
VOLUME /data
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# Intune Manager - Docker-Test (self-hosted)
|
||||||
|
|
||||||
|
Test-Aufbau, um den Intune Manager als Container zu verproben. **Der bestehende
|
||||||
|
App-/Client-Teil (`Start.ps1`, `src/`, `www/`) wird nicht verändert** — er wird nur
|
||||||
|
unverändert ins Image kopiert. Container-Spezifika laufen über Env-Variablen und ein
|
||||||
|
Entrypoint-Script.
|
||||||
|
|
||||||
|
> Kein Caddy/TLS enthalten — der **vorhandene Reverse-Proxy** zieht den
|
||||||
|
> veröffentlichten Port (`8080`) an. HTTPS macht der Proxy.
|
||||||
|
|
||||||
|
## Wie es funktioniert
|
||||||
|
- Die App bindet unverändert auf `http://localhost:8077/` (nur containerintern).
|
||||||
|
- Ein **socat-Bridge** im Container leitet `0.0.0.0:8080 → 127.0.0.1:8077` — dadurch ist
|
||||||
|
die App von außen erreichbar, ohne den App-Code anzufassen.
|
||||||
|
- Settings/Policy-Exporte liegen im Volume `/data` (`XDG_CONFIG_HOME=/data`, wird von
|
||||||
|
`Get-AppDataDir` auf Linux automatisch genutzt).
|
||||||
|
|
||||||
|
## Bauen & starten
|
||||||
|
```bash
|
||||||
|
docker compose -f docker/docker-compose.yml up --build -d
|
||||||
|
```
|
||||||
|
Logs ansehen:
|
||||||
|
```bash
|
||||||
|
docker compose -f docker/docker-compose.yml logs -f
|
||||||
|
```
|
||||||
|
Erwartet: „Intune Manager - Web Edition" und „URL: http://localhost:8077/".
|
||||||
|
|
||||||
|
Den Reverse-Proxy auf `http://<docker-host>:8080` zeigen lassen (reiner HTTP-Proxy,
|
||||||
|
keine WebSockets/Callbacks nötig).
|
||||||
|
|
||||||
|
## Erststart: Verbindung konfigurieren
|
||||||
|
Beim ersten Start ist noch kein Tenant hinterlegt. Zwei Wege:
|
||||||
|
|
||||||
|
- **UI:** Seite öffnen → *Einstellungen* → **Tenant-ID**, **Client-ID** (Read/Write),
|
||||||
|
optional **Client-ID (Read-Only)** und **Scopes** eintragen und speichern. Landet in
|
||||||
|
`/data/IntuneAppManager-Web/settings.json`.
|
||||||
|
- **oder** eine vorhandene `settings.json` ins Volume legen:
|
||||||
|
```bash
|
||||||
|
docker cp settings.json intune-manager-test:/data/IntuneAppManager-Web/settings.json
|
||||||
|
docker compose -f docker/docker-compose.yml restart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Login (Device-Code)
|
||||||
|
Der interaktive „Verbinden"-Button nutzt WAM/Loopback und **funktioniert im Container
|
||||||
|
nicht** — das ist erwartet. Für den Test den bereits vorhandenen **Device-Code-Flow**
|
||||||
|
per `curl` anstoßen (Host = euer Reverse-Proxy oder `http://<docker-host>:8080`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -s -X POST http://<host>/api/connect/start
|
||||||
|
```
|
||||||
|
Antwort enthält `code` und `urlComplete`. Dann:
|
||||||
|
1. `urlComplete` im Browser öffnen und als Admin anmelden.
|
||||||
|
2. Status pollen, bis verbunden:
|
||||||
|
```bash
|
||||||
|
curl -s http://<host>/api/status
|
||||||
|
```
|
||||||
|
(Feld `connected` wird `true`.)
|
||||||
|
3. Die UI im Browser **neu laden** → jetzt verbunden. Geräte/Gruppen/Policies laden
|
||||||
|
zum Verifizieren.
|
||||||
|
|
||||||
|
## Stoppen / Aufräumen
|
||||||
|
```bash
|
||||||
|
docker compose -f docker/docker-compose.yml down # Daten bleiben im Volume
|
||||||
|
docker compose -f docker/docker-compose.yml down -v # inkl. Daten löschen
|
||||||
|
```
|
||||||
|
|
||||||
|
## Wichtige Hinweise (für den echten Einsatz)
|
||||||
|
- **Kein eigener UI-Login und geteilte Sitzung:** Wer die URL erreicht, kann den Login
|
||||||
|
auslösen; die verbundene Graph-Sitzung gilt prozessweit. Die Instanz **zwingend hinter
|
||||||
|
Zugangsschutz** stellen (Reverse-Proxy-Auth / Netzsegment / VPN). Eine Instanz =
|
||||||
|
eine Team-Sitzung, kein sauberes Multi-Admin.
|
||||||
|
- Reports liegen unter `/tmp` (nicht persistent) — für den Test ausreichend.
|
||||||
|
- Das ist ein **Test-Setup**. Echtes Mehrbenutzer (Login pro Admin) wäre ein separater
|
||||||
|
Ausbau (Auth-Code-Flow + Sitzungs-Isolation).
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# Intune Manager - Test-Compose (self-hosted).
|
||||||
|
# Kein Caddy/TLS: der bestehende Reverse-Proxy zieht den veroeffentlichten Port an.
|
||||||
|
services:
|
||||||
|
intune-manager:
|
||||||
|
build:
|
||||||
|
context: .. # Build-Kontext = Repo-Root (fuer COPY Start.ps1/src/www)
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
|
image: intune-manager-test
|
||||||
|
container_name: intune-manager-test
|
||||||
|
ports:
|
||||||
|
- "8080:8080" # <docker-host>:8080 -> vom Reverse-Proxy anziehen
|
||||||
|
volumes:
|
||||||
|
- im-data:/data # settings.json + policy-exports persistent
|
||||||
|
environment:
|
||||||
|
- XDG_CONFIG_HOME=/data
|
||||||
|
- APP_PORT=8077
|
||||||
|
- BRIDGE_PORT=8080
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
im-data:
|
||||||
Executable
+14
@@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Startet die App unveraendert (bindet auf 127.0.0.1:APP_PORT) und leitet externe
|
||||||
|
# Verbindungen per socat-Bridge dorthin - so bleibt der App-Code unangetastet.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
: "${APP_PORT:=8077}"
|
||||||
|
: "${BRIDGE_PORT:=8080}"
|
||||||
|
|
||||||
|
# Bridge im Hintergrund: 0.0.0.0:BRIDGE_PORT -> 127.0.0.1:APP_PORT
|
||||||
|
# (fork = pro Verbindung ein Prozess; reuseaddr = schneller Neustart).
|
||||||
|
socat "TCP-LISTEN:${BRIDGE_PORT},fork,reuseaddr" "TCP:127.0.0.1:${APP_PORT}" &
|
||||||
|
|
||||||
|
# App im Vordergrund (Logs -> stdout). -NoBrowser: im Container kein Desktop/open.
|
||||||
|
exec pwsh -NoProfile -File /app/Start.ps1 -NoBrowser -Port "${APP_PORT}"
|
||||||
Reference in New Issue
Block a user