diff --git a/Apps/steam-headless/README.md b/Apps/steam-headless/README.md new file mode 100644 index 0000000..4aea9d8 --- /dev/null +++ b/Apps/steam-headless/README.md @@ -0,0 +1,78 @@ +# Steam Headless + +Steam Headless kör en webbaserad Linux-desktop med Steam i container, baserat på LinuxServer image `lscr.io/linuxserver/steam`. + +Imagepinning i denna app: + +- Compose använder immutable referens: `lscr.io/linuxserver/steam:version-f4f48542@sha256:d7b9fbf302e05ae79248d1171fe9751b354f8397eafa1e13a3df0aa6a75de0b4` +- `latest` finns i registryt men används inte i repo enligt policy. +- Vid verifieringstillfället pekade `latest` på samma release (`version-f4f48542`). + +## Syfte + +- Ge enkel Steam-access via webbläsare i ZimaOS. +- Hålla v1 med minsta möjliga privilegier. +- Förbereda en separat senare fas för Moonlight-fokuserad streaming. + +## Portar + +- `3000/tcp` (HTTP desktop): `${STEAM_HTTP_PORT:-3000}` +- `3001/tcp` (HTTPS desktop): `${STEAM_HTTPS_PORT:-3001}` + +## Volymer + +- `/DATA/AppData/$AppID/config -> /config` + +All Steam-data (profil, cache, installerade spel) lagras under appens egna AppData-sökväg. + +## Privilegier och säkerhet + +Aktiva säkerhetsinställningar i denna app: + +- `security_opt: ["seccomp:unconfined", "no-new-privileges:true"]` +- `cap_drop: ["ALL"]` +- Ingen `privileged: true` +- Ingen `network_mode: host` +- Ingen mount av `/var/run/docker.sock` + +Motivering: + +- LinuxServer Steam använder sandbox/bubblewrap-mönster som normalt kräver `seccomp:unconfined` för att spel/launcher ska fungera stabilt. +- `no-new-privileges:true` och `cap_drop: ["ALL"]` används för att kompensera med lägsta möjliga capability-yta i övrigt. + +Kända tradeoffs: + +- På vissa Debian/Ubuntu-hostar kan även `apparmor:unconfined` behövas. Detta är inte default här av least-privilege-skäl. +- Browser-vägen (KasmVNC) är enkel men ger inte samma latens/gamepad-egenskaper som Moonlight. + +## Säkerhetsavvikelser + +Denna app använder en avvikelse från strikt seccomp-default: + +- `seccomp:unconfined` + +Varför det behövs: + +- För kompatibilitet med LinuxServer Steam runtime och dess sandboxade processer. + +Alternativ som utvärderats: + +- Standard seccomp-profil: blockar delar av förväntad processmodell för Steam/spel. +- Full `privileged: true`: avvisat på grund av större attackyta. + +Risker: + +- Minskad syscall-filtrering jämfört med default seccomp-profil. +- Om container komprometteras finns större möjlighet att anropa kernel-funktioner än med strikt seccomp. + +Riskreducering: + +- Inga host-network eller docker-socket mounts. +- Capability-surface minimerad med `cap_drop: ["ALL"]`. +- Isolerad data-path under `/DATA/AppData/$AppID/...`. + +## Driftnoteringar + +- För GPU-acceleration kan extra device-mounts krävas beroende på host och drivrutiner. +- Om HTTPS används på `3001` kan webbläsaren visa certifikatvarning vid första anslutning. +- Rekommenderad nästa fas: separat Moonlight/Sunshine-spår som opt-in, med egen riskprofil. diff --git a/Apps/steam-headless/docker-compose.yaml b/Apps/steam-headless/docker-compose.yaml new file mode 100644 index 0000000..b8a5c5b --- /dev/null +++ b/Apps/steam-headless/docker-compose.yaml @@ -0,0 +1,81 @@ +name: steam-headless + +services: + steam: + image: lscr.io/linuxserver/steam:version-f4f48542@sha256:d7b9fbf302e05ae79248d1171fe9751b354f8397eafa1e13a3df0aa6a75de0b4 + container_name: steam-headless + restart: unless-stopped + shm_size: "1gb" + + environment: + TZ: ${TZ} + PUID: ${PUID} + PGID: ${PGID} + STEAM_HTTP_PORT: ${STEAM_HTTP_PORT:-3000} + STEAM_HTTPS_PORT: ${STEAM_HTTPS_PORT:-3001} + + ports: + - target: 3000 + published: ${STEAM_HTTP_PORT:-3000} + protocol: tcp + - target: 3001 + published: ${STEAM_HTTPS_PORT:-3001} + protocol: tcp + + volumes: + - type: bind + source: /DATA/AppData/$AppID/config + target: /config + + # Required by LinuxServer Steam for bubblewrap/game namespaces. + security_opt: + - seccomp:unconfined + - no-new-privileges:true + + # Keep capability surface minimal unless a specific game requires otherwise. + cap_drop: + - ALL + + x-casaos: + envs: + - container: TZ + description: + en_us: Timezone, for example Europe/Stockholm + - container: PUID + description: + en_us: User ID for filesystem permissions + - container: PGID + description: + en_us: Group ID for filesystem permissions + ports: + - container: "3000" + description: + en_us: Steam desktop GUI over HTTP + - container: "3001" + description: + en_us: Steam desktop GUI over HTTPS + volumes: + - container: /config + description: + en_us: Steam home, configuration, and game files + +x-casaos: + architectures: + - amd64 + main: steam + category: Games + author: Zima Apps Team + developer: linuxserver.io + icon: https://cdn.simpleicons.org/steam + tagline: + en_us: Browser-based Steam desktop container for ZimaOS + description: + en_us: >- + Runs LinuxServer Steam as a web-accessible desktop session. + Optimized for amd64 and least-privilege defaults, with optional future + Moonlight-focused expansion in a later phase. + title: + en_us: Steam Headless + index: / + port_map: ${STEAM_HTTPS_PORT:-3001} + scheme: https diff --git a/Apps/steam-moonlight/MOONLIGHT-RUNTIME-CHECKLIST.md b/Apps/steam-moonlight/MOONLIGHT-RUNTIME-CHECKLIST.md new file mode 100644 index 0000000..b0aa015 --- /dev/null +++ b/Apps/steam-moonlight/MOONLIGHT-RUNTIME-CHECKLIST.md @@ -0,0 +1,51 @@ +# Moonlight Runtime Checklist + +Strikt checklista för att aktivera `steam-moonlight`-profilen säkert. + +## Preflight (måste vara grönt) + +1. Bekräfta att du medvetet accepterar högriskprofil (`network_mode: host`, extra capabilities, device passthrough). +2. Sätt starkt lösenord i `SUNSHINE_PASS` (inte `change-me`, inte återanvänt). +3. Verifiera GPU-device mapping: + - `GPU_CARD_DEVICE` pekar på korrekt `/dev/dri/card*` + - `GPU_RENDER_DEVICE` pekar på korrekt `/dev/dri/renderD*` +4. Verifiera att hosten har: + - `/dev/fuse` + - `/dev/uinput` + - korrekt `/dev/dri/*` +5. Bekräfta att Sunshine-portar inte exponeras publikt mot internet. +6. Verifiera att volymerna är under `/DATA/AppData/$AppID/...`. +7. Verifiera compose-rendering: + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight config` + +## Startsekvens + +1. Starta endast Moonlight-profilen: + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight up -d steam-moonlight` +2. Kontrollera containerstatus: + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml ps` +3. Kontrollera initiala logs: + - `docker logs --tail=200 steam-moonlight-profile` + +## Post-start verifiering + +1. Verifiera att Sunshine kräver autentisering. +2. Verifiera att streaming fungerar från avsedd klient (LAN/VPN). +3. Verifiera controller-input utan att aktivera fler capabilities än definierat. +4. Verifiera att inga oväntade portar exponeras. +5. Verifiera att defaultprofil fortfarande kan köras separat vid rollback. + +## Driftregler + +1. Kör inte Moonlight-profilen permanent om den inte används. +2. Roterar `SUNSHINE_PASS` regelbundet och alltid efter incident. +3. Uppdatera image-pin via digest i kontrollerade change windows. +4. Undvik ad-hoc ändringar av capabilities eller device mounts. + +## Snabb rollback + +1. Stoppa Moonlight-profil: + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight stop steam-moonlight` +2. Kör defaultprofil: + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam` +3. Bekräfta återställd låg-risk drift via logs och funktionstest. diff --git a/Apps/steam-moonlight/README.md b/Apps/steam-moonlight/README.md new file mode 100644 index 0000000..82013eb --- /dev/null +++ b/Apps/steam-moonlight/README.md @@ -0,0 +1,102 @@ +# Steam Moonlight (Scaffold) + +Detta är en scaffold för hybridspåret (browser + Moonlight) baserat på `josh5/steam-headless`. + +Kompletterande säkerhetsdokument: + +- `SECURITY.md` +- `MOONLIGHT-RUNTIME-CHECKLIST.md` + +## Syfte + +- Ge en låg-risk default för browserbaserad Steam-desktop. +- Ge en separat opt-in-profil för Moonlight/Sunshine. +- Isolera högriskinställningar till en explicit profil (`moonlight`). + +## Imagepinning + +- Compose använder immutable referens: + - `josh5/steam-headless:debian-0.2.0@sha256:540366bee31297c5679a5006a84dbca039ca62aaab695852b51b5f62dffd2c14` +- Repon kräver att `latest` inte används i compose. + +## Profiler + +- `steam` (default): browser-first, lägre risk, ingen host network. +- `steam-moonlight` (`profiles: ["moonlight"]`): aktiverar Sunshine + controller/GPU passthrough med högre privilegier. + +## Körning + +- Default (rekommenderad start): + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam` +- Moonlight (opt-in): + - `docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight up -d steam-moonlight` +- Innan Moonlight aktiveras: + - byt `SUNSHINE_PASS` till ett starkt lösenord, + - verifiera `GPU_CARD_DEVICE` och `GPU_RENDER_DEVICE` för rätt GPU. + +## Portar + +- Defaultprofil (`steam`): + - `${STEAM_WEB_PORT:-8083}/tcp` för webdesktop. + +Moonlightprofilen använder `network_mode: host` och tar därför nätverk direkt från host. + +## Volymer + +- Defaultprofil: + - `/DATA/AppData/$AppID/home -> /home/default` + - `/DATA/AppData/$AppID/games -> /mnt/games` +- Moonlightprofil: + - `/DATA/AppData/$AppID/moonlight-home -> /home/default` + - `/DATA/AppData/$AppID/moonlight-games -> /mnt/games` + +## Privilegier och säkerhet + +Gemensamt: + +- `no-new-privileges:true` + +Defaultprofil (`steam`, lägre risk): + +- `cap_drop: ["ALL"]` +- Ingen `network_mode: host` +- Inga device mounts +- Ingen Sunshine-aktivering som default + +Moonlightprofil (högrisk): + +- `ipc: host` +- `security_opt: ["seccomp:unconfined", "apparmor:unconfined", "no-new-privileges:true"]` +- `cap_drop: ["ALL"]` + `cap_add: [NET_ADMIN, SYS_ADMIN, SYS_NICE]` +- `network_mode: host` +- Device mounts: `/dev/fuse`, `/dev/uinput`, `/dev/dri/*` +- `device_cgroup_rules: ['c 13:* rmw']` + +## Säkerhetsavvikelser + +Denna app innehåller avsiktliga avvikelser, primärt i `moonlight`-profilen. + +Varför det behövs: + +- Moonlight/Sunshine och fysisk controller-input kräver i praktiken host-nära åtkomst i denna containerfamilj. + +Alternativ som utvärderats: + +- Browser-only (`steam` default): lägre risk men sämre latens/gamepad. +- Full `privileged: true`: avvisat i scaffolden för att begränsa attackytan. + +Risker: + +- Host network minskar nätverksisolering. +- Extra capabilities och device-passthrough ökar konsekvensen vid containerkompromettering. + +Riskreducering: + +- Högrisk är opt-in via profil, inte default. +- Ingen docker socket-mount används. +- Persistent data är begränsad till `/DATA/AppData/$AppID/...`. +- Defaultprofilen droppar alla Linux capabilities. + +## Status + +Scaffolden är avsedd för kontrollerad vidareutveckling och verifiering, inte som slutlig hardened release. diff --git a/Apps/steam-moonlight/ROADMAP.md b/Apps/steam-moonlight/ROADMAP.md new file mode 100644 index 0000000..4f2f42f --- /dev/null +++ b/Apps/steam-moonlight/ROADMAP.md @@ -0,0 +1,50 @@ +# Roadmap + +## Current State (2026-03-18) + +- Browser-first service (`steam`) är testbar med låg-risk baseline. +- Moonlight service (`steam-moonlight`) finns som opt-in scaffold med dokumenterade risker. +- Operativa säkerhetskrav finns i `SECURITY.md` och `MOONLIGHT-RUNTIME-CHECKLIST.md`. + +## Next Milestone: Moonlight Test-Ready (Fail-Closed) + +Mål: Moonlight-profilen ska vägra starta vid osäker konfiguration. + +1. Enforce credentials +- Blockera start om `SUNSHINE_PASS` är tomt eller default (`change-me`). +- Blockera start om `SUNSHINE_USER` är tomt. + +2. Enforce GPU/device prerequisites +- Blockera start om `GPU_CARD_DEVICE` eller `GPU_RENDER_DEVICE` saknas på host. +- Blockera start om `/dev/fuse` eller `/dev/uinput` saknas. + +3. Enforce network safety baseline +- Tydlig varning + explicit opt-in env för internet-exponering. +- Defaultantagande: LAN/VPN-only drift. + +4. Preflight command and runbook +- Lägg till en verifierbar preflight-sekvens som måste passera före `up`. +- Uppdatera checklistan med pass/fail-kriterier. + +## Hardening Milestone + +1. Secrets hygiene +- Dokumentera rotationsintervall för Sunshine-credentials. +- Säkerställ att exempel aldrig innehåller riktiga credentials. + +2. Capability minimization +- Verifiera om någon `cap_add` kan tas bort utan funktionsförlust. +- Dokumentera minsta uppsättning capabilities per use-case. + +3. Upgrade discipline +- Definiera rutin för image-pin uppdatering (`tag + digest`) och rollback. + +## Release Criteria (Moonlight) + +För att kalla Moonlight-profilen releaseklar ska följande vara uppfyllt: + +1. Fail-closed enforcement implementerat och verifierat. +2. Positiv test av Moonlight streaming med korrekt auth. +3. Negativ test: start blockeras vid osäkra defaults/missing devices. +4. `./scripts/validate-appstore.sh --enforce-risk-docs` passerar. +5. README + security docs uppdaterade med slutlig driftmodell. diff --git a/Apps/steam-moonlight/SECURITY.md b/Apps/steam-moonlight/SECURITY.md new file mode 100644 index 0000000..317e32f --- /dev/null +++ b/Apps/steam-moonlight/SECURITY.md @@ -0,0 +1,70 @@ +# Security Model + +Detta dokument beskriver säkerhetsmodellen för `steam-moonlight` och hur risker begränsas mellan default- och Moonlight-profil. + +## Mål + +- Hålla default-profilen (`steam`) så nära least-privilege som möjligt. +- Göra Moonlight-profil (`steam-moonlight`) explicit opt-in med tydlig riskaccept. +- Hålla state/data begränsad till `/DATA/AppData/$AppID/...`. + +## Tillitsgränser + +- Host OS och Docker daemon är högsta trust-zon. +- Containern är lägre trust-zon. +- Moonlight-klienter och LAN-trafik är extern yta. + +## Threat Model + +Primära hot: + +- Kontoövertagande via svagt `SUNSHINE_PASS`. +- Lateral movement via `network_mode: host` (Moonlight-profil). +- Ökad impact vid containerkompromiss p.g.a. extra capabilities och device passthrough. +- Dataförlust vid felaktig mount-path. + +## Säkerhetskontroller + +Gemensamt: + +- Immutable image pin (`tag + digest`). +- Ingen docker socket mount. +- Ingen `privileged: true`. +- Data paths begränsade till `/DATA/AppData/$AppID/...`. + +Defaultprofil (`steam`): + +- `cap_drop: ["ALL"]` +- `no-new-privileges:true` +- Ingen `host` network +- Inga device mounts +- Sunshine avstängd som default (`ENABLE_SUNSHINE=false`) + +Moonlightprofil (`steam-moonlight`): + +- Högriskkontroller isolerade till `profiles: ["moonlight"]` +- `cap_drop: ["ALL"]` + minsta kända `cap_add` +- Explicit device lista (`/dev/fuse`, `/dev/uinput`, `/dev/dri/*`) +- `seccomp:unconfined` och `apparmor:unconfined` endast i Moonlight-profilen + +## Fail-Closed Regler + +- Moonlight ska inte startas om `SUNSHINE_PASS` är default eller tomt. +- Moonlight ska inte startas om GPU-device mapping saknas eller är fel. +- Vid osäkerhet, kör endast defaultprofilen (`steam`). + +## Operativa krav + +- Exponera inte Sunshine admin/UI mot internet. +- Begränsa åtkomst till LAN/VPN och pålitliga klienter. +- Rota image-pins kontrollerat och verifiera digest före uppdatering. +- Följ checklistan i `MOONLIGHT-RUNTIME-CHECKLIST.md` före varje aktivering. + +## Incidentrespons (minimum) + +Vid misstänkt kompromiss: + +1. Stoppa Moonlight-profilen direkt. +2. Roterar `SUNSHINE_PASS` och övriga credentials. +3. Granska hostens nätverksexponering och Docker logs. +4. Byt image till känd god pin och starta om endast defaultprofil. diff --git a/Apps/steam-moonlight/docker-compose.yaml b/Apps/steam-moonlight/docker-compose.yaml new file mode 100644 index 0000000..ac2b6d1 --- /dev/null +++ b/Apps/steam-moonlight/docker-compose.yaml @@ -0,0 +1,131 @@ +name: steam-moonlight + +x-steam-common: &steam-common + image: josh5/steam-headless:debian-0.2.0@sha256:540366bee31297c5679a5006a84dbca039ca62aaab695852b51b5f62dffd2c14 + restart: unless-stopped + shm_size: ${SHM_SIZE:-2G} + environment: + TZ: ${TZ} + PUID: ${PUID} + PGID: ${PGID} + UMASK: ${UMASK:-000} + USER_PASSWORD: ${USER_PASSWORD:-change-me} + MODE: ${MODE:-primary} + WEB_UI_MODE: ${WEB_UI_MODE:-vnc} + PORT_NOVNC_WEB: ${STEAM_WEB_PORT:-8083} + ENABLE_STEAM: ${ENABLE_STEAM:-true} + STEAM_ARGS: ${STEAM_ARGS:--silent} + ENABLE_SUNSHINE: ${ENABLE_SUNSHINE:-false} + SUNSHINE_USER: ${SUNSHINE_USER:-admin} + SUNSHINE_PASS: ${SUNSHINE_PASS:-change-me} + +services: + steam: + <<: *steam-common + container_name: steam-moonlight + security_opt: + - no-new-privileges:true + cap_drop: + - ALL + ports: + - target: 8083 + published: ${STEAM_WEB_PORT:-8083} + protocol: tcp + volumes: + - type: bind + source: /DATA/AppData/$AppID/home + target: /home/default + - type: bind + source: /DATA/AppData/$AppID/games + target: /mnt/games + x-casaos: + envs: + - container: TZ + description: + en_us: Timezone, for example Europe/Stockholm + - container: PUID + description: + en_us: User ID for filesystem permissions + - container: PGID + description: + en_us: Group ID for filesystem permissions + - container: STEAM_WEB_PORT + description: + en_us: Browser desktop port + ports: + - container: "8083" + description: + en_us: Steam desktop over web browser + volumes: + - container: /home/default + description: + en_us: Persistent user home and runtime state + - container: /mnt/games + description: + en_us: Persistent Steam game library + + steam-moonlight: + <<: *steam-common + container_name: steam-moonlight-profile + profiles: ["moonlight"] + network_mode: host + ipc: host + security_opt: + - seccomp:unconfined + - apparmor:unconfined + - no-new-privileges:true + cap_drop: + - ALL + cap_add: + - NET_ADMIN + - SYS_ADMIN + - SYS_NICE + devices: + - /dev/fuse + - /dev/uinput + - ${GPU_CARD_DEVICE:-/dev/dri/card0} + - ${GPU_RENDER_DEVICE:-/dev/dri/renderD128} + device_cgroup_rules: + - 'c 13:* rmw' + environment: + TZ: ${TZ} + PUID: ${PUID} + PGID: ${PGID} + UMASK: ${UMASK:-000} + USER_PASSWORD: ${USER_PASSWORD:-change-me} + MODE: ${MODE:-primary} + WEB_UI_MODE: ${WEB_UI_MODE:-vnc} + PORT_NOVNC_WEB: ${STEAM_WEB_PORT:-8083} + ENABLE_STEAM: ${ENABLE_STEAM:-true} + STEAM_ARGS: ${STEAM_ARGS:--silent} + ENABLE_SUNSHINE: "true" + SUNSHINE_USER: ${SUNSHINE_USER:-admin} + SUNSHINE_PASS: ${SUNSHINE_PASS:-change-me} + volumes: + - type: bind + source: /DATA/AppData/$AppID/moonlight-home + target: /home/default + - type: bind + source: /DATA/AppData/$AppID/moonlight-games + target: /mnt/games + +x-casaos: + architectures: + - amd64 + main: steam + category: Games + author: Zima Apps Team + developer: Steam-Headless community + icon: https://cdn.simpleicons.org/steam + tagline: + en_us: Steam web desktop with optional Moonlight profile + description: + en_us: >- + Browser-first Steam container with an explicit moonlight profile for higher + compatibility and controller support. The moonlight profile is opt-in and + carries additional security risk. + title: + en_us: Steam Moonlight (Scaffold) + index: / + port_map: ${STEAM_WEB_PORT:-8083} + scheme: http diff --git a/Apps/steam-moonlight/how_to_verify.md b/Apps/steam-moonlight/how_to_verify.md new file mode 100644 index 0000000..8b684f6 --- /dev/null +++ b/Apps/steam-moonlight/how_to_verify.md @@ -0,0 +1,107 @@ +# How To Verify + +Detta dokument verifierar båda Steam-apparna i repo: + +- `Apps/steam-headless` +- `Apps/steam-moonlight` + +## 1) Repo-validering + +Kör från repo-roten: + +```bash +./scripts/validate-appstore.sh --enforce-risk-docs +``` + +Förväntat: `Validation OK` eller `Validation OK with ... warning(s)`. + +## 2) Verifiera steam-headless (browser-first) + +Rendera compose: + +```bash +docker compose -f Apps/steam-headless/docker-compose.yaml config +``` + +Starta: + +```bash +docker compose -f Apps/steam-headless/docker-compose.yaml up -d steam +``` + +Kontroller: + +1. `docker compose -f Apps/steam-headless/docker-compose.yaml ps` visar `steam` som running. +2. Web UI nås på `${STEAM_HTTP_PORT:-3000}` eller `${STEAM_HTTPS_PORT:-3001}`. +3. Inga extra högriskflaggor används (`privileged`, `host network`, `docker.sock`). + +Stoppa: + +```bash +docker compose -f Apps/steam-headless/docker-compose.yaml down +``` + +## 3) Verifiera steam-moonlight defaultprofil + +Rendera compose (default): + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml config +``` + +Starta default service: + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam +``` + +Kontroller: + +1. `steam` är running. +2. Webdesktop nås på `${STEAM_WEB_PORT:-8083}`. +3. Defaultprofilen kör med låg-risk baseline (`cap_drop: ALL`, ingen `host network`). + +Stoppa: + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml down +``` + +## 4) Verifiera steam-moonlight moonlight-profil (opt-in) + +Preflight: + +1. Sätt starkt `SUNSHINE_PASS`. +2. Verifiera GPU devices (`GPU_CARD_DEVICE`, `GPU_RENDER_DEVICE`). +3. Verifiera `/dev/fuse` och `/dev/uinput` på host. + +Rendera moonlight-profil: + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight config +``` + +Starta: + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight up -d steam-moonlight +``` + +Kontroller: + +1. `steam-moonlight` är running. +2. Sunshine kräver autentisering. +3. Moonlight-klient kan ansluta från LAN/VPN. +4. Ingen oavsiktlig internetexponering av Sunshine-portar. + +Stoppa/rollback: + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml --profile moonlight down +``` + +Vid problem, återgå till defaultprofil: + +```bash +docker compose -f Apps/steam-moonlight/docker-compose.yaml up -d steam +```