Eén app store, twee apps
umbrelOS leest per store één repo, dus twee apps in twee repo's kan niet. Deze repo is de store en bevat vanaf nu Electrum Gate en het werk aan Evolu Relay. Opgezet als verse repo op verzoek van de gebruiker: de historie van ElectrumTLS en van EvoluRelay komt niet mee. Dat heeft één gevolg dat verder gaat dan opruimen. In de historie van ElectrumTLS staat het domein van de gebruiker en het certificaatpad, van vóór de opschoning van 19-08. Die komt hier niet in. Zolang die repo op de Git-server blijft staan verandert dat niets, dus het weghalen ervan is het laatste stuk van open punt 3 van het plan Appstore, en geen bijzaak. De store zelf hoefde niet te veranderen: store-id whatsnext, en dus blijft het app-id whatsnext-electrum-gate. Dat hangt aan het store-id en niet aan de URL, dus voor umbrelOS is dit dezelfde app in een andere store. Dat de store op 19-08 naar de maker genoemd werd in plaats van naar deze ene app, betaalt zich hier uit. Wat de documentatie betreft is dit één wortel voor beide apps, en dat was de reden om samen te voegen en niet de prijs ervan: de appstore-spec, het pinnen van images en de werkwijze golden al voor allebei en stonden in twee repo's naast elkaar. De kruisverwijzing die daarvoor nodig was (Referenties/Umbrel-appstore.md in de oude EvoluRelay-repo) is verdwenen; wat daarin stond over de plekken waar de relay een ander geval is, staat nu als ontwerp in het masterplan Umbrelapp §4. Botsende namen kregen een achtervoegsel met de app, en alleen die: Publicatie werd Publicatie-Gate en Publicatie-Relay, CHANGELOG.md werd CHANGELOG-electrum-gate.md. Proefopstelling kreeg 007, tussen de twee bestaande nummers, zodat de bovenkant van de reeks op tier-orde blijft staan. CONTINUE_HERE.md heeft een kolom App, maar de tiers lopen over beide apps heen: er is één volgorde van werken. Electrum Gate gaat naar 0.0.15, want website, repo, support, submission en icon wijzen nu naar UmbrelApps en zonder versieverhoging rolt dat niet uit. De release notes leggen aan de gebruiker uit dat hij de store opnieuw moet toevoegen. Of een geïnstalleerde app een wisseling van store-URL overleeft is nog steeds niet uitgezocht; dat blijkt bij het omzetten. Twee dingen in de plannen van Electrum Gate waren door deze verhuizing niet meer waar en zijn bijgewerkt: de taak "de repo hernoemen" in fase 7 is afgevinkt, en de repo-vorm in PLAN.md §4a toonde nog de store-id electrumtls, die al sinds fase 7 achterhaald was. Tests: 39 goed 0 fout en 54 goed 0 fout, niets overgeslagen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
# Appstore - masterplan
|
||||
|
||||
> **Status: nog niet actief.** Dit is één bestand en dat is bewust: er is nog geen `TAKEN.md`,
|
||||
> `PROGRESS.md` of `OPEN.md`, want er wordt nog niet aan gewerkt. Bij promotie naar
|
||||
> `Plannen/Actief/NNN-Appstore/` worden de paragrafen hieronder over die vier bestanden verdeeld; zie
|
||||
> `HomeGit/Docs/Werkproces.md` §1b.
|
||||
>
|
||||
> Afhankelijk van: –
|
||||
|
||||
## 1. Doel
|
||||
|
||||
De app draait nu als een met de hand neergezette docker-compose die umbrelOS niet kent. Gevolg: na een
|
||||
herstart van de Umbrel, of als een app waar deze van afhangt omvalt, moet er met de hand
|
||||
`docker compose down` en `up` gedaan worden. Dit plan maakt er een echte Umbrel-app van in een eigen
|
||||
community app store: een tegel met icoon, die umbrelOS zelf installeert, start en na een herstart weer
|
||||
opbrengt.
|
||||
|
||||
Als dit af is, is de repo tegelijk de app store: de URL erin plakken in umbrelOS is genoeg om de app te
|
||||
installeren, en een `git push` is genoeg om een update uit te leveren. De repo staat op de eigen
|
||||
Git-server, `https://sc.kamenier-hamer.nl/sysop/ElectrumTLS.git`, en dat kan: umbreld doet geen enkele
|
||||
controle op de hostnaam. Zie §4e voor wat dat wél afdwingt.
|
||||
|
||||
## 2. Afbakening
|
||||
|
||||
- De repo omzetten naar de vorm die umbrelOS voor een community app store verwacht.
|
||||
- `docker-compose.yml` omzetten naar de moderne vorm: `app_proxy`, geen zelfgebouwd netwerk, geen
|
||||
handmatige host-poorten waar dat niet hoeft.
|
||||
- De Electrum-backend via de afhankelijkheid aanspreken in plaats van via een hardgecodeerde
|
||||
containernaam, zodat Electrs, Fulcrum en ElectrumX alle drie werken.
|
||||
- Een image die gepind kan worden, in plaats van `alpine:latest` met `apk add` bij elke start.
|
||||
- Het manifest compleet en eerlijk maken: eigen icoon, eigen gallery, kloppende velden.
|
||||
- De oude `install.sh` en `uninstall.sh` weghalen.
|
||||
|
||||
De volledige spec waar dit tegenaan moet, met bronvermelding per feit, staat in
|
||||
[Referenties/Umbrel-appstore-spec.md](../../Referenties/Umbrel-appstore-spec.md). Die is bij het schrijven
|
||||
van dit plan uitgezocht en hoeft niet opnieuw opgezocht te worden.
|
||||
|
||||
## 3. Niet-doelen
|
||||
|
||||
- **De hardgecodeerde waarden eruit halen.** Het domein `sync.kamenier-hamer.nl` en het Zoraxy-pad blijven
|
||||
in dit plan staan zoals ze zijn. Dat is het plan **Configuratie**, en het apart houden is bewust: een
|
||||
commit die tegelijk de structuur omgooit en de configuratie herontwerpt is niet meer na te lezen.
|
||||
Wel een harde koppeling: **de repo gaat pas naar GitHub als Configuratie af is**, want anders staat een
|
||||
persoonlijk domein en de indeling van een privé-server in een publieke repo. Zie open punt 3.
|
||||
- **De web-UI eerlijk maken.** De pagina toont verzonnen status. Dat is het plan **Webinterface**. Hier
|
||||
wordt de pagina alleen verhuisd en aan `app_proxy` gehangen, niet herschreven.
|
||||
- **Meerdere apps in de store.** De store krijgt de vorm die meer apps toelaat, maar er komt er één in.
|
||||
- **Indienen bij de officiële Umbrel App Store.** Een community store is er juist om dat niet te hoeven.
|
||||
Als het later toch aantrekkelijk wordt, is de spec-eis grotendeels dezelfde, dus dit sluit niets af.
|
||||
|
||||
## 4. Ontwerp
|
||||
|
||||
### 4a. De repo-vorm
|
||||
|
||||
```
|
||||
ElectrumTLS/
|
||||
├── umbrel-app-store.yml id: electrumtls
|
||||
├── electrumtls-electrum-tls/
|
||||
│ ├── umbrel-app.yml id: electrumtls-electrum-tls
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── entrypoint.sh
|
||||
│ └── web/index.html
|
||||
├── Docs/
|
||||
├── README.md
|
||||
└── CHANGELOG.md
|
||||
```
|
||||
|
||||
De store-id is `electrumtls`, gekozen op 18-08-2026. De prefix-eis is hard: mapnaam en manifest-`id`
|
||||
moeten gelijk zijn en allebei met de store-id beginnen.
|
||||
|
||||
### 4b. Backend-onafhankelijk, en waarom dat bijna niets kost
|
||||
|
||||
umbrelOS 1.3 heeft swappable dependencies. Fulcrum en ElectrumX declareren allebei `implements: [electrs]`
|
||||
en hun `exports.sh` aliast `APP_ELECTRS_IP`, `APP_ELECTRS_NODE_IP` en `APP_ELECTRS_NODE_PORT` naar hun
|
||||
eigen waarden. De gebruiker kiest de implementatie in de umbrelOS-instellingen; umbrelOS laadt de
|
||||
`exports.sh` van de gekozen app.
|
||||
|
||||
Deze app hoeft daarvoor dus **geen keuzemechanisme te bouwen**. Het is dit:
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
- electrs
|
||||
```
|
||||
|
||||
en in de compose `${APP_ELECTRS_NODE_IP}:${APP_ELECTRS_NODE_PORT}` gebruiken.
|
||||
|
||||
Twee vallen om te vermijden. De eerste: de huidige compose zet `ELECTRS_HOST=${APP_ELECTRS_IP}`, en dat
|
||||
is de **web-UI-container** van Electrs, niet de Electrum-server; dat moet `APP_ELECTRS_NODE_IP` worden.
|
||||
De tweede: alleen `IP`, `NODE_IP` en `NODE_PORT` worden gealiast, dus alles wat Electrs-specifiek is
|
||||
(zoals `APP_ELECTRS_RPC_HIDDEN_SERVICE`) mag hier niet gebruikt worden.
|
||||
|
||||
### 4c. De image: nginx `stream` in plaats van stunnel
|
||||
|
||||
Het huidige `alpine:latest` plus `apk add stunnel` bij elke start is op drie manieren fout: het is niet
|
||||
te pinnen, het faalt zonder internet, en het maakt de starttijd afhankelijk van een Alpine-mirror. De
|
||||
app-store-eis is een image gepind op de multi-arch index-digest.
|
||||
|
||||
Er zijn drie wegen, en de aanbeveling is de derde:
|
||||
|
||||
1. **Eigen image bouwen** met een `Dockerfile` en een GitHub Actions-workflow die multi-arch naar GHCR
|
||||
duwt. Correct, maar het voegt CI, een registry en een tweede uitleverstroom toe aan een app die verder
|
||||
uit twee shellscripts bestaat.
|
||||
2. **Een bestaande stunnel-image pinnen.** Er is geen onderhouden multi-arch stunnel-image die het
|
||||
vertrouwen waard is. Afgevallen.
|
||||
3. **De officiële `nginx`-image gebruiken en de `stream`-module de TLS-terminatie laten doen.** Die image
|
||||
is multi-arch, wordt onderhouden en is gewoon te pinnen. Dan valt er meer weg dan alleen het
|
||||
bouwprobleem:
|
||||
- dezelfde container serveert de web-UI én termineert TLS, dus van drie containers blijft er één over;
|
||||
- een certificaatwissel wordt `nginx -s reload` **binnen** de container, dus de `cert-monitor` heeft de
|
||||
Docker-socket niet meer nodig. Die socket is nu read-only gemonteerd, maar read-only op de
|
||||
Docker-socket beschermt niets: wie de socket kan lezen kan containers starten en is daarmee root op
|
||||
de host. Dat weghalen is de grootste beveiligingswinst in dit plan;
|
||||
- een reload verbreekt bestaande verbindingen niet, een containerherstart wel.
|
||||
|
||||
**Te verifiëren voordat hierop gebouwd wordt:** dat de officiële `nginx:alpine` daadwerkelijk met
|
||||
`--with-stream` en `--with-stream_ssl_module` gebouwd is. Dat is de aanname waar deze hele keuze op
|
||||
rust en hij is in één commando te controleren (`nginx -V`). Klopt hij niet, dan valt dit terug op weg 1.
|
||||
|
||||
De `awk`-splitsing van de certificaat-chain uit `entrypoint.sh` blijft bruikbaar en wordt overgenomen.
|
||||
|
||||
### 4e. De eigen Git-server als app store
|
||||
|
||||
De repo komt op `https://sc.kamenier-hamer.nl/sysop/ElectrumTLS.git`. umbreld valideert de URL alleen met
|
||||
de `URL`-constructor en kloont met isomorphic-git; er is geen GitHub-eis. Wat er wél uit die aanroep volgt
|
||||
en wat dus getest moet worden:
|
||||
|
||||
- **HTTPS, niet SSH.** De URL hierboven heeft de goede vorm.
|
||||
- **Anoniem kloonbaar.** umbreld geeft geen inloggegevens mee, dus de repo moet in Gitea op publiek
|
||||
staan. Een privérepo werkt niet, en er is geen omweg.
|
||||
- **Geldig certificaat op `sc.kamenier-hamer.nl`.** Node valideert de keten. Loopt die host al via
|
||||
Zoraxy met Let's Encrypt, dan is dit in orde, maar het is het controleren waard voordat het klonen
|
||||
onverklaarbaar faalt.
|
||||
- **Alles op de standaardbranch.** Er wordt met `depth: 1, singleBranch: true` gekloond, dus een tag of
|
||||
tweede branch levert niets op.
|
||||
- **De URL is de identiteit van de store.** Wijzigt hij, dan ziet umbrelOS een andere store en moet hij
|
||||
opnieuw toegevoegd worden. Kies hem dus één keer goed.
|
||||
|
||||
### 4d. Poorten
|
||||
|
||||
`port:` in het manifest is de **web-UI-poort** van de tegel, niet de TLS-poort. Dat staat nu op 50002 en
|
||||
is daarmee fout.
|
||||
|
||||
De TLS-poort blijft een gepubliceerde host-poort; daar helpt `app_proxy` niet, want dat is voor HTTP.
|
||||
Welke poort dat wordt is een open punt in **Configuratie**: Fulcrum bezet host-poort 50002 en botst dus
|
||||
met de huidige keuze.
|
||||
|
||||
## 5. Het werk in grote lijnen
|
||||
|
||||
**Fase 1 - De repo-vorm.** `umbrel-app-store.yml` erbij, de app-bestanden naar
|
||||
`electrumtls-electrum-tls/`, het app-id met prefix, `install.sh` en `uninstall.sh` eruit. Uitkomst: de
|
||||
repo heeft de vorm die umbrelOS herkent.
|
||||
|
||||
**Fase 2 - De compose.** `app_proxy` erin, het externe `umbrel_main_network` en de handmatige
|
||||
`APP_..._PORT`-plaatshouders eruit, de mounts op `${APP_DATA_DIR}` en `${UMBREL_ROOT}`. Uitkomst: een
|
||||
compose die umbrelOS zelf kan draaien.
|
||||
|
||||
**Fase 3 - Backend-onafhankelijk.** `dependencies: [electrs]` en `${APP_ELECTRS_NODE_IP}` /
|
||||
`${APP_ELECTRS_NODE_PORT}`. Uitkomst: de app werkt met Electrs, Fulcrum en ElectrumX zonder aanpassing.
|
||||
|
||||
**Fase 4 - De image.** `nginx:alpine` gepind op digest, `stream`-configuratie in plaats van stunnel,
|
||||
`cert-monitor` samengevoegd en de Docker-socket eruit. Uitkomst: één gepinde container, geen `apk add`
|
||||
bij start, geen socket.
|
||||
|
||||
**Fase 5 - Het manifest.** Eigen icoon en gallery in de repo, `port` op de web-UI-poort, `developer`,
|
||||
`repo`, `support`, `submitter` en `submission` kloppend, `website` naar de eigen repo. Uitkomst: een
|
||||
tegel die er klopt uitziet en niet naar andermans plaatjes wijst.
|
||||
|
||||
**Fase 6 - Installeren en verifiëren.** Store toevoegen in umbrelOS, installeren, en de dingen nalopen
|
||||
die alleen op het apparaat te zien zijn: start hij mee na een herstart, komt hij terug als Electrs
|
||||
omvalt, en werkt de TLS-verbinding vanaf een echte wallet.
|
||||
|
||||
## 6. Open punten
|
||||
|
||||
1. **Draait `nginx:alpine` met de `stream`- en `stream_ssl`-module?** De hele keuze uit §4c hangt hierop.
|
||||
**Moment:** als eerste taak van fase 4, vóór er iets herschreven wordt. **Eigenaar:** uitvoerder.
|
||||
|
||||
2. **Wat gebeurt er met een bestaande installatie?** Er draait nu een handmatig neergezette
|
||||
`electrum-tls` op de Umbrel. Die moet met de hand weg voordat de echte app geïnstalleerd wordt, anders
|
||||
vecht hij om de poort. Hoort daar een korte migratie-aanwijzing bij in de README, of doet de gebruiker
|
||||
dat eenmalig zelf? **Moment:** bij fase 6. **Eigenaar:** gebruiker.
|
||||
|
||||
3. **Wanneer wordt er voor het eerst gepusht?** **Beslist op 18-08-2026: meteen.** De repo staat sinds
|
||||
die dag publiek op `https://sc.kamenier-hamer.nl/sysop/ElectrumTLS.git`, met de
|
||||
installatiespecifieke waarden er nog in. Dat de repo publiek moest, stond niet ter discussie: umbreld
|
||||
kloont anoniem. Alleen de volgorde was een keuze, en die is bewust vóór **Configuratie** gevallen.
|
||||
|
||||
Het gevolg dat vastligt: **`sync.kamenier-hamer.nl` en het certificaatpad staan nu in de publieke
|
||||
historie.** Ze eruit halen in Configuratie haalt ze uit de bestanden, niet uit de historie; daarvoor
|
||||
zou de historie herschreven moeten worden, en dat is bij een repo die anderen al gekloond kunnen
|
||||
hebben geen schoonmaak maar een breuk. Behandel het domein dus als bekend, en laat het geen argument
|
||||
worden om Configuratie uit te stellen: de winst daarvan zit nu in herbruikbaarheid, niet meer in
|
||||
geheimhouding.
|
||||
|
||||
4. **Eigen icoon.** Het manifest wijst nu naar het Electrs-icoon in andermans repo. Er moet een eigen
|
||||
SVG komen en een gallery-plaatje. Wie maakt die, en waar staan ze (in de repo of extern gehost)?
|
||||
**Moment:** fase 5. **Eigenaar:** gebruiker.
|
||||
|
||||
## 7. Verificatie
|
||||
|
||||
Er zijn geen tests in dit project en die zijn hier ook niet zinvol: de app is configuratie, geen code.
|
||||
Wat er wél moet, en wat per se handmatig op het apparaat gebeurt:
|
||||
|
||||
- de store laat zich in umbrelOS toevoegen en de app verschijnt met icoon en tegel;
|
||||
- installeren via de umbrelOS-interface werkt zonder SSH;
|
||||
- **na `sudo reboot` komt de app vanzelf terug.** Dit is de aanleiding voor het hele plan en dus de
|
||||
belangrijkste controle;
|
||||
- de app komt ook terug nadat Electrs handmatig gestopt en gestart is;
|
||||
- een Electrum-wallet verbindt over TLS en verifieert het certificaat;
|
||||
- omschakelen naar Fulcrum in de umbrelOS-instellingen laat de app werken zonder aanpassing.
|
||||
|
||||
Wat automatisch gecontroleerd kan worden, en de moeite waard is omdat het de fouten vangt die je niet
|
||||
ziet: dat de YAML geldig is, dat het `id` in het manifest gelijk is aan de mapnaam, en dat elke `image:`
|
||||
een `@sha256:`-digest heeft.
|
||||
Reference in New Issue
Block a user