164 lines
9.7 KiB
Markdown
164 lines
9.7 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
|
||
|
|
|
||
|
|
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. 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.
|