diff --git a/Docs/CONTINUE_HERE.md b/Docs/CONTINUE_HERE.md index d9b48b9..49039bf 100644 --- a/Docs/CONTINUE_HERE.md +++ b/Docs/CONTINUE_HERE.md @@ -64,6 +64,7 @@ daaronder, dus deze tabel en de mapinhoud kunnen niet uit elkaar lopen. | [Bereikbaarheid.PLAN.md](Plannen/Masterplannen/Bereikbaarheid.PLAN.md) | Relay | Umbrelapp: er valt niets bereikbaar te maken zolang er niets draait | Synchroniseren buiten het thuisnetwerk. **Suite eist geen TLS**, dus Tailscale blijft open en een certificaat is geen voorwaarde. Het risico van een publiek eindpunt is niet vertrouwelijkheid (dat regelt de versleuteling) maar misbruik als gratis opslag: een kale relay kent geen accounts. Wil je tóch open, dan is een eigenaars-allowlist nodig; drie manieren in §4b | | [Publicatie-Relay.PLAN.md](Plannen/Masterplannen/Publicatie-Relay.PLAN.md) | Relay | Umbrelapp, plus een image die te pinnen valt | Inleveren bij de officiële appstore. Twee dingen kunnen dit blokkeren: een image die niet als multi-arch digest in een registry bestaat, en de eis dat de umbrelOS-inlog aan blijft terwijl de relay een cliënt zonder sessie moet bedienen | | [Publicatie-Gate.PLAN.md](Plannen/Masterplannen/Publicatie-Gate.PLAN.md) | Gate | Appstore: de herstart-controle | **Doel van de gebruiker sinds 20-08-2026:** de app inleveren als standaard-app voor Umbrel. Dat verandert de maatstaf van "hij werkt hier" naar "iemand anders keurt het pakket goed". Het meeste is al goed; wat er nog moet is de images pinnen, het app-id kaal maken en de manifestvelden op orde. Het risico zit niet in die lijst maar in de leesmount op de certificaten van Zoraxy | +| [Eigenimage.PLAN.md](Plannen/Masterplannen/Eigenimage.PLAN.md) | Gate | – | Van de code die nu uit `app-data` gemount wordt een eigen image maken, in het eigen Gitea-register. **Het lost níet het updateprobleem op**, want alle code staat al in een `*.template` en die staan in de whitelist. Wat het wel doet: code uit `app-data`, het shell-blok van honderd regels uit de compose, en één eigen digest in plaats van twee vreemde. Kosten: een bouwronde per wijziging, en multi-arch is nog nooit geprobeerd | | [Configuratie.PLAN.md](Plannen/Masterplannen/Configuratie.PLAN.md) | Gate | – | **Grotendeels ingehaald op 19-08-2026** en moet opgeschoond worden voordat promotie nog zin heeft: de agent doet de certificaatbronnen en de keuze al, en het hardgecodeerde domein is uit de compose en uit `nginx.conf.template` verdwenen. Wat er nog in zit is een configuratiebestand voor de poort- en padoverstemmingen, plus de README | Cross-plan kennis staat in [KNOWLEDGE.md](KNOWLEDGE.md). Naslag staat niet in deze boom maar in diff --git a/Docs/Plannen/Masterplannen/Eigenimage.PLAN.md b/Docs/Plannen/Masterplannen/Eigenimage.PLAN.md new file mode 100644 index 0000000..7d83c67 --- /dev/null +++ b/Docs/Plannen/Masterplannen/Eigenimage.PLAN.md @@ -0,0 +1,171 @@ +# Eigenimage - masterplan + +> **App: Electrum Gate**, met een korte paragraaf over wat het voor Evolu Relay betekent (§8). Voorgesteld +> door de gebruiker op 27-08-2026: van de uitvoerbare bestanden die nu in de app-map staan een image maken +> en die in het eigen Gitea-register zetten. +> +> Nog geen tier en geen nummer. Wat er eerst beslist moet worden staat in §7, en het moment staat in §9. + +## 1. Waar dit over gaat, en wat het uitdrukkelijk níet oplost + +Electrum Gate is de enige app in deze store zonder eigen image. Hij draait op `python:3-alpine` en +`nginx:alpine` en mount zijn eigen programmacode uit `app-data`. Dat is geen ongeluk maar een besluit uit +het plan **Appstore**: geen eigen image bouwen betekende toen geen bouwstap, geen register en geen +inloggegevens, en de app werkte. + +Dit plan stelt dat besluit ter discussie, en het begint met wat het **niet** is: + +**Dit is geen oplossing voor het updateprobleem, want dat is er niet meer.** De valkuil die dit project een +dag gekost heeft is dat een update alleen een whitelist ververst. Maar `*.template` staat in die whitelist, +en alle code van deze app staat inmiddels in een `.template`-bestand: `agent.py.template`, +`index.html.template`, `nginx.conf.template` en `stream.conf.template`. Een `git push` met een +versieverhoging bereikt een bestaande installatie dus gewoon. Wie dit plan verkoopt met "dan komen +wijzigingen eindelijk aan", verkoopt iets wat al werkt. + +Er is één uitzondering en die is echt: **`icon.png` is geen template** en bereikt een bestaande installatie +nooit. Dat staat als zodanig in de compose. Voor een plaatje dat vrijwel nooit wijzigt is dat goed genoeg, +en het is te klein om dit plan op te bouwen. + +Wat het wél is, staat in §3. + +## 2. Wat er vandaag uit `app-data` gemount wordt + +De inventaris, want dit is precies de lijst die in een image zou verdwijnen. + +| Bestand | Container | Wat het is | +|-|-|-| +| `agent.py` | agent | het programma: certificaten lezen, de Electrum-server bevragen, `status.json` schrijven, de keuze aannemen | +| `nginx.conf` | server | de configuratie van de pagina en de proxy naar de agent | +| `stream.conf` | server | het TLS-blok voor poort 50022, bewust apart | +| `index.html` | server | het dashboard | +| `icon.png` | server | het plaatje in de kop en het tabblad | +| het `command`-blok | server | ruim honderd regels shell in `docker-compose.yml`: log-format, TLS aan- en uitzetten, de sessieteller en de herlaadlus | + +Die laatste regel is de interessantste. Dat blok staat in de compose omdat de compose in de whitelist +staat, en het moet daar dollartekens ontsnappen als `$$` omdat umbreld elk `${...}` in een template +leegmaakt. Het is dus shell in een YAML-string met een eigen ontsnappingsregel eroverheen: het enige stuk +van deze app waar de vorm door de verpakking bepaald wordt en niet door wat het doet. + +## 3. Wat een eigen image oplevert + +Op volgorde van hoe zwaar het weegt. + +1. **De programmacode gaat uit `app-data`.** Dat is de afwijking die de gebruiker zelf opmerkte op + 20-08-2026, uitgezocht in `Umbrel-appstore-spec.md`: bij andere apps staat in `app-data` alleen + configuratie en data, want hun code zit in een image. Voor eigen gebruik is dat cosmetisch. Voor het + masterplan **Publicatie-Gate** is het meer dan dat, want daar kijkt iemand anders naar het pakket. +2. **Het `command`-blok wordt een gewoon script.** Een `entrypoint.sh` in de image is te lezen, te + controleren en desnoods te testen, en hoeft geen dollartekens te verdubbelen. Dat is de grootste + inhoudelijke winst en de enige die de code zelf beter maakt. +3. **Eén digest in plaats van twee vreemde.** De pin-eis uit **Publicatie-Gate** gaat nu over + `python:3-alpine` en `nginx:alpine`, images van iemand anders die bij elke beveiligingsupdate opnieuw + gepind moeten worden. Met een eigen image pin je één ding dat je zelf uitgeeft. Let op de andere kant + hiervan: de basisimage zit dan ín jouw image, dus het onderhoud verdwijnt niet, het verhuist naar het + bouwrecept. +4. **`icon.png` wordt updatebaar**, zie §1. + +## 4. Wat het kost, en dit is de reden dat het moment ertoe doet + +**Elke wijziging wordt een bouwronde.** Vandaag is een wijziging aan het dashboard: bestand aanpassen, +`version` ophogen, committen, in umbrelOS updaten. Met een eigen image wordt dat: aanpassen, bouwen, naar +het register duwen, de digest opzoeken, de compose bijwerken, `version` ophogen, committen, updaten. Dat is +geen ramp, maar het is een veelvoud, en het moet op de machine met Docker gebeuren en niet op de machine +waar geschreven wordt. + +Dat is precies het probleem met "nu": het plan **Webinterface** staat op tier A en itereert op +`index.html.template`. Een bouwronde per UI-wijziging remt het plan dat op dit moment het meeste oplevert. + +**Multi-arch is een tweede kostenpost.** De eis is `linux/amd64` én `linux/arm64` in de manifest-lijst. De +Umbrel van de gebruiker is amd64 (vastgesteld 20-08-2026 uit de nginx-startlog), dus een `docker build` +daar levert de helft. Dat vraagt `buildx` met QEMU, en dat is trager en kan bij een Python-image met +gecompileerde afhankelijkheden stukgaan. Deze app heeft die afhankelijkheden niet, dus de kans is klein, +maar hij is niet nul en het is nog nooit geprobeerd. + +## 5. Het register: Gitea werkt, en dat is bewezen + +Dit is het deel waar het minste onzeker aan is, want de weg is al een keer gelopen. + +Op 25-08-2026 faalde de eerste installatie van Evolu Relay met `pull access denied` op een image die alleen +lokaal gebouwd was. De verklaring staat in `Umbrel-appstore-spec.md`: umbreld haalt elke image zelf op via +de Docker Engine API, dus lokaal bouwen bestaat niet voor hem en `pull_policy: never` verandert daar niets +aan. De oplossing werd het Gitea-register op dezelfde server als de store, +`sc.kamenier-hamer.nl/sysop/evolu-relay`, gepind op tag plus digest. + +Twee dingen zijn daarbij al vastgesteld en gelden hier onverkort: + +- **anoniem halen moet werken**, want umbreld krijgt geen inloggegevens mee. Controleer dat met een + uitgelogde pull in dezelfde context waarin je inlogde, anders meet je je eigen sessie. Het commando staat + onderaan `tools/evolu-relay/build.sh`; +- **het bouwrecept hoort in `tools/`**, nooit in de app-map. Een `Dockerfile` staat niet in de + update-whitelist, dus bouwen-in-de-app kost bij elke versie een deïnstallatie. + +## 6. Hoe het eruit zou zien + +Eén image, niet twee. De agent en nginx blijven wel twee containers, want ze doen verschillend werk en de +sessieteller moet in de netwerk-namespace van nginx zitten; maar één image met beide erin scheelt een +bouwrecept, en `nginx` plus `python3` in één alpine is klein. + +``` +tools/electrum-gate/ + Dockerfile de basisimage, agent.py, de nginx-configuratie, de pagina, entrypoint.sh + build.sh pin op de basisimage, bouwt multi-arch, duwt naar het register, drukt de digest af +``` + +Wat er in de app-map overblijft: `docker-compose.yml`, `umbrel-app.yml`, `icon.png` en `data/` met zijn +twee `.gitkeep`-bestanden. De compose houdt zijn `environment`-blok, want dat is hoe +`${APP_ELECTRS_NODE_IP}` binnenkomt, en die weg is op 27-08-2026 juist bewezen bij de omschakeling naar +Fulcrum. + +Eén ding om bij het ontwerp niet over te slaan: `index.html.template` bevat vandaag +`${APP_ELECTRS_NODE_IP}:${APP_ELECTRS_NODE_PORT}`, ingevuld door umbreld bij het starten. Zit de pagina in +de image, dan bestaat die invulling niet meer en moet het adres langs de omgeving naar binnen, bijvoorbeeld +doordat de agent het in `status.json` zet en de pagina het daaruit leest. Dat is werk dat nu nog gratis is +en straks niet meer. + +## 7. Open punten + +1. **Blijft het Gitea-register ook bij publicatie de bron?** Voor eigen gebruik is het antwoord ja, en het + is bewezen. Voor het masterplan **Publicatie-Gate** zitten er twee bezwaren aan die geen van beide een + spec-eis zijn maar allebei echt: + + - **het domein van de gebruiker komt in de compose van een publieke repo**, en dat is precies wat het + plan **Configuratie** eruit gehaald heeft. Nu staat het in de store-URL van een repo die niemand + aangekondigd heeft; dan zou het in het pakket staan dat aan de officiële store aangeboden wordt; + - **iedereen die de app installeert haalt dan een image van de thuisserver van de gebruiker.** Dat maakt + die server een afhankelijkheid van andermans installatie, met het verkeer en de beschikbaarheid die + daarbij horen. + + De spec eist alleen `registry/repo:versie-of-commit@sha256:` met beide architecturen, en zegt + niets over wélk register. Gitea voldoet dus aan de letter. De vraag is of je dat wilt. + **Moment:** voordat dit actief wordt · **Eigenaar:** gebruiker + +2. **Eén image of twee?** §6 stelt één voor. Twee is netter gescheiden en verdubbelt het bouwwerk. + **Moment:** bij de start van het werk · **Eigenaar:** sessie, met de gebruiker mee + +3. **Waar wordt gebouwd?** Op de Umbrel staat Docker, maar dat is een productiemachine en amd64. Bouwen op + de werkplek van de gebruiker vraagt daar Docker. + **Moment:** bij de start van het werk · **Eigenaar:** gebruiker + +## 8. Wat dit voor Evolu Relay betekent + +Voor die app is dit plan grotendeels al uitgevoerd: `tools/evolu-relay/build.sh` bestaat, het register is +gekozen en de anonieme pull is gecontroleerd. Wat hier eventueel bijkomt is de multi-arch-stap, want ook +dat recept bouwt vandaag één architectuur. + +**Trek dat werk niet in dit plan.** Het plan **Umbrelapp** staat op tier A met de conclusie dat de +gepakketteerde relay in de kern niet kan werken, en dat de volgende stap de kale +`docker.io/evoluhq/relay:latest` is. Wordt dat de weg, dan is er een gepubliceerde image en vervalt het +hele bouwrecept. Iets verbeteren aan een recept dat misschien weggaat, is de verkeerde volgorde. + +## 9. Wanneer dit actief zou moeten worden + +**Niet nu, en om dezelfde reden als waarom de pin-eis in Publicatie-Gate op "niet nu doen" staat:** zolang +er nog gedraaid en verbeterd wordt, betaalt elke wijziging de bouwronde uit §4 en levert het niets op wat +er vandaag ontbreekt. + +Het natuurlijke moment is als **Webinterface** klaar is met itereren op de pagina, en vóór de inlevering +uit **Publicatie-Gate**. Dan valt dit samen met het werk dat toch aan de compose gedaan moet worden: het +pinnen en het kaal maken van het app-id vragen allebei een herinstallatie, en die kun je één keer doen in +plaats van drie keer. + +Harde afhankelijkheid heeft dit plan niet. Het kan technisch morgen.