Files
UmbrelApps/Docs/Plannen/Actief/006-Eigenimage/PLAN.md
T
HarmenandClaude Opus 5 940b2582f9 Webinterface is af en zakt naar B, Eigenimage neemt het over
De opruimronde eerst. Zes vinkjes stonden open terwijl het werk gedaan was: open
punt 5, fase 5, "draaien op de Umbrel", "verifiëren tegen een echte status.json",
en het nakijken van de eerste indeling op een breed scherm, een indeling die na
fase 6 niet meer bestaat. Elk staat nu afgevinkt met de reden erbij, want een
regel wegpoetsen laat de vraag "is dit ooit gebeurd" open.

Ook de regel "Niets" onder Geblokkeerd is geen vinkje meer. Een leeg vakje bij
het woord niets telt mee zodra iemand de openstaande punten telt, en dat is
precies wat die kop moet uitsluiten.

Wat er in Webinterface overblijft is niet te plannen of ligt bij de gebruiker:
een etmaal wachten op het log, waar Nginx Proxy Manager zijn certificaten
neerzet, en of Zoraxy een harde afhankelijkheid wordt. Vandaar tier B.

Eigenimage is daarmee gepromoveerd naar Actief met nummer 006 en tier A, zoals
op 27-08 afgesproken. Het masterplan is omgezet: de drie open beslissingen zijn
naar OPEN.md gegaan, het werk naar TAKEN.md in vier fasen, en PLAN.md houdt het
ontwerp. Het origineel blijft nog even staan; dat verhuist pas naar Archief nu
deze commit er is.

De eerste stap daar is geen bouwtaak maar een vraag: blijft het Gitea-register
ook bij publicatie de bron.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-27 16:42:56 +02:00

9.7 KiB

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, de open beslissingen in 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 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.