Alleen documentatie. Op aanwijzing van de gebruiker bij het afsluiten: de suite meldt bij elke ronde dat python:3-alpine en nginx:alpine niet gepind zijn, en de verleiding is dat even te doen. Dat is de verkeerde volgorde. Pinnen is een eis van Publicatie, maar daarvoor gaat de app-inhoud eerst een eigen image in, en dan bestaan die twee niet meer als de plek waar onze code draait. De regel staat nu in KNOWLEDGE.md, want vier plannen raken hem en geen van de vier bezit hem: de eis komt uit Publicatie, de oorzaak zit in Eigenimage, en de taak stond in Umbrelapp en Appstore. Met twee grenzen erbij, anders slaat het de andere kant op door: de eigen image pin je wel meteen bij elke verhoging, en de melding in de suite blijft een afdruk en geen toets, zodat de suite niet rood staat tot Eigenimage klaar is. Onderweg bleek Eigenimage PLAN.md 8 achterhaald en misleidend. Daar stond dat het bouwrecept van Evolu Relay misschien zou vervallen zodra de kale relay de weg werd, en dat je er daarom niets aan moest verbeteren. Wij bouwen juist een eigen image, want de twee terugroepfuncties zitten niet in de gepubliceerde. En de paragraaf onderschatte wat er nog te doen is: ook bij die app staan de agent en de pagina nog op vreemde images, alleen de relay zelf is klaar. Herschreven, en de kolom App van dat plan in CONTINUE_HERE staat daarom op "beide" in plaats van op Gate. Verder de taak in Umbrelapp gemarkeerd als wachtend op Eigenimage in plaats van open, een verwijzing bovenaan Images-pinnen.md, en de regel voor Umbrelapp in CONTINUE_HERE ingekort en bijgewerkt naar 0.5.1. Geen tests gedraaid: er is niets buiten Docs/ geraakt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
180 lines
11 KiB
Markdown
180 lines
11 KiB
Markdown
# Eigenimage - plan
|
|
|
|
> **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.
|
|
>
|
|
> **Gepromoveerd van masterplan naar `Actief/` op 27-08-2026**, toen **Webinterface** afgerond was; dat was
|
|
> de volgorde die de gebruiker die dag afsprak. Het origineel staat in `Plannen/Masterplannen/Archief/` en
|
|
> is historie: hier wordt gewerkt.
|
|
>
|
|
> Taken staan in [TAKEN.md](TAKEN.md), de open beslissingen in [OPEN.md](OPEN.md). §7 en §9 hieronder zijn
|
|
> daarheen verhuisd en staan er niet meer; wat hier blijft is het ontwerp en de afweging.
|
|
|
|
## 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
|
|
|
|
Verhuisd naar [OPEN.md](OPEN.md) bij de promotie op 27-08-2026. Het gaat om drie vragen: blijft het
|
|
Gitea-register ook bij publicatie de bron, wordt het één image of twee, en waar wordt er gebouwd. De eerste
|
|
moet vóór de eerste taak beantwoord zijn.
|
|
|
|
Dit kopje blijft staan met deze verwijzing en is niet weggehaald, want de nummering van de paragrafen
|
|
hierna wordt elders aangehaald.
|
|
|
|
## 8. Wat dit voor Evolu Relay betekent
|
|
|
|
**Herschreven op 30-08-2026, want de vorige versie van deze paragraaf gokte verkeerd.** Daar stond dat het
|
|
bouwrecept van die app misschien zou vervallen omdat de kale `docker.io/evoluhq/relay:latest` de weg zou
|
|
worden, en dat je daarom niets aan dat recept moest verbeteren. Die verwachting is ingehaald: de app draait
|
|
sinds 28-08-2026 op een **eigen** image, omdat wij twee terugroepfuncties aan `createRelay` meegeven en die
|
|
in de gepubliceerde image niet zitten. Het recept in `tools/evolu-relay/` is dus geen tijdelijke toestand
|
|
maar de vaste weg.
|
|
|
|
Wat daarmee de stand is, en het is minder ver dan hier stond:
|
|
|
|
- **de relay zelf: klaar.** Eigen image, eigen recept, register gekozen, anonieme pull gecontroleerd, en
|
|
gepind op tag plus digest bij elke verhoging. Voor dat deel is dit plan uitgevoerd;
|
|
- **de agent en de pagina: niet.** Die zitten daar precies zoals bij Electrum Gate: `agent.py.template`,
|
|
`index.html.template` en `nginx.conf.template` in de app-map, gemount in `python:3-alpine` en
|
|
`nginx:alpine`. Alles in §1 tot §4 geldt dus onverkort ook voor die app;
|
|
- **multi-arch: open**, want ook dat recept bouwt vandaag één architectuur. Dat staat bij
|
|
**Publicatie-Relay**.
|
|
|
|
**De volgorde die hieruit volgt en die verder reikt dan dit plan:** zolang de agent en de pagina op vreemde
|
|
images draaien, valt er voor die twee niets zinnig te pinnen, want ze verdwijnen hier. Dat is de regel in
|
|
[KNOWLEDGE.md](../../../KNOWLEDGE.md), en Evolu Relay is er het tweede geval van.
|
|
|
|
Wat wél blijft gelden: **trek het werk aan de relay-image niet in dit plan.** Niet meer omdat het recept
|
|
misschien weggaat, maar omdat het dat níet doet en het al af is. Wat hier hoort is de agent en de pagina,
|
|
voor beide apps.
|
|
|
|
## 9. Waarom dit nú actief is
|
|
|
|
**Beslist door de gebruiker op 27-08-2026: na Webinterface**, en dat moment is er. Dat was dezelfde
|
|
afweging 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 dan ontbreekt.
|
|
**Webinterface** iterereerde die dag juist op de pagina, en dat was het werk dat er het meeste onder zou
|
|
lijden. Dat plan is dezelfde dag afgerond en naar tier B gezakt.
|
|
|
|
Het valt daarmee ook samen met het werk dat toch aan de compose gedaan moet worden vóór de inlevering uit
|
|
**Publicatie-Gate**: 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.
|
|
|
|
**Wat dit niet is: een harde afhankelijkheid.** Technisch kon dit plan altijd al. De volgorde was een
|
|
keuze, geen feit over het plan.
|