Evolu Relay als tweede app in de store, plus het bouwrecept
De gebruiker koos ervoor het pakket meteen te maken en een installatie te proberen, met de image lokaal gebouwd en het recept in de repo. Dit is dat pakket. Er is nog niets gebouwd en niets geinstalleerd; "gebouwd" is hier nadrukkelijk niet "werkend". De zwaarste ontwerpvraag is met een precedent beslecht en niet met een gok. Trezor Suite is geen browser met een sessiecookie en kan dus niet achter de inlog van umbrelOS; het was onduidelijk of PROXY_AUTH_ADD "false" dan verantwoord is of een omweg. De eigen nostr-relay-app van Umbrel doet exact hetzelfde, om precies dezelfde reden, en heeft ook geen eigen ports:. De prijs staat in de compose en in het plan: wie die poort bereikt, bereikt de relay. Wat de schade beperkt is dat de relay elke eigenaar zonder limietenrij weigert. Daarom gaat de quota-manager mee, en dat is geen restje van Trezor's betaalde hosting: hij is wat die rijen aanmaakt. Relay en quota-manager komen uit dezelfde image met een ander command, want bovenstrooms is het een codebase met meerdere startscripts. Het command staat expliciet en leunt niet op de CMD van de Dockerfile, waar yarn start staat met bovenstrooms zelf een twijfel erbij. Het bouwrecept staat in tools/ en niet in de app-map. Dat is geen netheid: een Dockerfile staat niet in de update-whitelist, dus bouwen-in-de-app zou elke nieuwe versie een deinstallatie plus herinstallatie kosten. Onder tools/ en niet onder build/, want dat laatste staat in .gitignore als bouwselmap en het recept zou stilzwijgend buiten de repo zijn gebleven. Dat kwam pas bij git status aan het licht. De poort is 3851 en niet 4000. 4000 is de eigen poort van de relay maar ook een veelgebruikte poort, en een botsing op de host merk je pas als de app niet start. Die les komt van 50002 tegen Fulcrum. Nieuw testbestand test_appstore_vorm.py, en het gaat over de store en niet over een app: id gelijk aan mapnaam, store-voorvoegsel, veldvolgorde, app_proxy die naar een bestaande service wijst, en elke gemounte map die in de repo bestaat. Het vindt zijn apps zelf, dus een derde app valt er automatisch onder. Digests toetst het expres niet: geen van de twee apps haalt die regel vandaag en een suite die altijd rood staat wordt niet gelezen. Mutatie-getest met drie ingrepen: het app-id laten afwijken van de mapnaam, APP_HOST naar een niet-bestaande service laten wijzen, en de .gitkeep weghalen. Alle drie vielen om bij de juiste toets, en git diff was daarna leeg. Umbrelapp is gepromoveerd naar Actief als 008, tussen Proefopstelling en Appstore, en het masterplan is naar het archief. Wat er in de plannen als open blijft staan is niet klein: of Trezor Suite dit adres accepteert, of het databaseschema zichzelf aanmaakt, en hoe je een eigenaar registreert. Tests: 32 goed 0 fout, 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:
@@ -10,7 +10,7 @@ gelden, dan per app wat alleen daar geldt.
|
||||
| App | Map | Toestand |
|
||||
|-|-|-|
|
||||
| **Electrum Gate** | `whatsnext-electrum-gate/` | draait op de Umbrel, wordt gebruikt |
|
||||
| **Evolu Relay** | nog niet | bestaat uit plannen; zie het plan **Proefopstelling** |
|
||||
| **Evolu Relay** | `whatsnext-evolu-relay/` | gepakketteerd, nog nooit geïnstalleerd; zie het plan **Umbrelapp** |
|
||||
|
||||
**Zet geen CLAUDE.md of andere werkbestanden in een app-map.** umbreld kopieert bij installatie de héle
|
||||
app-map naar `~/umbrel/app-data/<app-id>/` met `rsync --archive`, dus alles wat daar staat belandt op het
|
||||
@@ -57,9 +57,20 @@ python tests/test_agent_certificates.py
|
||||
python tests/test_server_start_zonder_certificaat.py
|
||||
```
|
||||
|
||||
Geen testrunner en geen afhankelijkheden: het zijn losse scripts die 0 teruggeven als alles goed is. Beide
|
||||
horen bij "de suite", dus beide draaien voor een commit die deze app raakt. De uitvoer eindigt met een
|
||||
regel "N goed, M fout". Er is geen watch-modus; de suite kost minder dan een seconde.
|
||||
Deze twee gaan over Electrum Gate en noemen die app-map bij naam. Er is een derde die over de **store**
|
||||
gaat en zijn apps zelf vindt, dus over beide:
|
||||
|
||||
```
|
||||
python tests/test_appstore_vorm.py
|
||||
```
|
||||
|
||||
Geen testrunner en geen afhankelijkheden: het zijn losse scripts die 0 teruggeven als alles goed is. Alle
|
||||
drie horen bij "de suite" en draaien voor een commit; de uitvoer eindigt met een regel "N goed, M fout".
|
||||
Er is geen watch-modus; de suite kost minder dan een seconde.
|
||||
|
||||
`test_appstore_vorm.py` toetst **expres niet** dat images op een digest gepind zijn. Dat is wél de regel,
|
||||
maar geen van de twee apps haalt hem vandaag, en een suite die altijd rood staat wordt niet gelezen. Hij
|
||||
drukt de pinstatus wel af.
|
||||
|
||||
Twee dingen om te weten voordat je een groene uitslag vertrouwt:
|
||||
|
||||
@@ -96,16 +107,29 @@ dan een app die weigert en zegt waarom.
|
||||
|
||||
## Evolu Relay
|
||||
|
||||
**Er is nog geen manifest, geen compose en geen code, en die horen er ook nog niet te komen.** Het eerste
|
||||
dat er moet komen is een antwoord, niet een bestand: zie [Docs/CONTINUE_HERE.md](Docs/CONTINUE_HERE.md).
|
||||
Speculatieve pakketbestanden zouden geschreven worden op aannames die het plan **Proefopstelling** juist
|
||||
moet toetsen.
|
||||
|
||||
**De relay-code is niet van ons.** Dit pakketteert `trezor/trezor-suite-sync`; er worden geen wijzigingen
|
||||
aan die software gedaan en er wordt niet bovenstrooms bijgedragen.
|
||||
|
||||
**Er zijn geen tests, want er is geen bron.** Werkte een sessie uitsluitend aan deze app en aan
|
||||
documentatie, dan vervalt stap 4 van het sessie-protocol.
|
||||
**Het bouwrecept staat in `tools/evolu-relay/`, nooit in de app-map.** Trezor publiceert geen image, dus er
|
||||
is een bouwstap. Die hoort niet in `whatsnext-evolu-relay/`: een `Dockerfile` staat niet in de
|
||||
update-whitelist, dus bouwen-in-de-app kost bij elke nieuwe versie een deïnstallatie plus herinstallatie.
|
||||
Wat wij toevoegen aan hun Dockerfile is uitsluitend de **pin** op een commit; bouw hun stappen niet na.
|
||||
|
||||
**Verhoog je de pin in `build.sh`, dan verhoog je ook `version` in het manifest.** Anders is er een nieuwe
|
||||
image en een oude installatie, zonder dat iets dat meldt.
|
||||
|
||||
**De app-proxy staat op `PROXY_AUTH_ADD: "false"` en dat is met opzet.** Trezor Suite is geen browser met
|
||||
een sessiecookie. Zet het niet "voor de veiligheid" terug: dan krijgt Suite een inlogpagina in plaats van
|
||||
de relay en werkt de app niet meer. De keerzijde hoort erbij en staat in de compose: wie de poort bereikt,
|
||||
bereikt de relay. Voeg dus geen pagina toe achter diezelfde poort zonder daar apart over na te denken; zie
|
||||
het plan **Umbrelapp**, `OPEN.md` punt 2.
|
||||
|
||||
**De quota-manager hoort erbij en is geen restje.** De relay weigert elke eigenaar zonder rij in de
|
||||
limietentabel, en dit is wat die rijen maakt. Haal hem er niet uit omdat hij bij Trezor bij betaalde
|
||||
hosting hoort.
|
||||
|
||||
**"Gebouwd" is hier nog verder van "werkend" dan bij Electrum Gate:** er is nog nooit iets van deze app op
|
||||
een Umbrel gedraaid. Meld dat expliciet in plaats van het te laten meelezen als werkend.
|
||||
|
||||
## Repo-feiten
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Versiegeschiedenis - Evolu Relay
|
||||
|
||||
Nieuwste bovenaan. Elke regel hier hoort bij een `version` in
|
||||
`whatsnext-evolu-relay/umbrel-app.yml`; zonder verhoging van dat nummer rolt umbrelOS een wijziging niet
|
||||
uit.
|
||||
|
||||
## 0.0.1 - 25-08-2026
|
||||
|
||||
Eerste versie, nog niet geinstalleerd.
|
||||
|
||||
Drie containers: de relay en de quota-manager uit dezelfde zelfgebouwde image met een ander `command`, en
|
||||
een Postgres eronder. De quota-manager gaat mee omdat de relay elke eigenaar zonder limietenrij weigert.
|
||||
|
||||
De app-proxy staat op `PROXY_AUTH_ADD: "false"`, want Trezor Suite is geen browser met een sessiecookie.
|
||||
Dat is het patroon van de eigen nostr-relay-app van Umbrel. Poort 3851.
|
||||
|
||||
De image komt uit `tools/evolu-relay/build.sh`, gepind op commit `c03a204` van
|
||||
`trezor/trezor-suite-sync`. Trezor publiceert zelf geen image.
|
||||
|
||||
Nog niets van dit alles is op een Umbrel gedraaid.
|
||||
@@ -17,14 +17,15 @@
|
||||
| App | Map | Wat het doet |
|
||||
|-|-|-|
|
||||
| **Electrum Gate** | `whatsnext-electrum-gate/` | TLS-voordeur op je eigen Electrum-server, zodat een wallet van buiten erbij kan zonder Tor. Draait, wordt gebruikt |
|
||||
| **Evolu Relay** | nog niet | De sync-server achter de labels van Trezor Suite, op je eigen Umbrel. Bestaat nog uit plannen |
|
||||
| **Evolu Relay** | `whatsnext-evolu-relay/` | De sync-server achter de labels van Trezor Suite, op je eigen Umbrel. Gepakketteerd sinds 25-08-2026, nog nooit geïnstalleerd |
|
||||
|
||||
## A - Nu (aanbevolen focus)
|
||||
|
||||
| Plan | App | Volgende stap | Status |
|
||||
|-|-|-|-|
|
||||
| [Webinterface](Plannen/Actief/005-Webinterface/TAKEN.md) | Gate | 0.0.10 op een telefoon nakijken, en het uploaden op het niet-gelukkige pad proberen met een sleutel die niet bij het certificaat hoort. Daarna open punt 5: laten controleren of de TLS-poort zélf antwoordt | 🔶 |
|
||||
| [Proefopstelling](Plannen/Actief/007-Proefopstelling/TAKEN.md) | Relay | Controleren of Trezor Suite een eigen sync-server accepteert, en op welk platform. Dat is de goedkoopste weerlegging van het hele project en het kost een minuut in de interface. Fase 1 is verder af: de quota-manager blijkt in de praktijk verplicht en er is geen publieke image, dus die moet zelf gebouwd worden | 🔶 |
|
||||
| [Umbrelapp](Plannen/Actief/008-Umbrelapp/TAKEN.md) | Relay | De image bouwen op de Umbrel met `tools/evolu-relay/build.sh`. Dat is de enige stap tussen wat er in de repo staat en een installatie die kan slagen; daarna installeren en kijken of de drie containers blijven draaien | 🔶 |
|
||||
| [Proefopstelling](Plannen/Actief/007-Proefopstelling/TAKEN.md) | Relay | Controleren of Trezor Suite een eigen sync-server accepteert, en op welk platform. Dat is de goedkoopste weerlegging van het hele project en het kost een minuut in de interface. Daarna: hoe registreer je een eigenaar bij de quota-manager, want zonder dat weigert de relay iedereen | 🔶 |
|
||||
|
||||
## B - Los oppakbaar (geen blokkade, geen vaste volgorde)
|
||||
|
||||
@@ -60,8 +61,7 @@ daaronder, dus deze tabel en de mapinhoud kunnen niet uit elkaar lopen.
|
||||
|
||||
| Plan | App | Afhankelijk van | Waarover het gaat |
|
||||
|-|-|-|-|
|
||||
| [Umbrelapp.PLAN.md](Plannen/Masterplannen/Umbrelapp.PLAN.md) | Relay | Proefopstelling: het aantal containers, de variabelen en de authenticatievraag | Een tweede app-map in deze store, die je in umbrelOS installeert. De ontwerpvraag die alles bepaalt is of de app achter de inlog van umbrelOS kan staan: Trezor Suite is geen browser met een sessiecookie |
|
||||
| [Bereikbaarheid.PLAN.md](Plannen/Masterplannen/Bereikbaarheid.PLAN.md) | Relay | Umbrelapp: er valt niets bereikbaar te maken zolang er niets draait | Synchroniseren buiten het thuisnetwerk, zonder een poort op de router open te zetten. Voorstel is Tailscale; of dat volstaat hangt ervan af of Suite TLS eist |
|
||||
| [Bereikbaarheid.PLAN.md](Plannen/Masterplannen/Bereikbaarheid.PLAN.md) | Relay | Umbrelapp: er valt niets bereikbaar te maken zolang er niets draait | Synchroniseren buiten het thuisnetwerk, zonder een poort op de router open te zetten. Voorstel is Tailscale; of dat volstaat hangt ervan af of Suite TLS eist. De gebruiker maakt een subdomein aan, wat op de reverse-proxy-route wijst |
|
||||
| [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 |
|
||||
| [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 |
|
||||
@@ -78,5 +78,5 @@ Cross-plan kennis staat in [KNOWLEDGE.md](KNOWLEDGE.md). Naslag staat niet in de
|
||||
| [Vergelijkbare-apps.md](Referenties/Vergelijkbare-apps.md) | Gate | Of dit type app al bestaat voor Umbrel, en waarom niet. De kern voor de PR-tekst bij inlevering: de reverse proxies in de store kunnen een certificaat niet op een TCP-poort zetten |
|
||||
| [Upstream-evolu-relay.md](Referenties/Upstream-evolu-relay.md) | Relay | Wat er over `trezor/trezor-suite-sync` bekend is, met per feit hoe hard het is, en de vier dingen die nog helemaal niet uitgezocht zijn |
|
||||
|
||||
Versiegeschiedenis staat per app: [CHANGELOG-electrum-gate.md](CHANGELOG-electrum-gate.md). Evolu Relay
|
||||
heeft er nog geen, want er is nog geen manifest met een `version`.
|
||||
Versiegeschiedenis staat per app: [CHANGELOG-electrum-gate.md](CHANGELOG-electrum-gate.md) en
|
||||
[CHANGELOG-evolu-relay.md](CHANGELOG-evolu-relay.md).
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Open punten - Umbrelapp
|
||||
|
||||
> Beslissingen die nog een **eigenaar** of een **moment** nodig hebben. Staat een punt hier zonder allebei,
|
||||
> dan is dat de eerste fout om op te lossen. Wordt een punt een taak, dan verhuist het naar
|
||||
> [TAKEN.md](TAKEN.md).
|
||||
>
|
||||
> **Nummers blijven staan**, ook als een punt beslist is: er kan elders naar verwezen worden, ook vanuit
|
||||
> codecommentaar. Beslissen betekent verplaatsen naar de kop hieronder, niet hernummeren.
|
||||
|
||||
## Nog te beslissen
|
||||
|
||||
1. **Waar komt de image te staan zodra lokaal niet meer volstaat?**
|
||||
Op 25-08-2026 is gekozen voor lokaal bouwen als eerste stap, en dat is een bewust tijdelijke keuze: de
|
||||
app werkt dan alleen op die ene machine en herbouwen is handwerk. Drie richtingen, en ze zijn allemaal
|
||||
verdedigbaar:
|
||||
|
||||
- **het ingebouwde containerregister van de eigen Gitea.** Zelfde host als de store, geldig
|
||||
TLS-certificaat, geen nieuw account. Nog na te kijken: staat het pakketregister aan, en mag er anoniem
|
||||
uit gehaald worden. Zo ja, dan is dit de netste plek;
|
||||
- **Docker Hub onder een eigen account.** De standaardweg, en verplicht als het ooit de officiële store
|
||||
in gaat. Zet wel je naam op een publieke image van software van Trezor; lees dan eerst `LICENSE.md`,
|
||||
dat door GitHub als "other" geclassificeerd staat;
|
||||
- **lokaal laten.** Verdedigbaar zolang er één Umbrel is. De prijs is dat een herinstallatie ook een
|
||||
herbouw is, en dat je dat over een half jaar niet meer weet.
|
||||
|
||||
**Moment:** zodra de installatie uit fase 4 geslaagd is, en niet eerder: pas dan weet je of het pakket
|
||||
iets waard is · **Eigenaar:** gebruiker
|
||||
|
||||
2. **Komt er een statuspagina?**
|
||||
Electrum Gate heeft er een en die bleek in de praktijk het nuttigste deel van die app. Hier zou dat
|
||||
kunnen: draait de relay, hoe groot is de database, wanneer was de laatste synchronisatie, en is er een
|
||||
eigenaar geregistreerd. Dat laatste is meer dan gemak, want het is precies waar het stil kan misgaan.
|
||||
|
||||
Ertegen: het is een eigen container en een eigen onderhoudslast, en het is geen voorwaarde om te kunnen
|
||||
synchroniseren. Ervoor, en dat is nieuw sinds de samenvoeging van de repo's: de pagina en de agent van
|
||||
Electrum Gate staan in dezelfde repo en zijn grotendeels over te nemen.
|
||||
|
||||
Let op één ding als het ervan komt: de app-proxy staat op `PROXY_AUTH_ADD: "false"`, dus een pagina zou
|
||||
net zo onbeschermd zijn als de relay. Bij Electrum Gate zit de pagina juist wél achter de inlog. Dat
|
||||
vraagt dan een tweede poort of een smalle whitelist.
|
||||
**Moment:** pas overwegen als fase 4 geslaagd is · **Eigenaar:** gebruiker
|
||||
|
||||
3. **Wat doen we met de quota-manager als blijkt dat hij iets extern nodig heeft?**
|
||||
Hij is meegepakketteerd omdat de relay zonder limietenrij niemand toelaat. Als het registreren van een
|
||||
eigenaar een betaalprovider of een Notion-sleutel vraagt, klopt die keuze niet meer en wordt de tweede
|
||||
weg uit [PLAN.md](PLAN.md) §4b weer actueel: de rij met de hand in de database zetten.
|
||||
**Moment:** zodra **Proefopstelling** de registratievraag beantwoordt · **Eigenaar:** volgt uit dat plan
|
||||
|
||||
## Bewust uitgesteld
|
||||
|
||||
4. **`SERVER_ENV` op `prod` of `dev`?** - `prod`, tot het tegendeel gemeten is (25-08-2026).
|
||||
`.env.sample` zegt dat prod authenticatie aanzet; in de code die gelezen is bepaalt die vlag alleen het
|
||||
logniveau en staan de autorisatiecontroles onvoorwaardelijk aan. Eén van de twee is achterhaald.
|
||||
|
||||
`prod` is de veilige kant van die onduidelijkheid: als het iets aanzet, willen we dat het aanstaat. Maar
|
||||
het is een gok tot het gemeten is, en het is met één keer starten te meten. Staat als taak in
|
||||
**Proefopstelling** fase 2.
|
||||
**Moment:** bij de eerste geslaagde start · **Eigenaar:** volgt uit Proefopstelling
|
||||
@@ -0,0 +1,140 @@
|
||||
# Umbrelapp - plan
|
||||
|
||||
> **App: Evolu Relay.** Ontwerp en afbakening. **Dit bestand lees je zelden**, alleen bij twijfel over
|
||||
> scope of architectuur. Status staat in [TAKEN.md](TAKEN.md), geschiedenis in [PROGRESS.md](PROGRESS.md),
|
||||
> onbesliste punten in [OPEN.md](OPEN.md).
|
||||
>
|
||||
> Gepromoveerd uit `Masterplannen/` op 25-08-2026, toen de gebruiker besloot het pakket meteen te maken in
|
||||
> plaats van te wachten op de proefopstelling.
|
||||
|
||||
## 1. Doel
|
||||
|
||||
Een tweede app in deze store: `whatsnext-evolu-relay/`, met een manifest en een compose, geïnstalleerd op
|
||||
de Umbrel van de gebruiker, met Trezor Suite die erop synchroniseert.
|
||||
|
||||
## 2. Afbakening
|
||||
|
||||
Het pakket en de installatie: manifest, compose, het bouwrecept voor de image, en de controles op het
|
||||
apparaat zelf.
|
||||
|
||||
De store zelf valt hier buiten: die bestaat en serveert Electrum Gate al. Wat erbij komt is één map.
|
||||
|
||||
## 3. Niet-doelen
|
||||
|
||||
- **Geen bereikbaarheid van buiten het thuisnetwerk.** Masterplan **Bereikbaarheid**. Dit plan is af als
|
||||
het op het eigen netwerk werkt.
|
||||
- **Geen inlevering bij de officiële store.** Masterplan **Publicatie-Relay**.
|
||||
- **Geen wijzigingen aan de relay zelf.** Wat Trezor levert, draaien we.
|
||||
- **Geen eigen statuspagina.** Zie [OPEN.md](OPEN.md) punt 2.
|
||||
|
||||
## 4. Ontwerp
|
||||
|
||||
Alles hieronder rust op [Upstream-evolu-relay.md](../../../Referenties/Upstream-evolu-relay.md), waar de
|
||||
feiten met bron-URL per stuk staan. De vorm van een Umbrel-app staat in
|
||||
[Umbrel-appstore-spec.md](../../../Referenties/Umbrel-appstore-spec.md).
|
||||
|
||||
### 4a. Drie containers, twee images
|
||||
|
||||
De relay en de quota-manager komen uit **dezelfde** image met een ander `command`: bovenstrooms is het één
|
||||
codebase met meerdere startscripts. Daarnaast een Postgres. Dat is de hele stack.
|
||||
|
||||
Het `command` staat expliciet in de compose en leunt niet op de `CMD` van de Dockerfile: daar staat
|
||||
`yarn start`, met bovenstrooms zelf een commentaar dat het misschien een van de twee specifieke scripts had
|
||||
moeten zijn.
|
||||
|
||||
### 4b. De quota-manager gaat mee, en waarom dat geen keuze was
|
||||
|
||||
De relay weigert elke eigenaar die geen rij in de limietentabel heeft (`isOwnerAllowed()`), en de
|
||||
quota-manager maakt die rijen. Er is **geen** HTTP-koppeling tussen de twee: geen URL in de configuratie,
|
||||
ze delen alleen de database.
|
||||
|
||||
Dat laatste opent een tweede weg, die hier bewust niet gekozen is: de rij met de hand in de database
|
||||
zetten en de quota-manager weglaten. Minder bewegende delen, maar het is schrijven in andermans schema en
|
||||
dat breekt bij de eerste migratie. De container kost weinig; het risico van zelf in hun tabellen schrijven
|
||||
is groter dan de winst.
|
||||
|
||||
### 4c. De app-proxy zonder inlog, en dat is het patroon en geen omweg
|
||||
|
||||
Trezor Suite is geen browser met een sessiecookie. Achter `app_proxy` met de standaardinstelling krijgt het
|
||||
een inlogpagina in plaats van de relay.
|
||||
|
||||
De oplossing is `PROXY_AUTH_ADD: "false"`, met `port` in het manifest als de poort waar Suite naartoe
|
||||
wijst. **Dat is niet zelfbedacht:** de eigen `nostr-relay`-app in de officiële store doet exact dit, om
|
||||
precies dezelfde reden, en Gitea en Budibase doen het ook. Daarmee is de zwaarste ontwerpvraag van dit plan
|
||||
beantwoord met een precedent in plaats van met een gok.
|
||||
|
||||
Het alternatief dat is afgevallen: een eigen `ports:` op de service, zoals Electrum Gate met 50022 doet.
|
||||
Dat kan, maar het vraagt een tweede poort die op de host vrij moet zijn, terwijl de proxy-poort er al is.
|
||||
|
||||
**De prijs staat in de compose genoemd en hoort ook hier:** wie die poort kan bereiken, bereikt de relay
|
||||
zonder aanmelding. Wat de schade beperkt is de weigering uit §4b. Dat is een reden om deze app niet zonder
|
||||
meer naar het internet open te zetten, en het is de kern van het risico in **Publicatie-Relay**.
|
||||
|
||||
### 4d. De poort is 3851 en niet 4000
|
||||
|
||||
`port` in het manifest is de poort waarop umbrelOS de app aanbiedt. 4000 zou aansluiten op de eigen poort
|
||||
van de relay, maar het is een veelgebruikte poort en een botsing op de host merk je pas als de app niet
|
||||
start. Dat heeft bij Electrum Gate een dag gekost, met 50002 tegen Fulcrum. 3851 sluit aan op de 3850 van
|
||||
die app.
|
||||
|
||||
### 4e. De database
|
||||
|
||||
Postgres onder `${APP_DATA_DIR}/data/postgres`, niet in een naamloos Docker-volume: dat is wat umbrelOS
|
||||
bewaart en in de back-up meeneemt. Het wachtwoord komt uit `${APP_PASSWORD}`, per installatie afgeleid,
|
||||
want deze repo is publiek.
|
||||
|
||||
`PGDATA` staat op een submap van de mount en niet op de wortel: Postgres weigert een datamap die al iets
|
||||
anders bevat, en een mount kan een `lost+found` hebben.
|
||||
|
||||
De image is `postgres:17-alpine` en niet `postgres` kaal zoals bovenstrooms: dat laatste is `latest`, en
|
||||
een grote-versiesprong migreert de datamap niet vanzelf. Dan start de database niet meer.
|
||||
|
||||
`backupIgnore` blijft leeg. Electrum Gate gebruikt dat veld wel, maar daar gaat het om een log en een
|
||||
statusbestand; hier ís de database de waarde van de app.
|
||||
|
||||
### 4f. De image bouwen we zelf, en het recept staat in de repo
|
||||
|
||||
Trezor publiceert geen image: hun werkproces duwt naar een eigen Amazon ECR en op Docker Hub staat niets.
|
||||
Er is dus een bouwstap, en die moet ergens.
|
||||
|
||||
**Niet in de app-map.** Dat is technisch mogelijk (`build:` in plaats van `image:`, en umbreld roept gewoon
|
||||
`docker compose` aan), maar drie dingen maken het verkeerd, en het derde is fataal: de broncode zou in onze
|
||||
repo moeten staan, de bouw duurt minuten tijdens het starten van de app, en **een `Dockerfile` staat niet in
|
||||
de update-whitelist**, dus elke nieuwe versie zou een deïnstallatie plus herinstallatie vragen.
|
||||
|
||||
De gekozen vorm: `tools/evolu-relay/build.sh` haalt de broncode op een **vastgezette commit** en bouwt hun
|
||||
Dockerfile. Het recept is versiebeheerd en na te lezen, de uitkomst staat in de Docker-opslag of later in
|
||||
een register, en de compose verwijst alleen naar de tag. We bouwen niet hun Dockerfile na; wat wij
|
||||
toevoegen is uitsluitend de pin.
|
||||
|
||||
Voorlopig blijft die tag lokaal, op verzoek van de gebruiker: dat is de kortste weg naar een installatie
|
||||
die je kunt proberen. Compose haalt niets op zolang de image lokaal bestaat, dus dezelfde regel werkt later
|
||||
ook als de tag naar een register wijst. Waar dat register komt te staan is [OPEN.md](OPEN.md) punt 1.
|
||||
|
||||
## 5. Raakvlakken
|
||||
|
||||
- **Proefopstelling** leverde alle feiten waarop §4 rust, en heeft nog twee open vragen die dit plan raken:
|
||||
of Trezor Suite een eigen relay accepteert, en hoe je een eigenaar registreert.
|
||||
- **Bereikbaarheid** begint waar dit plan ophoudt.
|
||||
- **Publicatie-Relay** erft §4c als grootste review-risico, en §4f als grootste praktische eis.
|
||||
- **Appstore** (Electrum Gate) leverde de les die §4d stuurt, en de ervaring dat een store-URL wisselen een
|
||||
herinstallatie is.
|
||||
|
||||
## 6. Verificatie
|
||||
|
||||
Automatisch, en dat draait al: `tests/test_appstore_vorm.py` controleert voor élke app in deze repo dat het
|
||||
`id` gelijk is aan de mapnaam, dat het store-voorvoegsel klopt, dat de manifestvelden in de voorgeschreven
|
||||
volgorde staan, dat de `app_proxy` naar een bestaande service wijst en dat elke gemounte map in de repo
|
||||
bestaat. Het pint niets af op digests; dat is bewust, zie de kop van dat bestand.
|
||||
|
||||
Op de Umbrel, en dat is waar dit plan om gaat:
|
||||
|
||||
1. de image bouwen met `tools/evolu-relay/build.sh`;
|
||||
2. de app installeren en zien dat alle drie de containers blijven draaien. **De database is hier de
|
||||
twijfel:** of het schema zichzelf aanmaakt is niet uitgezocht;
|
||||
3. Trezor Suite naar `<umbrel>:3851` laten wijzen en een label synchroniseren. Dit is de enige controle die
|
||||
telt, en hij kan mislukken op de registratie uit §4b zonder dat er iets mis is met het pakket;
|
||||
4. de app stoppen en starten, en controleren dat de database het overleeft;
|
||||
5. controleren dat het toevoegen van deze app Electrum Gate niet raakt.
|
||||
|
||||
Meld per controle of hij gedaan is, en meld ook expliciet welke niet.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Voortgang - Umbrelapp
|
||||
|
||||
> Chronologisch sessielog, nieuwste bovenaan. Kort: 3 tot 6 regels per entry. Wat er is gebeurd en waarom,
|
||||
> niet wat er nog moet: dat staat in [TAKEN.md](TAKEN.md).
|
||||
|
||||
## 25-08-2026 - plan werd actief, en het pakket staat er
|
||||
|
||||
De gebruiker besloot het pakket meteen te maken in plaats van te wachten op de proefopstelling. Dat kon,
|
||||
omdat fase 1 van **Proefopstelling** die middag de feiten had opgeleverd: één image met meerdere
|
||||
startscripts, een quota-manager die in de praktijk verplicht is, en geen publieke image.
|
||||
|
||||
**De zwaarste ontwerpvraag is met een precedent beslecht en niet met een gok.** Trezor Suite kan niet achter
|
||||
de inlog van umbrelOS, en het was onduidelijk of `PROXY_AUTH_ADD: "false"` dan een verantwoorde keuze is of
|
||||
een omweg. De eigen `nostr-relay`-app van Umbrel doet exact hetzelfde, om precies dezelfde reden, en heeft
|
||||
ook geen eigen `ports:`. Daarmee is de vorm van de compose niet zelfbedacht.
|
||||
|
||||
**Twee dingen kwamen boven die niet in het ontwerp zaten.** `build/` staat in `.gitignore` als bouwselmap,
|
||||
dus het bouwrecept zou stilzwijgend buiten de repo zijn gebleven; het staat nu onder `tools/`. Dat kwam pas
|
||||
bij het stagen aan het licht en niet bij het schrijven, wat precies is waarom `git status` lezen erbij hoort.
|
||||
En de poort werd 3851 en niet 4000: 4000 is de eigen poort van de relay, maar ook een veelgebruikte poort,
|
||||
en een botsing op de host merk je pas als de app niet start. Die les komt van 50002 tegen Fulcrum.
|
||||
|
||||
**Er is een derde testbestand**, `tests/test_appstore_vorm.py`, en het gaat over de store en niet over één
|
||||
app: id gelijk aan mapnaam, store-voorvoegsel, veldvolgorde, `app_proxy` die naar een bestaande service
|
||||
wijst, en elke gemounte map die in de repo bestaat. Het vindt zijn apps zelf, dus een derde app valt er
|
||||
automatisch onder. Digests toetst het expres niet: geen van de twee apps haalt die regel vandaag, en een
|
||||
suite die altijd rood staat wordt niet gelezen.
|
||||
|
||||
Mutatie-getest met drie ingrepen: het app-id laten afwijken van de mapnaam, `APP_HOST` naar een
|
||||
niet-bestaande service laten wijzen, en de `.gitkeep` weghalen. Alle drie vielen om bij de juiste toets, met
|
||||
een bruikbare melding, en `git diff` was daarna leeg.
|
||||
|
||||
**Geraakt:** `whatsnext-evolu-relay/` (nieuw), `tools/evolu-relay/build.sh` (nieuw),
|
||||
`tests/test_appstore_vorm.py` (nieuw), `Docs/CHANGELOG-evolu-relay.md` (nieuw), dit plan,
|
||||
`Docs/CONTINUE_HERE.md`, `CLAUDE.md`, `README.md`.
|
||||
**Tests:** 32 goed 0 fout (nieuw), 39 goed 0 fout en 54 goed 0 fout (bestaand), niets overgeslagen.
|
||||
|
||||
**Wat er níet geverifieerd is, en dat is veel:** er is nog niets gebouwd en niets geïnstalleerd. Of het
|
||||
databaseschema zichzelf aanmaakt, of Trezor Suite dit adres accepteert, en of een eigenaar te registreren is
|
||||
zonder iets extern: alle drie onbekend. "Gebouwd" is hier nadrukkelijk niet "werkend".
|
||||
@@ -0,0 +1,77 @@
|
||||
# Taken - Umbrelapp
|
||||
|
||||
> **App: Evolu Relay.** Prioriteit: **A** | Afhankelijk van: –
|
||||
>
|
||||
> Actief sinds 25-08-2026. Gepromoveerd uit `Masterplannen/` omdat de gebruiker besloot het pakket meteen te
|
||||
> maken. De afhankelijkheid op **Proefopstelling** is daarmee geen blokkade meer maar een parallelle bron:
|
||||
> fase 1 daarvan is af en leverde de feiten waarop dit pakket rust. Wat er nog uit moet komen zijn twee
|
||||
> vragen die pas bij het installeren pijn doen, en die staan hieronder als eigen taak.
|
||||
|
||||
## Volgende stap
|
||||
|
||||
- [ ] **De image bouwen op de Umbrel met `tools/evolu-relay/build.sh`.** Dat is de enige stap tussen wat er
|
||||
nu in de repo staat en een installatie die kan slagen. Het script haalt de broncode op commit
|
||||
`c03a204` en bouwt de Dockerfile van Trezor; verwacht minuten, want er zit een `yarn install` en een
|
||||
`yarn build` in. **Eigenaar: gebruiker**
|
||||
|
||||
## Fase 1 - De app-map
|
||||
|
||||
- [x] **`whatsnext-evolu-relay/` aangemaakt met `umbrel-app.yml` en `docker-compose.yml` (25-08-2026).**
|
||||
Mapnaam gelijk aan het `id`, met het store-voorvoegsel `whatsnext-`, en de manifestvelden in de
|
||||
voorgeschreven volgorde
|
||||
- [x] `data/postgres/.gitkeep` erin, zodat de mount bij de eerste start niet als root wordt aangemaakt
|
||||
- [x] **`dependencies` weggelaten en niet leeg gezet.** Deze app hangt van geen enkele andere app af; een
|
||||
leeg veld zou suggereren dat er iets te kiezen valt
|
||||
- [ ] **Een eigen icoon.** Er staat nu géén `icon` in het manifest, dus de tegel blijft naamloos in de
|
||||
store. Bewust leeg: een geleend of verkeerd icoon is erger dan geen. **Eigenaar: gebruiker**
|
||||
|
||||
## Fase 2 - De compose
|
||||
|
||||
- [x] **`app_proxy` met `PROXY_AUTH_ADD: "false"`, en geen eigen `ports:`.** Trezor Suite is geen browser
|
||||
met een sessiecookie. Dit is het patroon van de eigen `nostr-relay`-app van Umbrel, dus een precedent
|
||||
en geen omweg; zie [PLAN.md](PLAN.md) §4c
|
||||
- [x] **Relay en quota-manager uit één image met een ander `command`.** Expliciet en niet leunend op de
|
||||
`CMD` van de Dockerfile, want daar staat `yarn start` met bovenstrooms zelf een twijfel erbij
|
||||
- [x] **De quota-manager gaat mee.** Niet omdat de relay hem aanroept, maar omdat de relay elke eigenaar
|
||||
zonder limietenrij weigert en dit is wat die rijen maakt
|
||||
- [x] **Postgres onder `${APP_DATA_DIR}/data/postgres`**, wachtwoord uit `${APP_PASSWORD}`, `PGDATA` op een
|
||||
submap, en `postgres:17-alpine` in plaats van `postgres` kaal
|
||||
- [x] **Healthcheck op de eigen database en gebruiker**, niet op `-d postgres` zoals bovenstrooms: die
|
||||
database bestaat hier niet, en dan is de controle groen op het verkeerde antwoord
|
||||
- [ ] **De images pinnen op een digest.** `postgres:17-alpine` kan meteen, met
|
||||
`docker buildx imagetools inspect`. De eigen image kan pas als hij in een register staat; zie
|
||||
[OPEN.md](OPEN.md) punt 1. Beide staan als TODO in de compose
|
||||
|
||||
## Fase 3 - Het bouwrecept
|
||||
|
||||
- [x] **`tools/evolu-relay/build.sh` (25-08-2026).** Haalt de broncode op een vastgezette commit en bouwt
|
||||
de Dockerfile van Trezor. Niet hun bouwstappen nabouwen; wat wij toevoegen is de pin
|
||||
- [x] **Niet in de app-map gezet, en dat is geen netheid.** Een `Dockerfile` staat niet in de
|
||||
update-whitelist, dus bouwen-in-de-app zou elke nieuwe versie een herinstallatie kosten. Zie
|
||||
[PLAN.md](PLAN.md) §4f
|
||||
- [x] **Onder `tools/` en niet onder `build/`:** dat laatste staat in `.gitignore` als bouwselmap, dus het
|
||||
recept zou stilzwijgend buiten de repo blijven. Gevonden bij het stagen, niet bij het schrijven
|
||||
- [x] Het script controleert na het ophalen dat de commit is wat hij verwachtte, en faalt hard als dat niet
|
||||
zo is. Zonder die regel bouwt het stil de verkeerde toestand
|
||||
|
||||
## Fase 4 - Installeren en verifiëren op de Umbrel
|
||||
|
||||
Niets hiervan is op een laptop te doen. Eigenaar van deze hele fase: **gebruiker**.
|
||||
|
||||
- [ ] De image gebouwd (zie "Volgende stap")
|
||||
- [ ] De app geïnstalleerd, en alle drie de containers blijven draaien
|
||||
- [ ] **Gecontroleerd of het databaseschema zichzelf aanmaakt.** Niet uitgezocht, en dit is de eerste
|
||||
plek waar het misgaat als het antwoord nee is. Kijk in de logs van de relay-container
|
||||
- [ ] Trezor Suite naar `<umbrel>:3851` laten wijzen en een label synchroniseren. **Dit is de enige
|
||||
controle die telt**, en hij kan mislukken op de eigenaarsregistratie zonder dat er iets mis is met het
|
||||
pakket
|
||||
- [ ] De app gestopt en gestart, en de database heeft het overleefd
|
||||
- [ ] Gecontroleerd dat het toevoegen van deze app Electrum Gate niet raakt
|
||||
|
||||
## Geblokkeerd / wacht op
|
||||
|
||||
- [ ] **Hoe registreer je een eigenaar bij de quota-manager?** Zonder antwoord kan er niet gesynchroniseerd
|
||||
worden, ook al draait alles. Wacht op **Proefopstelling** fase 1; begin bij `bruno-collection/` in de
|
||||
bovenstroomse repo
|
||||
- [ ] **Accepteert Trezor Suite dit adres, en in welke vorm?** Wacht op **Proefopstelling**, "Volgende
|
||||
stap". Als het antwoord nee is, is dit pakket zonder waarde
|
||||
+8
-7
@@ -88,14 +88,15 @@ naar deze map. De oude `ARCHITECTURE.md`, `STRUCTURE.md` en `QUICKSTART.md` uit
|
||||
[Referenties/Architectuur-huidig.md](Referenties/Architectuur-huidig.md); ze beschreven grotendeels
|
||||
hetzelfde in drie versies.
|
||||
|
||||
**Er zijn tests, maar alleen voor Electrum Gate**, en ze dekken de agent en het manifest. Hoe ze draaien
|
||||
staat in [../CLAUDE.md](../CLAUDE.md). Voor Evolu Relay is er nog geen bron en dus ook niets te testen;
|
||||
stap 4 van het sessie-protocol vervalt zolang een sessie alleen aan die app werkt.
|
||||
**Er zijn drie testbestanden.** Twee gaan over Electrum Gate en noemen die app-map bij naam; het derde,
|
||||
`tests/test_appstore_vorm.py`, gaat over de **store** en vindt zijn apps zelf, dus een derde app valt daar
|
||||
automatisch onder. Hoe ze draaien staat in [../CLAUDE.md](../CLAUDE.md).
|
||||
|
||||
**Wat sowieso automatisch te controleren is** en de moeite waard blijft, en dat geldt straks voor beide
|
||||
app-mappen: dat de YAML geldig is, dat het `id` in `umbrel-app.yml` gelijk is aan de mapnaam, en dat elke
|
||||
`image:` een `@sha256:`-digest heeft. Dat zijn precies de fouten die je op het apparaat pas merkt als de
|
||||
app niet start.
|
||||
Dat derde bestand dekt precies de fouten die je op het apparaat pas merkt: `id` gelijk aan de mapnaam, het
|
||||
store-voorvoegsel, de voorgeschreven veldvolgorde, een `app_proxy` die naar een bestaande service wijst, en
|
||||
elke gemounte map die in de repo bestaat. Wat het **niet** doet is eisen dat elke `image:` een
|
||||
`@sha256:`-digest heeft. Dat is wel de regel, maar geen van de twee apps haalt hem vandaag en een suite die
|
||||
altijd rood staat wordt niet gelezen; het staat als taak in de plannen en de pinstatus wordt afgedrukt.
|
||||
|
||||
**"Gebouwd" en "werkend" liggen hier verder uit elkaar dan gebruikelijk.** Elk plan heeft daarom een
|
||||
paragraaf Verificatie met de controles die **op de Umbrel zelf** gedaan moeten worden. Meld die uitslag,
|
||||
|
||||
@@ -37,16 +37,32 @@ trade-off is written out in [Docs/Referenties/Clients.md](Docs/Referenties/Clien
|
||||
|
||||
### Evolu Relay
|
||||
|
||||
> **Not packaged yet.** Plans only, no manifest and no compose.
|
||||
> **Packaged, never installed.** The manifest and compose are here; nothing has run on an Umbrel yet.
|
||||
|
||||
Trezor Suite syncs labels and account names between devices, and by default that runs through a server
|
||||
operated by Trezor. That server is open source and called Evolu Relay. The plan is to package it here so
|
||||
the sync runs through your own machine. Trezor states the data is end to end encrypted client-side, so
|
||||
self-hosting does not change that guarantee, it only takes Trezor out of the picture.
|
||||
operated by Trezor. That server is open source and called Evolu Relay. This app runs it on your own
|
||||
machine. The data is end to end encrypted on the device, so self-hosting does not change that guarantee,
|
||||
it only changes who holds the encrypted copy.
|
||||
|
||||
Two questions decide the shape of the package, and both are open: whether Trezor Suite can point at a
|
||||
custom sync server at all, and whether the quota manager (part of Trezor's own paid hosting) is required.
|
||||
See [Docs/Referenties/Upstream-evolu-relay.md](Docs/Referenties/Upstream-evolu-relay.md).
|
||||
Three containers, two images.
|
||||
|
||||
| Container | What it does |
|
||||
|-|-|
|
||||
| `relay` | the sync relay on 4000, reached through the app proxy on 3851 |
|
||||
| `quota-manager` | same image, different command; registers the storage limit the relay requires |
|
||||
| `db` (`postgres:17-alpine`) | storage, under `${APP_DATA_DIR}/data/postgres` |
|
||||
|
||||
The app proxy runs with `PROXY_AUTH_ADD: "false"`, because Trezor Suite is not a browser with a session
|
||||
cookie. That is the same pattern Umbrel's own nostr-relay app uses. The flip side: anything that can reach
|
||||
port 3851 reaches the relay without signing in. What limits the damage is that the relay refuses any owner
|
||||
without a storage limit registered in its database.
|
||||
|
||||
**Trezor publishes no image**, so it is built from their Dockerfile, pinned to a commit, by
|
||||
[tools/evolu-relay/build.sh](tools/evolu-relay/build.sh). Run that before installing.
|
||||
|
||||
Still unverified: whether Trezor Suite accepts this address, whether the database schema creates itself,
|
||||
and how an owner gets registered. See
|
||||
[Docs/Referenties/Upstream-evolu-relay.md](Docs/Referenties/Upstream-evolu-relay.md).
|
||||
|
||||
## Documentatie
|
||||
|
||||
@@ -65,13 +81,20 @@ Alles staat in **[Docs/](Docs/README.md)**. Begin bij
|
||||
|
||||
## Tests
|
||||
|
||||
```
|
||||
python tests/test_appstore_vorm.py
|
||||
```
|
||||
|
||||
Die gaat over de store en vindt zijn apps zelf: id gelijk aan mapnaam, store-voorvoegsel, veldvolgorde in
|
||||
het manifest, en een `app_proxy` die naar een bestaande service wijst. Daarnaast twee suites voor Electrum
|
||||
Gate:
|
||||
|
||||
```
|
||||
python tests/test_agent_certificates.py
|
||||
```
|
||||
|
||||
Losse scripts, geen afhankelijkheden. Let op de regels met `OVERGESLAGEN`: die toetsen hebben de
|
||||
certificaatwinkel van het besturingssysteem of netwerk nodig, en zijn dan niet bewezen. Ze dekken Electrum
|
||||
Gate; voor Evolu Relay is er nog geen bron.
|
||||
certificaatwinkel van het besturingssysteem of netwerk nodig, en zijn dan niet bewezen.
|
||||
|
||||
## Licentie
|
||||
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
"""Toetst de vorm die umbrelOS van deze app store eist, voor élke app erin.
|
||||
|
||||
Waarom deze test bestaat. De twee bestaande testbestanden gaan over Electrum
|
||||
Gate; ze noemen die app-map bij naam. Sinds 25-08-2026 zit er een tweede app in
|
||||
deze repo en zijn er dus regels die niet over één app gaan maar over alle:
|
||||
|
||||
- het `id` in `umbrel-app.yml` moet gelijk zijn aan de mapnaam;
|
||||
- dat id moet beginnen met het store-id uit `umbrel-app-store.yml`;
|
||||
- de manifestvelden staan in de volgorde die de packaging-documentatie
|
||||
voorschrijft;
|
||||
- er is een `docker-compose.yml`, en de `app_proxy` daarin wijst naar een
|
||||
service die in datzelfde bestand bestaat.
|
||||
|
||||
Dat zijn precies de fouten die je op het apparaat pas merkt: de app verschijnt
|
||||
niet in de store, of hij verschijnt en start niet. Er komt geen nette
|
||||
foutmelding, want de runtime-validatie van het manifest staat in umbreld
|
||||
uitgecommentarieerd.
|
||||
|
||||
Wat deze toetsen expres NIET doen: eisen dat elke image op een digest gepind is.
|
||||
Dat is wél de regel, maar op 25-08-2026 haalt geen van de twee apps hem, en een
|
||||
suite die altijd rood staat wordt niet gelezen. Het staat als taak in de plannen
|
||||
Umbrelapp en Publicatie-Gate. Wat hier wel gebeurt is de pinstatus afdrukken, zodat
|
||||
je hem ziet zonder erover te struikelen.
|
||||
|
||||
Deze toetsen vinden hun apps zelf. Komt er een derde app bij, dan valt die
|
||||
automatisch onder alles hierboven en hoeft hier niets bij.
|
||||
|
||||
Draaien:
|
||||
|
||||
python tests/test_appstore_vorm.py
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
import os # noqa: E402
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
REPO = os.path.abspath(os.path.join(HERE, os.pardir))
|
||||
STORE = os.path.join(REPO, "umbrel-app-store.yml")
|
||||
|
||||
# De volgorde uit de packaging-documentatie. Wat de spec niet noemt (icon,
|
||||
# backupIgnore, submitter, submission) mag erachter, niet ertussen.
|
||||
VOORGESCHREVEN = [
|
||||
"manifestVersion", "id", "category", "name", "version", "tagline",
|
||||
"description", "releaseNotes", "developer", "website", "dependencies",
|
||||
"repo", "support", "port", "gallery", "path",
|
||||
]
|
||||
|
||||
# Velden die er per se moeten staan, ook al is het schema soepeler: zonder deze
|
||||
# is de winkelpagina leeg of start de app niet.
|
||||
VERPLICHT = ["manifestVersion", "id", "category", "name", "version", "tagline",
|
||||
"description", "port"]
|
||||
|
||||
|
||||
class Uitslag:
|
||||
def __init__(self):
|
||||
self.goed = 0
|
||||
self.fout = []
|
||||
|
||||
def check(self, naam, gelukt, uitleg=""):
|
||||
if gelukt:
|
||||
self.goed += 1
|
||||
else:
|
||||
self.fout.append(naam + ((" - " + uitleg) if uitleg else ""))
|
||||
|
||||
def rapport(self):
|
||||
print()
|
||||
print("%d goed, %d fout" % (self.goed, len(self.fout)))
|
||||
for f in self.fout:
|
||||
print(" FOUT: " + f)
|
||||
return 0 if not self.fout else 1
|
||||
|
||||
|
||||
def lees(pad):
|
||||
with open(pad, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def veld(tekst, naam):
|
||||
"""De waarde van een veld op het eerste niveau, of None.
|
||||
|
||||
Geen YAML-lezer: de suite heeft geen afhankelijkheden en dat is een
|
||||
projectregel. Daarom alleen velden die aan het begin van een regel staan.
|
||||
"""
|
||||
for regel in tekst.splitlines():
|
||||
if regel.startswith(naam + ":"):
|
||||
return regel.split(":", 1)[1].strip().strip('"').strip("'")
|
||||
return None
|
||||
|
||||
|
||||
def velden_in_volgorde(tekst):
|
||||
"""De veldnamen op het eerste niveau, in de volgorde waarin ze staan."""
|
||||
namen = []
|
||||
for regel in tekst.splitlines():
|
||||
if not regel or regel[0] in " \t#-":
|
||||
continue
|
||||
if ":" not in regel:
|
||||
continue
|
||||
namen.append(regel.split(":", 1)[0].strip())
|
||||
return namen
|
||||
|
||||
|
||||
def app_mappen():
|
||||
"""Elke map in de repo-root met een umbrel-app.yml erin."""
|
||||
gevonden = []
|
||||
for naam in sorted(os.listdir(REPO)):
|
||||
pad = os.path.join(REPO, naam)
|
||||
if not os.path.isdir(pad):
|
||||
continue
|
||||
if os.path.isfile(os.path.join(pad, "umbrel-app.yml")):
|
||||
gevonden.append(naam)
|
||||
return gevonden
|
||||
|
||||
|
||||
def test_er_is_een_store_met_apps(u, store_id, apps):
|
||||
u.check("umbrel-app-store.yml heeft een id", bool(store_id))
|
||||
u.check("en er is minstens een app-map gevonden", bool(apps),
|
||||
"geen enkele map met een umbrel-app.yml")
|
||||
|
||||
|
||||
def test_id_en_mapnaam(u, store_id, app):
|
||||
"""Mapnaam == id == store-prefix + rest. Alle drie of de app bestaat niet."""
|
||||
tekst = lees(os.path.join(REPO, app, "umbrel-app.yml"))
|
||||
app_id = veld(tekst, "id")
|
||||
|
||||
u.check("%s: het manifest heeft een id" % app, bool(app_id))
|
||||
if not app_id:
|
||||
return
|
||||
|
||||
u.check("%s: id is gelijk aan de mapnaam" % app, app_id == app,
|
||||
"manifest zegt %r" % app_id)
|
||||
u.check("%s: id begint met het store-id %r" % (app, store_id),
|
||||
app_id.startswith(store_id + "-"),
|
||||
"id is %r" % app_id)
|
||||
u.check("%s: id is lowercase kebab-case" % app,
|
||||
app_id == app_id.lower() and " " not in app_id and "_" not in app_id,
|
||||
"id is %r" % app_id)
|
||||
|
||||
|
||||
def test_verplichte_velden(u, app):
|
||||
tekst = lees(os.path.join(REPO, app, "umbrel-app.yml"))
|
||||
ontbreekt = [naam for naam in VERPLICHT if veld(tekst, naam) is None]
|
||||
u.check("%s: alle verplichte manifestvelden staan erin" % app,
|
||||
not ontbreekt, "ontbreekt: %r" % ontbreekt)
|
||||
|
||||
|
||||
def test_manifest_volgorde(u, app):
|
||||
"""De voorgeschreven velden in de voorgeschreven onderlinge orde.
|
||||
|
||||
Niet dat ze er alle zestien zijn: `dependencies` hoort weg te blijven bij een
|
||||
app zonder afhankelijkheden. Wel dat wat er staat niet door elkaar loopt, want
|
||||
dat is de eis waar een review op valt.
|
||||
"""
|
||||
aanwezig = velden_in_volgorde(lees(os.path.join(REPO, app, "umbrel-app.yml")))
|
||||
volgens_spec = [n for n in aanwezig if n in VOORGESCHREVEN]
|
||||
verwacht = [n for n in VOORGESCHREVEN if n in volgens_spec]
|
||||
|
||||
u.check("%s: de manifestvelden staan in de voorgeschreven volgorde" % app,
|
||||
volgens_spec == verwacht,
|
||||
"gevonden %r, verwacht %r" % (volgens_spec, verwacht))
|
||||
|
||||
# Wat de spec niet noemt hoort erachter, niet ertussen. Anders is de kop niet
|
||||
# letterlijk goed en moet er bij inlevering geschoven worden.
|
||||
laatste_spec = -1
|
||||
for i, naam in enumerate(aanwezig):
|
||||
if naam in VOORGESCHREVEN:
|
||||
laatste_spec = i
|
||||
extra_ertussen = [n for n in aanwezig[:laatste_spec] if n not in VOORGESCHREVEN]
|
||||
u.check("%s: velden buiten de spec staan achteraan" % app,
|
||||
not extra_ertussen, "ertussen: %r" % extra_ertussen)
|
||||
|
||||
|
||||
def test_compose_bestaat_en_hangt_samen(u, app):
|
||||
"""De app_proxy moet naar een service wijzen die bestaat.
|
||||
|
||||
Dit is een echte klasse fouten en niet een formaliteit: de hostnaam is
|
||||
`<app-id>_<service>_1`, dus hij bevat het app-id én de servicenaam. Verandert
|
||||
een van de twee, dan wijst de proxy naar niets en meldt umbrelOS alleen dat de
|
||||
server onbereikbaar is. Precies het symptoom dat bij Electrum Gate 0.0.3 een
|
||||
dag kostte.
|
||||
"""
|
||||
pad = os.path.join(REPO, app, "docker-compose.yml")
|
||||
u.check("%s: er is een docker-compose.yml" % app, os.path.isfile(pad))
|
||||
if not os.path.isfile(pad):
|
||||
return
|
||||
|
||||
tekst = lees(pad)
|
||||
|
||||
# Servicenamen: twee spaties diep onder services:, eindigend op een dubbele
|
||||
# punt. Geen YAML-lezer, zie veld().
|
||||
services = []
|
||||
in_services = False
|
||||
for regel in tekst.splitlines():
|
||||
if regel.startswith("services:"):
|
||||
in_services = True
|
||||
continue
|
||||
if in_services and regel and not regel[0].isspace():
|
||||
break
|
||||
if in_services and regel.startswith(" ") and not regel.startswith(" "):
|
||||
kaal = regel.strip()
|
||||
if kaal.endswith(":") and not kaal.startswith("#"):
|
||||
services.append(kaal[:-1])
|
||||
|
||||
u.check("%s: de compose heeft een app_proxy" % app,
|
||||
"app_proxy" in services, "services: %r" % services)
|
||||
|
||||
app_host = None
|
||||
for regel in tekst.splitlines():
|
||||
if regel.strip().startswith("APP_HOST:"):
|
||||
app_host = regel.split(":", 1)[1].strip()
|
||||
break
|
||||
|
||||
u.check("%s: de app_proxy heeft een APP_HOST" % app, bool(app_host))
|
||||
if not app_host:
|
||||
return
|
||||
|
||||
u.check("%s: APP_HOST begint met het app-id" % app,
|
||||
app_host.startswith(app + "_"),
|
||||
"APP_HOST is %r maar de map heet %r" % (app_host, app))
|
||||
|
||||
# De vorm is <app-id>_<service>_1; haal de servicenaam eruit en kijk of die
|
||||
# bestaat.
|
||||
rest = app_host[len(app) + 1:]
|
||||
u.check("%s: APP_HOST eindigt op _1" % app, rest.endswith("_1"),
|
||||
"APP_HOST is %r" % app_host)
|
||||
service = rest[:-2] if rest.endswith("_1") else rest
|
||||
u.check("%s: APP_HOST wijst naar een service die bestaat" % app,
|
||||
service in services,
|
||||
"wijst naar %r, aanwezig: %r" % (service, services))
|
||||
|
||||
|
||||
def test_data_onder_data(u, app):
|
||||
"""Wat de app bewaart staat onder data/, en er is een .gitkeep per map.
|
||||
|
||||
De appstore-eis is dat gebruikersstaat onder ${APP_DATA_DIR}/data/... valt en
|
||||
dat elke map die bij de eerste start moet bestaan in de repo staat. Een mount
|
||||
naar een map die er niet is, maakt Docker aan als root, en dan kan de app er
|
||||
niet in schrijven.
|
||||
"""
|
||||
pad = os.path.join(REPO, app, "docker-compose.yml")
|
||||
if not os.path.isfile(pad):
|
||||
return
|
||||
tekst = lees(pad)
|
||||
|
||||
buiten = []
|
||||
ontbreekt = []
|
||||
for regel in tekst.splitlines():
|
||||
kaal = regel.strip()
|
||||
if not kaal.startswith("- ${APP_DATA_DIR}/"):
|
||||
continue
|
||||
pad_in_app = kaal[len("- ${APP_DATA_DIR}/"):].split(":", 1)[0]
|
||||
# Losse bestanden die uit een *.template komen zijn geen gebruikersstaat.
|
||||
if "/" not in pad_in_app:
|
||||
continue
|
||||
if not pad_in_app.startswith("data/"):
|
||||
buiten.append(pad_in_app)
|
||||
continue
|
||||
op_schijf = os.path.join(REPO, app, pad_in_app)
|
||||
if not os.path.exists(op_schijf):
|
||||
ontbreekt.append(pad_in_app)
|
||||
elif os.path.isdir(op_schijf) and not os.path.isfile(
|
||||
os.path.join(op_schijf, ".gitkeep")):
|
||||
ontbreekt.append(pad_in_app + "/.gitkeep")
|
||||
|
||||
u.check("%s: alle mounts met een pad staan onder data/" % app,
|
||||
not buiten, "erbuiten: %r" % buiten)
|
||||
u.check("%s: elke gemounte map bestaat in de repo" % app,
|
||||
not ontbreekt, "ontbreekt: %r" % ontbreekt)
|
||||
|
||||
|
||||
def rapporteer_pinstatus(apps):
|
||||
"""Afdrukken, niet toetsen. Zie de uitleg bovenaan dit bestand."""
|
||||
print()
|
||||
print("Pinstatus van de images (informatief, geen toets):")
|
||||
for app in apps:
|
||||
pad = os.path.join(REPO, app, "docker-compose.yml")
|
||||
if not os.path.isfile(pad):
|
||||
continue
|
||||
for regel in lees(pad).splitlines():
|
||||
kaal = regel.strip()
|
||||
if not kaal.startswith("image:"):
|
||||
continue
|
||||
image = kaal.split(":", 1)[1].strip()
|
||||
merk = "gepind" if "@sha256:" in image else "NIET GEPIND"
|
||||
print(" %-24s %-12s %s" % (app, merk, image))
|
||||
|
||||
|
||||
def main():
|
||||
u = Uitslag()
|
||||
store_id = veld(lees(STORE), "id")
|
||||
apps = app_mappen()
|
||||
|
||||
test_er_is_een_store_met_apps(u, store_id, apps)
|
||||
for app in apps:
|
||||
test_id_en_mapnaam(u, store_id, app)
|
||||
test_verplichte_velden(u, app)
|
||||
test_manifest_volgorde(u, app)
|
||||
test_compose_bestaat_en_hangt_samen(u, app)
|
||||
test_data_onder_data(u, app)
|
||||
|
||||
rapporteer_pinstatus(apps)
|
||||
return u.rapport()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,71 @@
|
||||
#!/bin/sh
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Bouwt de image voor de app whatsnext-evolu-relay.
|
||||
#
|
||||
# Waarom dit bestand bestaat: Trezor publiceert geen image. Hun werkproces duwt
|
||||
# naar een eigen Amazon ECR en op Docker Hub staat niets, dus er is geen
|
||||
# `docker pull` die iets oplevert. De broncode is wel publiek, met een Dockerfile
|
||||
# erin. Dit script is de brug: het haalt de broncode op een vastgezette commit en
|
||||
# bouwt hún Dockerfile.
|
||||
#
|
||||
# Waarom het NIET in de app-map staat: umbreld kopieert de hele app-map naar het
|
||||
# apparaat, en bij een update wordt alleen een whitelist ververst waar een
|
||||
# Dockerfile niet in zit. Bouwen tijdens het starten van de app zou de installatie
|
||||
# bovendien minuten laten hangen. Het recept hoort dus in de repo en het resultaat
|
||||
# in een register of in de lokale Docker-opslag; de app verwijst alleen naar de tag.
|
||||
#
|
||||
# Waarom we hun Dockerfile gebruiken en geen eigen: dan hoeven we hun bouwstappen
|
||||
# niet na te bouwen en niet bij te houden. Wat wij toevoegen is uitsluitend de pin.
|
||||
#
|
||||
# Draaien: sh build.sh
|
||||
# Vereist: docker en git op de machine waar je bouwt.
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
set -eu
|
||||
|
||||
# ── De pin ────────────────────────────────────────────────────────────────────
|
||||
# Dit is het enige wat je aanpast als je een nieuwere versie wil. Verhoog daarna
|
||||
# ook `version` in whatsnext-evolu-relay/umbrel-app.yml, anders rolt umbrelOS de
|
||||
# wijziging niet uit.
|
||||
UPSTREAM_REPO="https://github.com/trezor/trezor-suite-sync.git"
|
||||
UPSTREAM_COMMIT="c03a2043acec48d4a1bbafca65e94da33dce1edd"
|
||||
|
||||
# De tag waar docker-compose.yml van de app naar verwijst. De korte commit zit
|
||||
# erin, zodat je op het apparaat kunt zien wat er draait.
|
||||
IMAGE="whatsnext/evolu-relay:c03a204"
|
||||
|
||||
# ── Bouwen ────────────────────────────────────────────────────────────────────
|
||||
WORKDIR="$(mktemp -d)"
|
||||
cleanup() { rm -rf "$WORKDIR"; }
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
echo "Broncode ophalen op ${UPSTREAM_COMMIT}"
|
||||
|
||||
# Niet `clone --branch`: dat pint op een naam die meebeweegt. Een fetch van één
|
||||
# commit haalt precies deze toestand op en niets anders. GitHub staat het ophalen
|
||||
# van een losse commit-sha toe; een Git-server die dat niet doet, geeft hier een
|
||||
# foutmelding in plaats van stil een andere versie te bouwen.
|
||||
git init --quiet "$WORKDIR"
|
||||
git -C "$WORKDIR" remote add origin "$UPSTREAM_REPO"
|
||||
git -C "$WORKDIR" fetch --quiet --depth 1 origin "$UPSTREAM_COMMIT"
|
||||
git -C "$WORKDIR" checkout --quiet FETCH_HEAD
|
||||
|
||||
# Controle dat we hebben wat we dachten. Zonder deze regel bouwt het script bij
|
||||
# een gewijzigde afspraak over sha's stil de verkeerde toestand.
|
||||
GEVONDEN="$(git -C "$WORKDIR" rev-parse HEAD)"
|
||||
if [ "$GEVONDEN" != "$UPSTREAM_COMMIT" ]; then
|
||||
echo "FOUT: opgehaald ${GEVONDEN}, verwacht ${UPSTREAM_COMMIT}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Bouwen als ${IMAGE}"
|
||||
docker build --tag "$IMAGE" "$WORKDIR"
|
||||
|
||||
echo
|
||||
echo "Klaar. De app verwijst naar deze tag:"
|
||||
docker image inspect --format '{{.RepoTags}} {{.Id}}' "$IMAGE"
|
||||
echo
|
||||
echo "Wil je hem later uit een register halen in plaats van lokaal, dan is dit"
|
||||
echo "de plek: tag hem naar dat register, push, en zet de digest uit"
|
||||
echo "\`docker buildx imagetools inspect\` in docker-compose.yml. Zie"
|
||||
echo "Docs/Referenties/Images-pinnen.md."
|
||||
@@ -0,0 +1,117 @@
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Evolu Relay - de sync-server van Trezor Suite op je eigen Umbrel.
|
||||
#
|
||||
# Drie containers, twee images. De relay en de quota-manager komen uit dezélfde
|
||||
# image met een ander `command`: bovenstrooms is het één codebase met meerdere
|
||||
# startscripts. Dat is nagetrokken in de Dockerfile en de README van Trezor; zie
|
||||
# Docs/Referenties/Upstream-evolu-relay.md §2.
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
services:
|
||||
app_proxy:
|
||||
environment:
|
||||
APP_HOST: whatsnext-evolu-relay_relay_1
|
||||
APP_PORT: 4000
|
||||
# Trezor Suite is geen browser met een sessiecookie. Achter de inlog van
|
||||
# umbrelOS zou het een inlogpagina krijgen in plaats van de relay, en dat
|
||||
# is niet op te lossen aan onze kant.
|
||||
#
|
||||
# Dit is geen omweg: het is het patroon dat de eigen nostr-relay-app van
|
||||
# Umbrel gebruikt, om precies dezelfde reden. Ook Gitea en Budibase in de
|
||||
# officiele store doen het zo.
|
||||
#
|
||||
# De prijs staat er wel bij: wie deze poort kan bereiken, bereikt de relay
|
||||
# zonder aanmelding. Wat de schade beperkt is dat de relay zelf elke
|
||||
# eigenaar weigert die geen limietenrij in de database heeft. Zet deze app
|
||||
# dus niet zonder meer open naar het internet; zie het masterplan
|
||||
# Bereikbaarheid.
|
||||
PROXY_AUTH_ADD: "false"
|
||||
|
||||
relay:
|
||||
# TODO pinnen. Deze tag komt uit tools/evolu-relay/build.sh en bestaat
|
||||
# voorlopig alleen in de lokale Docker-opslag van de machine waar gebouwd is.
|
||||
# Daarom staat er geen @sha256: er is nog geen register. Compose haalt niets
|
||||
# op zolang de image lokaal bestaat; zodra de tag naar een register wijst,
|
||||
# hoort de digest erbij. Zie Docs/Referenties/Images-pinnen.md.
|
||||
image: whatsnext/evolu-relay:c03a204
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
# Bovenstrooms staat `CMD ["yarn", "start"]` in de Dockerfile, met daarbij een
|
||||
# eigen commentaar dat het misschien een van de twee specifieke scripts had
|
||||
# moeten zijn. Daarom hier expliciet, en niet vertrouwen op de standaard.
|
||||
command: ["yarn", "start-evolu-relay"]
|
||||
environment:
|
||||
RELAY_PORT: "4000"
|
||||
HEALTH_PORT: "4002"
|
||||
# dev of prod. Volgens .env.sample zet prod authenticatie aan; in de code
|
||||
# bepaalt die vlag alleen het logniveau en staan de autorisatiecontroles
|
||||
# onvoorwaardelijk aan. Een van de twee is achterhaald en dat is nog niet
|
||||
# uitgezocht. Hier staat prod, want dat is de veilige kant van die
|
||||
# onduidelijkheid: als het iets aanzet, willen we dat het aanstaat.
|
||||
SERVER_ENV: prod
|
||||
POSTGRES_GATE_HOST: whatsnext-evolu-relay_db_1
|
||||
POSTGRES_GATE_PORT: "5432"
|
||||
POSTGRES_GATE_USER: suite-sync
|
||||
POSTGRES_GATE_DB: suite-sync-gate
|
||||
# Door umbrelOS per installatie afgeleid. Nooit een letterlijke waarde:
|
||||
# deze repo is publiek.
|
||||
POSTGRES_GATE_PASSWORD: ${APP_PASSWORD}
|
||||
POSTGRES_GATE_SSL: "false"
|
||||
|
||||
quota-manager:
|
||||
image: whatsnext/evolu-relay:c03a204
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
command: ["yarn", "start-quota-manager"]
|
||||
# Waarom deze container er is, terwijl hij bij Trezor bij hun betaalde
|
||||
# hosting hoort: de relay weigert elke eigenaar zonder rij in de
|
||||
# limietentabel, en dit is wat die rijen aanmaakt. Er is geen HTTP-koppeling
|
||||
# tussen de twee; ze delen alleen de database. Zie Upstream-evolu-relay.md §3.
|
||||
environment:
|
||||
QUOTA_MANAGER_PORT: "4001"
|
||||
HEALTH_PORT: "4012"
|
||||
SERVER_ENV: prod
|
||||
POSTGRES_GATE_HOST: whatsnext-evolu-relay_db_1
|
||||
POSTGRES_GATE_PORT: "5432"
|
||||
POSTGRES_GATE_USER: suite-sync
|
||||
POSTGRES_GATE_DB: suite-sync-gate
|
||||
POSTGRES_GATE_PASSWORD: ${APP_PASSWORD}
|
||||
POSTGRES_GATE_SSL: "false"
|
||||
|
||||
db:
|
||||
# TODO pinnen op de multi-arch index-digest, met
|
||||
# `docker buildx imagetools inspect postgres:17-alpine`. Kan alleen op een
|
||||
# machine met Docker; staat als taak in het plan Umbrelapp.
|
||||
#
|
||||
# Niet `postgres` kaal zoals de compose van Trezor doet: dat is `latest` en
|
||||
# dus niet reproduceerbaar, en een grote-versiesprong van Postgres migreert
|
||||
# zijn datamap niet vanzelf. Dan start de database niet meer en is de data
|
||||
# alleen met handwerk terug te halen.
|
||||
image: postgres:17-alpine
|
||||
restart: on-failure
|
||||
environment:
|
||||
POSTGRES_USER: suite-sync
|
||||
POSTGRES_DB: suite-sync-gate
|
||||
POSTGRES_PASSWORD: ${APP_PASSWORD}
|
||||
# Een submap en niet de wortel van de mount. Postgres weigert een datamap
|
||||
# die al iets anders bevat, en een mount heeft op sommige bestandssystemen
|
||||
# een lost+found.
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
volumes:
|
||||
# Onder data/ en niet in een naamloos Docker-volume: dit is wat umbrelOS
|
||||
# bewaart en meeneemt in de back-up. In een volume zou de database een
|
||||
# herinstallatie van de app niet overleven.
|
||||
- ${APP_DATA_DIR}/data/postgres:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
# Op de eigen database en gebruiker, niet op `-d postgres` zoals
|
||||
# bovenstrooms: die database bestaat hier niet en dan is de controle groen
|
||||
# terwijl het verkeerde antwoord gegeven wordt.
|
||||
test: ["CMD-SHELL", "pg_isready -U suite-sync -d suite-sync-gate"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
start_period: 30s
|
||||
@@ -0,0 +1,81 @@
|
||||
# De veldvolgorde hieronder is niet vrij: de packaging-documentatie van de
|
||||
# officiele appstore schrijft hem voor. Zie de tabel in
|
||||
# Docs/Referenties/Umbrel-appstore-spec.md.
|
||||
#
|
||||
# Wat de spec niet noemt staat onderaan dit bestand en niet ertussen. Dan is de
|
||||
# voorgeschreven kop letterlijk goed en hoeft er bij inlevering alleen iets weg.
|
||||
#
|
||||
# `dependencies` is weggelaten en niet leeg gezet: deze app hangt van geen enkele
|
||||
# andere app af. Een leeg veld zou suggereren dat er iets te kiezen valt.
|
||||
manifestVersion: 1
|
||||
id: whatsnext-evolu-relay
|
||||
category: bitcoin
|
||||
name: Evolu Relay
|
||||
version: "0.0.1"
|
||||
tagline: Sync your Trezor Suite labels through your own machine
|
||||
description: >-
|
||||
Trezor Suite can sync the labels and account names you give your addresses across your
|
||||
devices. By default that runs through a server operated by Trezor. This app runs that
|
||||
server on your Umbrel instead, so the sync goes through a machine you own.
|
||||
|
||||
|
||||
The data is end to end encrypted on your device before it leaves, so Trezor cannot read
|
||||
your labels either way. What self-hosting changes is who holds the encrypted copy and who
|
||||
can see that you are syncing at all.
|
||||
|
||||
|
||||
This is Trezor's own relay, not a reimplementation: it is built from the source they publish
|
||||
as trezor/trezor-suite-sync, pinned to a specific commit.
|
||||
|
||||
|
||||
Point Trezor Suite at this Umbrel to use it. Away from home you will need a way in, such as
|
||||
Tailscale or a reverse proxy with your own domain.
|
||||
|
||||
|
||||
Two things to know before you install. The relay has no web interface, so the tile opens the
|
||||
relay itself rather than a page for you to read. And it only serves an owner that has a
|
||||
storage limit registered in its database, which is what the included quota manager is for;
|
||||
if syncing is refused, that registration is the place to look.
|
||||
releaseNotes: >-
|
||||
First release. Packages Trezor's Evolu Relay, the quota manager it needs, and a PostgreSQL
|
||||
database, all on your own machine.
|
||||
|
||||
|
||||
Built from source pinned to commit c03a204 of trezor/trezor-suite-sync. There is no image
|
||||
published by Trezor, so the image is built from their Dockerfile; see tools/evolu-relay in
|
||||
the app store repository.
|
||||
|
||||
|
||||
Not verified yet: whether Trezor Suite accepts this address, and what has to happen before
|
||||
an owner is allowed to sync.
|
||||
developer: "WhatsNext?"
|
||||
website: https://sc.kamenier-hamer.nl/sysop/UmbrelApps
|
||||
repo: https://sc.kamenier-hamer.nl/sysop/UmbrelApps
|
||||
support: https://sc.kamenier-hamer.nl/sysop/UmbrelApps/issues
|
||||
# De poort waarop umbrelOS deze app aanbiedt, en tegelijk de poort waar Trezor
|
||||
# Suite naartoe wijst: de app-proxy staat met PROXY_AUTH_ADD op "false", dus wat
|
||||
# hier binnenkomt gaat rechtstreeks naar de relay. Zie docker-compose.yml.
|
||||
#
|
||||
# Niet 4000, de eigen poort van de relay: die is een veelgebruikte poort en een
|
||||
# botsing op de host merk je pas als de app niet start. Dat heeft bij Electrum
|
||||
# Gate een keer een dag gekost, met 50002 tegen Fulcrum. 3851 sluit aan op de 3850
|
||||
# van die app.
|
||||
port: 3851
|
||||
# Leeg laten bij een nieuw pakket; de plaatjes doet het store-team zelf.
|
||||
gallery: []
|
||||
path: ""
|
||||
submitter: "WhatsNext?"
|
||||
submission: https://sc.kamenier-hamer.nl/sysop/UmbrelApps
|
||||
|
||||
# ── Hieronder staat wat de voorgeschreven volgorde niet noemt ────────────────
|
||||
#
|
||||
# Er is geen `icon` en dat is zichtbaar: de tegel blijft naamloos in de store.
|
||||
# Bewust nog niet gevuld, want een verkeerd of geleend icoon is erger dan geen,
|
||||
# en er is nog geen eigen ontwerp. Staat als taak in het plan Umbrelapp.
|
||||
|
||||
# Wat niet in de back-up hoeft. Paden zijn relatief aan de app-datamap.
|
||||
#
|
||||
# Voor deze app is dat vrijwel niets, en dat is expres: de database ís de waarde
|
||||
# van de app. Electrum Gate gebruikt dit veld wel, maar daar gaat het om een log
|
||||
# en een statusbestand. Neem die keuze hier niet uit gewoonte over.
|
||||
backupIgnore: []
|
||||
Reference in New Issue
Block a user