feat: real remote desktop (Webtop) + OS v5 launcher integration
- Full Linux XFCE desktop in the browser at desktop.atlascorporation.nl (Selkies/WebRTC, Ubuntu 26.04), gated by Caddy basic_auth + TLS - Claude Code CLI + Chromium pre-installed; one-click desktop launchers - runs on loopback only; auth enforced at the Caddy edge - web/os.html: OS v5 adds Remote Desktop app (39 apps total) - docs/remote-desktop.md + deploy/webtop-docker-compose.yml
This commit is contained in:
parent
51b47c103e
commit
449133f470
3 changed files with 49 additions and 2 deletions
19
deploy/webtop-docker-compose.yml
Normal file
19
deploy/webtop-docker-compose.yml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
services:
|
||||||
|
webtop:
|
||||||
|
image: lscr.io/linuxserver/webtop:ubuntu-xfce
|
||||||
|
container_name: atlas-webtop
|
||||||
|
security_opt:
|
||||||
|
- seccomp:unconfined
|
||||||
|
environment:
|
||||||
|
- PUID=0
|
||||||
|
- PGID=0
|
||||||
|
- TZ=Europe/Amsterdam
|
||||||
|
- TITLE=Atlas Desktop
|
||||||
|
- CUSTOM_USER=${WEBTOP_USER}
|
||||||
|
- PASSWORD=${WEBTOP_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- /opt/atlas/webtop/config:/config
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8131:3000"
|
||||||
|
shm_size: "2gb"
|
||||||
|
restart: unless-stopped
|
||||||
27
docs/remote-desktop.md
Normal file
27
docs/remote-desktop.md
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# Atlas Remote Desktop
|
||||||
|
|
||||||
|
A **real Linux desktop in the browser** — not a web app. Full XFCE on Ubuntu 26.04,
|
||||||
|
streamed via Selkies/WebRTC, where you can run any application: Claude Code, Chromium,
|
||||||
|
a terminal, editors, anything you apt-install.
|
||||||
|
|
||||||
|
**URL:** https://desktop.atlascorporation.nl (login at the Caddy edge)
|
||||||
|
|
||||||
|
## Why a real desktop
|
||||||
|
Unlike a headless server, a desktop has a browser — so the Claude Code OAuth login
|
||||||
|
flow works normally. Open the terminal, run `claude`, log in through Chromium. Done.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
- **Image:** lscr.io/linuxserver/webtop:ubuntu-xfce (Selkies/WebRTC)
|
||||||
|
- **Bind:** 127.0.0.1:8131 (loopback only — never exposed directly)
|
||||||
|
- **Edge:** Caddy reverse_proxy + basic_auth (TLS via Let's Encrypt)
|
||||||
|
- **Persistence:** /opt/atlas/webtop/config (home survives restarts)
|
||||||
|
- **Pre-installed:** Claude Code CLI (on PATH), Chromium, XFCE terminal;
|
||||||
|
desktop launchers for Claude + Chromium
|
||||||
|
|
||||||
|
## Compose
|
||||||
|
See `deploy/webtop-docker-compose.yml`. Credentials live in a local `.env`
|
||||||
|
(gitignored) and the Caddy basic_auth hash — never committed.
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
- Migrate edge auth from Caddy basic_auth to Authentik SSO (consistent identity)
|
||||||
|
- Optional: pin Claude to the Max subscription via the in-desktop browser login
|
||||||
|
|
@ -153,9 +153,10 @@ var apps=[
|
||||||
{id:"s_bec",name:"Budget Energie",icon:"ti-bolt",c:"#e0a234",url:"https://budgetenergiecoach.nl"},
|
{id:"s_bec",name:"Budget Energie",icon:"ti-bolt",c:"#e0a234",url:"https://budgetenergiecoach.nl"},
|
||||||
{id:"s_hki",name:"HKinterCare",icon:"ti-heart",c:"#e2655f",url:"https://hkintercare.nl"},
|
{id:"s_hki",name:"HKinterCare",icon:"ti-heart",c:"#e2655f",url:"https://hkintercare.nl"},
|
||||||
{id:"s_jea",name:"Jouw Energie",icon:"ti-sun",c:"#e0a234",url:"https://jouwenergieadvies.nl"},
|
{id:"s_jea",name:"Jouw Energie",icon:"ti-sun",c:"#e0a234",url:"https://jouwenergieadvies.nl"},
|
||||||
{id:"s_rm",name:"ReclameMans",icon:"ti-speakerphone",c:"#4ec98a",url:"https://reclamemans.nl"}
|
{id:"s_rm",name:"ReclameMans",icon:"ti-speakerphone",c:"#4ec98a",url:"https://reclamemans.nl"},
|
||||||
|
{id:"desktop",name:"Remote Desktop",icon:"ti-device-desktop",c:"#9b8cf0",url:"https://desktop.atlascorporation.nl"}
|
||||||
];
|
];
|
||||||
var CATS={today:"Cockpit",money:"Cockpit",inbox:"Cockpit",pipeline:"Cockpit",fleet:"Cockpit",control:"Cockpit",auth:"Identity",vault:"Identity",chat:"AI",llm:"AI",mindmap:"AI",leer:"AI",odoo:"Work",cfo:"Work",bank:"Work",paperless:"Work",office:"Work",cal:"Work",files:"Files & Comms",mailadmin:"Files & Comms",relay:"Files & Comms",git:"Ops",n8n:"Ops",uptime:"Ops",mesh:"Ops",map:"Ops",arch:"Ops",s_works:"Sites",s_corp:"Sites",s_agency:"Sites",s_academy:"Sites",s_pos:"Sites",s_hub:"Sites",s_bicos:"Sites",s_bec:"Sites",s_hki:"Sites",s_jea:"Sites",s_rm:"Sites"};
|
var CATS={today:"Cockpit",money:"Cockpit",inbox:"Cockpit",pipeline:"Cockpit",fleet:"Cockpit",control:"Cockpit",auth:"Identity",vault:"Identity",chat:"AI",llm:"AI",mindmap:"AI",leer:"AI",odoo:"Work",cfo:"Work",bank:"Work",paperless:"Work",office:"Work",cal:"Work",files:"Files & Comms",mailadmin:"Files & Comms",relay:"Files & Comms",git:"Ops",n8n:"Ops",uptime:"Ops",mesh:"Ops",map:"Ops",arch:"Ops",s_works:"Sites",s_corp:"Sites",s_agency:"Sites",s_academy:"Sites",s_pos:"Sites",s_hub:"Sites",s_bicos:"Sites",s_bec:"Sites",s_hki:"Sites",s_jea:"Sites",s_rm:"Sites",desktop:"Ops"};
|
||||||
function eur(n){try{return new Intl.NumberFormat("nl-NL",{style:"currency",currency:"EUR"}).format(n);}catch(e){return "€"+n;}}
|
function eur(n){try{return new Intl.NumberFormat("nl-NL",{style:"currency",currency:"EUR"}).format(n);}catch(e){return "€"+n;}}
|
||||||
function esc(s){return String(s==null?"":s).replace(/[&<>]/g,function(c){return{"&":"&","<":"<",">":">"}[c];});}
|
function esc(s){return String(s==null?"":s).replace(/[&<>]/g,function(c){return{"&":"&","<":"<",">":">"}[c];});}
|
||||||
function netHealth(ok){var w=document.getElementById("tbwifi");if(!w)return;w.style.color=ok?"#4ec98a":"#e2655f";w.className="ti "+(ok?"ti-wifi":"ti-wifi-off");w.title=ok?"Live data connected":"Live data unavailable";}
|
function netHealth(ok){var w=document.getElementById("tbwifi");if(!w)return;w.style.color=ok?"#4ec98a":"#e2655f";w.className="ti "+(ok?"ti-wifi":"ti-wifi-off");w.title=ok?"Live data connected":"Live data unavailable";}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue