Relay 0.6.0: alles in een image, de app-map is leeg
Plan Eigenimage, fase 5, op keuze van de gebruiker: een image met de relay erbij en geen tweede recept. agent.py, nginx.conf en index.html verhuizen naar tools/evolu-relay/ naast src/; de Dockerfile blijft op node:24-slim en haalt nginx en python3 uit apt. Drie containers uit een image: de relay als node via de compose, de agent en nginx als root. Anders dan alleen verplaatst: user www-data in nginx.conf (Debian heeft geen gebruiker nginx), geen USER meer in de image, de versie in de kop via api/status met RELAY_APP_VERSION. VERSION 0.6.0, manifest 0.6.0, drie keer dezelfde tag in de compose, ongepind tot de eerste push. Tests mee verhuisd; de vormtest toetst de drie tags tegen VERSION. Niet gebouwd: er is hier geen Docker. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
0e824a6354
commit
a694a9cbd1
+7
-4
@@ -1,7 +1,10 @@
|
||||
# De bouwcontext van tools/electrum-gate/build.sh is de repo-root, omdat de
|
||||
# Dockerfile icon.png uit de app-map kopieert. Alles wat de Dockerfile niet
|
||||
# noemt blijft hier buiten, zodat de context klein is en een wijziging in de
|
||||
# documentatie de bouwcache niet ongeldig maakt.
|
||||
# De bouwcontext van tools/*/build.sh is de repo-root, omdat elke Dockerfile
|
||||
# icon.png uit zijn app-map kopieert. Alles wat de Dockerfiles niet noemen blijft
|
||||
# hier buiten, zodat de context klein is en een wijziging in de documentatie de
|
||||
# bouwcache niet ongeldig maakt.
|
||||
*
|
||||
!tools/electrum-gate
|
||||
!whatsnext-electrum-gate/icon.png
|
||||
!tools/evolu-relay
|
||||
!whatsnext-evolu-relay/icon.png
|
||||
tools/evolu-relay/node_modules
|
||||
|
||||
@@ -26,8 +26,8 @@ Deze gelden voor élke app hier, want het zijn eigenschappen van umbrelOS. Met b
|
||||
sloopt Python-code, en in een nginx-config betekent het geen `$host`, geen `log_format` en geen
|
||||
`access_log` met variabelen. Moet er tóch een dollarteken in een nginx-directive, dan hoort die directive
|
||||
in een bestand dat het `command`-blok van de compose wegschrijft (daar is `$$` te ontsnappen), of in een
|
||||
eigen image, waar geen envsubst aan te pas komt. Electrum Gate doet sinds 0.1.0 het tweede; Evolu Relay
|
||||
heeft zijn agent en pagina nog als `*.template`.
|
||||
eigen image, waar geen envsubst aan te pas komt. Beide apps doen sinds september 2026 het tweede; er
|
||||
staat geen `*.template` meer in deze repo, maar de regel blijft gelden voor wie er een bij zet.
|
||||
|
||||
**Wat bij een update meekomt is een whitelist**: `docker-compose.yml`, `*.template`, `exports.sh`, `torrc`,
|
||||
`hooks` en `umbrel-app.yml`. Al het andere bereikt een bestaande installatie nooit, zonder foutmelding.
|
||||
@@ -78,11 +78,12 @@ Er is ook een test over de **pagina's** van beide apps, en die is geen Python:
|
||||
node tests/test_paginas_parsen.mjs
|
||||
```
|
||||
|
||||
Hij toetst dat de JavaScript in elke statuspagina parseert. Een pagina staat op een van twee plekken: als
|
||||
`index.html.template` in de app-map (Evolu Relay; dan toetst hij ook dat het script heel blijft ná de
|
||||
invulling door umbreld) of als `index.html` in `tools/<app>/` (Electrum Gate sinds 0.1.0; dan toetst hij
|
||||
dat er geen accolade-variabele meer in staat). Dat is de enige klasse paginafouten die niet op het
|
||||
apparaat gevonden hoeft te worden; alles wat de pagina *toont* blijft handwerk in een browser.
|
||||
Hij toetst dat de JavaScript in elke statuspagina parseert. Een pagina kan op twee plekken staan: als
|
||||
`index.html.template` in de app-map (dan toetst hij ook dat het script heel blijft ná de invulling door
|
||||
umbreld) of als `index.html` in `tools/<app>/` (dan toetst hij dat er geen accolade-variabele meer in
|
||||
staat). Sinds september 2026 staan beide pagina's op de tweede plek. Dat is de enige klasse paginafouten
|
||||
die niet op het apparaat gevonden hoeft te worden; alles wat de pagina *toont* blijft handwerk in een
|
||||
browser.
|
||||
|
||||
**Wil je een pagina bekijken, gebruik `tools/voorbeeldpagina.mjs`.** Een statuspagina is niet zomaar te
|
||||
openen: de gegevens komen van een agent die alleen in de app bestaat, en in een `*.template` staan
|
||||
@@ -215,8 +216,17 @@ relay ergens kunt neerzetten is dat hij de sleutel niet heeft, en het manifest b
|
||||
Onderhoudsfuncties die de inhoud kennen horen in de tool in `HomeGit/Trezor`. Zie §11 van hetzelfde
|
||||
naslagdocument en `OPEN.md` punt 11.
|
||||
|
||||
**Alles zit in één image, sinds 0.6.0 (08-09-2026): de relay, de agent en de pagina.** `tools/evolu-relay/`
|
||||
heeft naast `src/` ook `agent.py`, `nginx.conf` en `index.html`; in de app-map staan alleen nog compose,
|
||||
manifest, icoon en `data/`. Basis is `node:24-slim` (om `better-sqlite3`, dat geen musl-binaries heeft)
|
||||
met nginx en python3 uit apt. Twee gevolgen die je moet kennen: nginx draait als `www-data`, want Debian
|
||||
heeft geen gebruiker `nginx`; en de image heeft geen `USER`, dus de compose zet `user: node` op de
|
||||
relay-service en de andere twee draaien als root. De versie in de kop van de pagina komt uit `api/status`
|
||||
via `RELAY_APP_VERSION`. Verhoog je `VERSION` in `build.sh`, dan ook het manifest en de tag in de compose,
|
||||
**drie keer**.
|
||||
|
||||
**Deze app draait en wordt gebruikt sinds 28-08-2026**, maar dat geldt niet voor elke wijziging: er zit een
|
||||
bouwstap tussen de repo en het apparaat. Een wijziging in `tools/evolu-relay/src/` is pas uitgerold als de
|
||||
bouwstap tussen de repo en het apparaat. Een wijziging in `tools/evolu-relay/` is pas uitgerold als de
|
||||
image gebouwd, geduwd en met zijn digest in de compose gezet is, en dat kan alleen de gebruiker. Meld dus
|
||||
per wijziging wat er wél geverifieerd is; "de app werkt" is geen uitspraak over de code van vandaag.
|
||||
|
||||
|
||||
@@ -19,6 +19,28 @@ De regel is: **verhoog je `VERSION`, dan verhoog je ook het manifest; andersom n
|
||||
> geschreven uit de `releaseNotes` in het manifest en uit `PROGRESS.md` van het plan **Umbrelapp**. Ze zijn
|
||||
> daarom korter dan de rest.
|
||||
|
||||
## 0.6.0 - 08-09-2026
|
||||
|
||||
**Nog niet gebouwd.** `VERSION` in `tools/evolu-relay/build.sh` staat op 0.6.0 en de compose verwijst
|
||||
drie keer naar die tag zonder digest; die komt erbij zodra de gebruiker de image op de Umbrel gebouwd en
|
||||
geduwd heeft. Tot die tijd is dit een versie in de repo en niet op het apparaat.
|
||||
|
||||
**Alles in één image.** Tot 0.5.6 zat alleen de relay in de eigen image en draaiden de agent en de pagina
|
||||
als `*.template` op `python:3-alpine` en `nginx:alpine`. Nu zitten `agent.py`, `nginx.conf` en `index.html`
|
||||
in dezelfde image als de relay, in `tools/evolu-relay/` naast `src/`. De basis blijft `node:24-slim` (om
|
||||
`better-sqlite3`), met nginx en python3 uit apt erbij. Drie containers uit één image: de relay als
|
||||
gebruiker `node` via de compose, de agent en nginx als root. Beslist door de gebruiker op 08-09-2026, na
|
||||
dezelfde stap bij Electrum Gate; zie het plan **Eigenimage**, `PLAN.md` §8.
|
||||
|
||||
Wat er daardoor anders is dan alleen verplaatst:
|
||||
|
||||
- nginx draait als `www-data`, want Debian heeft geen gebruiker `nginx`;
|
||||
- de pagina haalt de versie uit `api/status`; de agent krijgt hem als `RELAY_APP_VERSION` uit de compose.
|
||||
umbreld vulde hem tot nu rechtstreeks in de pagina in;
|
||||
- `icon.png` zit in de image en is daarmee updatebaar. Het blijft ook in de app-map, want het manifest
|
||||
wijst ernaar;
|
||||
- de app-map bevat nog `docker-compose.yml`, `umbrel-app.yml`, `icon.png` en `data/`.
|
||||
|
||||
## 0.5.6 - 07-09-2026
|
||||
|
||||
**Alleen de pagina, dus geen nieuwe image.** `VERSION` in `tools/evolu-relay/build.sh` blijft op 0.5.0.
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
| Plan | App | Volgende stap | Status |
|
||||
|-|-|-|-|
|
||||
| [Eigenimage](Plannen/Actief/004-Eigenimage/TAKEN.md) | **beide** | **Electrum Gate draait sinds 08-09-2026 op zijn eigen image (0.1.0), gepind, herinstalleerd, app-datamap schoon.** De bouw slaagde in één keer en de pagina toont v0.1.0. Voor Gate is dit plan af. **Volgende stap: hetzelfde voor de agent en de pagina van Evolu Relay** (§8), die nog als `*.template` op `python:3-alpine` en `nginx:alpine` draaien. Eerste keuze daar: een tweede recept naast de relay-image, of één image met de relay erbij. Daarvóór: **fase 1 tot en met 3 gedaan op 07-09-2026.** Het recept staat in `tools/electrum-gate/` (Dockerfile, build.sh, entrypoint.sh en de vier voormalige templates), de app-map bevat alleen nog compose, manifest, icoon en `data/`, en de compose is voor het eerst zonder shellblok. Eén image voor beide containers, gebouwd op de Umbrel; open punt 2 en 3 zijn daarmee beslist. **Volgende stap is van de gebruiker en kan alleen op de Umbrel:** `sh tools/electrum-gate/build.sh`, duwen, de digest twee keer in de compose, committen, updaten, en dan de controles van fase 4. Reken op minstens één ronde, want de image is nog nooit gebouwd; de tests toetsen de tekst van het recept en niet het resultaat. **Daarna:** hetzelfde voor de agent en de pagina van Evolu Relay (§8), pas als de weg bij Gate bewezen is. Multi-arch en de anonieme pull horen bij **Publicatie-Gate** | 🔶 |
|
||||
| [Eigenimage](Plannen/Actief/004-Eigenimage/TAKEN.md) | **beide** | **Evolu Relay 0.6.0 staat klaar in de repo (08-09-2026), ongebouwd: één image met relay, agent en pagina erin**, op keuze van de gebruiker. `tools/evolu-relay/` heeft nu naast `src/` ook `agent.py`, `nginx.conf` en `index.html`; de app-map bevat alleen nog compose, manifest, icoon en `data/`. **Volgende stap is van de gebruiker en kan alleen op de Umbrel:** `sh tools/evolu-relay/build.sh`, duwen, de digest drie keer in de compose, committen, updaten, en nakijken (v0.6.0 in de kop, een sync, de allowlist en labels intact). Eerste image met apt erin, dus reken op een ronde. **Daarna is dit plan voor beide apps af en gaat het naar `Archief/`.** Eerder vandaag: **Electrum Gate draait op zijn eigen image (0.1.0)**, gepind, herinstalleerd, app-datamap schoon; de bouw slaagde in één keer. Het recept staat in `tools/electrum-gate/` (Dockerfile, build.sh, entrypoint.sh en de vier voormalige templates), de app-map bevat alleen nog compose, manifest, icoon en `data/`, en de compose is voor het eerst zonder shellblok. Eén image voor beide containers, gebouwd op de Umbrel; open punt 2 en 3 zijn daarmee beslist. **Volgende stap is van de gebruiker en kan alleen op de Umbrel:** `sh tools/electrum-gate/build.sh`, duwen, de digest twee keer in de compose, committen, updaten, en dan de controles van fase 4. Reken op minstens één ronde, want de image is nog nooit gebouwd; de tests toetsen de tekst van het recept en niet het resultaat. **Daarna:** hetzelfde voor de agent en de pagina van Evolu Relay (§8), pas als de weg bij Gate bewezen is. Multi-arch en de anonieme pull horen bij **Publicatie-Gate** | 🔶 |
|
||||
|
||||
## B - Los oppakbaar (geen blokkade, geen vaste volgorde)
|
||||
|
||||
|
||||
+3
-2
@@ -24,8 +24,9 @@ De keten die eronder ligt, van achter naar voren:
|
||||
zelf uitgeeft, en die is er precies één per app.
|
||||
|
||||
Stand op 08-09-2026: Electrum Gate draait op zijn eigen image sinds 0.1.0, gepind, en zijn twee vreemde
|
||||
images zijn weg. Bij Evolu Relay staan `python:3-alpine` en `nginx:alpine` er nog voor de agent en de
|
||||
pagina, en daarvoor geldt de regel hierboven onverkort.
|
||||
images zijn weg. Evolu Relay heeft sinds 0.6.0 alles in zijn eigen image; de pin daarvan komt erbij bij de
|
||||
eerste push. Daarmee is de keten hieronder afgelopen en is er per app precies één image om te pinnen. De
|
||||
regel blijft staan voor wie er een vreemde image bij zet.
|
||||
|
||||
Twee dingen die dit níet zegt, want anders slaat het de andere kant op door:
|
||||
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
> 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).
|
||||
|
||||
## 08-09-2026 (later) - Evolu Relay: alles in één image, in de repo klaar
|
||||
|
||||
Direct erna, op verzoek van de gebruiker en met zijn keuze: één image met de relay erbij, geen tweede
|
||||
recept. De drie templates zijn met `git mv` naar `tools/evolu-relay/` gegaan, naast `src/`; de Dockerfile
|
||||
blijft op `node:24-slim` (om `better-sqlite3`) en haalt nginx en python3 uit apt. Twee dingen die Debian
|
||||
anders doet dan de nginx-image en die je moet kennen: geen gebruiker `nginx` (dus `www-data`), en geen
|
||||
`USER` meer in de image, zodat de compose de relay met `user: node` laat draaien en de andere twee als root.
|
||||
|
||||
De versie in de kop loopt nu via `api/status`, zoals bij Gate. Versie 0.6.0 in manifest, `VERSION` en drie
|
||||
keer in de compose, ongepind. Tests: alle zes groen, niets overgeslagen; de vormtest toetst de drie tags
|
||||
tegen `VERSION`. In de voorbeeldpagina staat v0.6.0 in de kop. **Niet geverifieerd: de image**, en dit is
|
||||
de eerste met apt erin. Bouwen is aan de gebruiker.
|
||||
|
||||
## 08-09-2026 - gebouwd, gepind, geïnstalleerd: Gate draait op zijn eigen image
|
||||
|
||||
De gebruiker bouwde en duwde de image op de Umbrel; de bouw slaagde in één keer, dus de zorg over `apk add
|
||||
|
||||
@@ -29,9 +29,10 @@
|
||||
mutatie-getest; details in [PROGRESS.md](PROGRESS.md)
|
||||
- [x] **Fase 4 gedaan (08-09-2026): gebouwd, geduwd, gepind, geüpdatet, herinstalleerd.** Electrum Gate
|
||||
draait op zijn eigen image en de app-datamap is schoon. Voor Gate is dit plan klaar
|
||||
- [ ] **Volgende stap: hetzelfde voor de agent en de pagina van Evolu Relay.** Zie "Daarna" onderaan. De
|
||||
weg is nu bij Gate bewezen, dus dit kan zonder onbekenden: `tools/evolu-relay/` krijgt naast de
|
||||
relay-image een tweede recept, of één image met de relay erbij; dat is de eerste keuze om te maken
|
||||
- [x] **Evolu Relay in de repo gedaan (08-09-2026), als 0.6.0:** één image met de relay erbij, zie fase 5
|
||||
- [ ] **Volgende stap: de Relay-image bouwen, duwen, pinnen en updaten.** Van de gebruiker; zie fase 5.
|
||||
Daarna is dit plan voor beide apps af en gaat het naar `Archief/`; wat overblijft (multi-arch,
|
||||
anonieme pull per verhoging) hoort bij **Publicatie-Gate** en **Publicatie-Relay**
|
||||
|
||||
- [x] **Open punt 1 beantwoord (27-08-2026): voor nu Gitea, bij inlevering opnieuw kijken.** Daarmee is de
|
||||
enige vraag weg die vóór het bouwen beantwoord moest zijn. Zie [OPEN.md](OPEN.md)
|
||||
@@ -94,12 +95,26 @@
|
||||
- [x] **`icon.png` is hiermee updatebaar**, want die zit in de image. Dat was de enige echte uitzondering
|
||||
op "alles komt al aan bij een update"; zie [PLAN.md](PLAN.md) §1
|
||||
|
||||
## Daarna - Evolu Relay
|
||||
## Fase 5 - Evolu Relay
|
||||
|
||||
- [ ] **Hetzelfde voor de agent en de pagina van Evolu Relay**, die nog als `*.template` op
|
||||
`python:3-alpine` en `nginx:alpine` draaien; zie [PLAN.md](PLAN.md) §8. Pas na fase 4 hierboven:
|
||||
eerst zien dat de weg werkt voordat de tweede app hem gaat
|
||||
- [x] **Beslist (08-09-2026, gebruiker): één image met de relay erbij**, geen tweede recept. Basis blijft
|
||||
`node:24-slim` om `better-sqlite3`; nginx en python3 komen uit apt
|
||||
- [x] **Agent, nginx-config en pagina naar `tools/evolu-relay/`** met `git mv`, zonder `.template`.
|
||||
Dockerfile en build.sh herschreven; bouwcontext is de repo-root, zoals bij Gate. `VERSION` 0.6.0,
|
||||
manifest 0.6.0, drie keer dezelfde tag in de compose, ongepind tot de eerste push
|
||||
- [x] **Wat er anders is dan verplaatst:** `user www-data;` in nginx.conf (Debian heeft geen gebruiker
|
||||
nginx), `user: node` op de relay-service in de compose (de image heeft geen `USER` meer), de versie
|
||||
via `api/status` met `RELAY_APP_VERSION`, en `PYTHONUNBUFFERED` als `ENV` in de image
|
||||
- [x] Tests mee: `test_relay_agent.py` laadt `tools/evolu-relay/agent.py`; de vormtest toetst de drie
|
||||
tags tegen `VERSION`; de paginatest en `voorbeeldpagina.mjs` vinden de pagina zelf
|
||||
- [ ] **Bouwen, duwen, pinnen, updaten, nakijken.** Van de gebruiker, op de Umbrel:
|
||||
`sh tools/evolu-relay/build.sh`, dan de digest **drie keer** in de compose. Nakijken: de pagina met
|
||||
v0.6.0 in de kop, een sync vanuit Trezor Suite, en of `owners.json` en de labels de update overleefd
|
||||
hebben (die staan onder `data/relay` en zijn niet aangeraakt). **Eerste keer voor deze image met
|
||||
apt erin**, dus reken op een ronde: of `nginx` uit Debian zonder `www-data`-verrassingen start, en of
|
||||
de relay als `node` nog in `data/relay` kan schrijven nu de map niet meer door de image aangemaakt
|
||||
wordt
|
||||
|
||||
## Geblokkeerd / wacht op
|
||||
|
||||
Niets. Het Relay-deel kan beginnen; bouwen blijft werk van de gebruiker op de Umbrel.
|
||||
De laatste stap van fase 5 wacht op de gebruiker: bouwen kan alleen op de Umbrel.
|
||||
|
||||
@@ -262,10 +262,14 @@ tonen, maar drie klassen fouten hoeven niet op het apparaat gevonden te worden:
|
||||
- [x] **De Postgres-pin is vervallen (28-08-2026):** die database zit niet meer in de app
|
||||
- [x] **De statuspagina verbeteren, op een lijst van de gebruiker.** De lijst kwam op 30-08-2026 en is in
|
||||
één ronde uitgevoerd; zie fase 6 hieronder
|
||||
- [ ] **`python:3-alpine` en `nginx:alpine` pinnen op hun multi-arch index-digest. WACHT OP het plan
|
||||
Eigenimage; doe dit niet eerder.** Op aanwijzing van de gebruiker (30-08-2026): die twee images zijn
|
||||
de plek waar de agent en de pagina van deze app uitgevoerd worden, en dat is precies wat **Eigenimage**
|
||||
naar een eigen image verhuist. Pin je ze nu, dan pin je iets dat verdwijnt.
|
||||
- [x] **`python:3-alpine` en `nginx:alpine` pinnen: vervallen (08-09-2026).** Sinds 0.6.0 zitten de agent
|
||||
en de pagina in de eigen relay-image (plan **Eigenimage**, fase 5), en die twee images staan niet
|
||||
meer in de compose. Wat er te pinnen is, is de eigen image, en dat gebeurt bij elke verhoging. De
|
||||
oude tekst hieronder blijft staan als uitleg waarom er tot dan bewust níet gepind is.
|
||||
|
||||
Op aanwijzing van de gebruiker (30-08-2026): die twee images waren
|
||||
de plek waar de agent en de pagina van deze app uitgevoerd werden, en dat is precies wat **Eigenimage**
|
||||
naar een eigen image verhuisde. Pin je ze dan, dan pin je iets dat verdwijnt.
|
||||
|
||||
De eis komt uit **Publicatie-Relay** en die is nog ver weg, dus er is geen haast. De regel en de hele
|
||||
keten erachter staan in [KNOWLEDGE.md](../../../KNOWLEDGE.md); de commando's in
|
||||
|
||||
@@ -39,32 +39,25 @@ trade-off is written out in [Docs/Referenties/Clients.md](Docs/Referenties/Clien
|
||||
|
||||
### Evolu Relay
|
||||
|
||||
> **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. 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.
|
||||
operated by Trezor. That server is built on Evolu, and its relay is published as an npm package. This app
|
||||
runs that relay on your own machine, with an owner allowlist around it. 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.
|
||||
|
||||
Three containers, two images.
|
||||
Three containers, one image, built from [tools/evolu-relay/](tools/evolu-relay/) by its `build.sh`
|
||||
(node on Debian slim, plus nginx and python3). The app folder holds only the compose file, the manifest,
|
||||
the icon and your data.
|
||||
|
||||
| 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` |
|
||||
| `relay` | the sync relay, published on host port 3852; our `src/index.js` around `@evolu/nodejs`, adding the allowlist |
|
||||
| `agent` | same image, different command; serves the status API and drops commands from the page into a mailbox the relay empties |
|
||||
| `server` | same image; nginx serving the status page on port 80 behind the umbrelOS app proxy, with its sign-in |
|
||||
|
||||
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).
|
||||
The relay publishes its own port because a sync client is not a browser with a session cookie; the page
|
||||
sits behind the app proxy because it is. New owners are admitted only while a two-minute learning window
|
||||
is open on the page; everyone else is refused and listed, so you can allow them by hand.
|
||||
|
||||
## Documentatie
|
||||
|
||||
|
||||
+20
-16
@@ -22,16 +22,16 @@ Draaien:
|
||||
|
||||
python tests/test_relay_agent.py
|
||||
|
||||
De test laadt `agent.py.template` rechtstreeks. Dat kan omdat dat bestand geen
|
||||
accolade-variabelen bevat en de invulling door umbreld hem dus onveranderd laat;
|
||||
de eerste toets hieronder controleert precies dat.
|
||||
De test laadt `tools/evolu-relay/agent.py` rechtstreeks: het bestand dat de
|
||||
Dockerfile in de image zet. Tot 0.6.0 heette dat `agent.py.template` en stond het
|
||||
in de app-map; de eerste toets hieronder is uit die tijd en blijft staan.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
# Vóór de imports, want anders is het te laat: Python legt bytecode naast
|
||||
# agent.py.template zodra die geïmporteerd wordt, en die rommel hoort niet in de
|
||||
# app-map. Een keer is zo'n .pyc meegegaan in een commit.
|
||||
# Vóór de imports, want anders is het te laat: Python legt bytecode naast agent.py
|
||||
# zodra die geïmporteerd wordt, en die rommel hoort niet in de repo. Een keer is
|
||||
# zo'n .pyc meegegaan in een commit.
|
||||
sys.dont_write_bytecode = True
|
||||
|
||||
import importlib.machinery # noqa: E402
|
||||
@@ -42,20 +42,18 @@ import tempfile # noqa: E402
|
||||
from datetime import datetime, timedelta, timezone # noqa: E402
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
APP = os.path.join(HERE, os.pardir, "whatsnext-evolu-relay")
|
||||
TEMPLATE = os.path.join(APP, "agent.py.template")
|
||||
AGENT = os.path.join(HERE, os.pardir, "tools", "evolu-relay", "agent.py")
|
||||
|
||||
|
||||
def load_agent(state_dir):
|
||||
"""Laadt agent.py.template als module, met zijn staat in een tijdelijke map.
|
||||
"""Laadt agent.py als module, met zijn staat in een tijdelijke map.
|
||||
|
||||
De agent leest `RELAY_STATE_DIR` op moduleniveau, dus die moet vóór het laden
|
||||
in de omgeving staan. Met een expliciete loader, want importlib kijkt normaal
|
||||
naar de extensie en .template staat daar niet tussen.
|
||||
in de omgeving staan. Met een expliciete loader, buiten sys.path om.
|
||||
"""
|
||||
os.environ["RELAY_STATE_DIR"] = state_dir
|
||||
loader = importlib.machinery.SourceFileLoader("relay_agent", TEMPLATE)
|
||||
spec = importlib.util.spec_from_file_location("relay_agent", TEMPLATE, loader=loader)
|
||||
loader = importlib.machinery.SourceFileLoader("relay_agent", AGENT)
|
||||
spec = importlib.util.spec_from_file_location("relay_agent", AGENT, loader=loader)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
@@ -94,11 +92,17 @@ def schrijf_owners(state_dir, staat):
|
||||
# ── De aanname waar deze hele test op rust ───────────────────────────────────
|
||||
|
||||
def test_template_is_invulbaar_zonder_schade(u):
|
||||
with open(TEMPLATE, "r", encoding="utf-8") as f:
|
||||
"""Een restant uit de template-tijd dat blijft staan.
|
||||
|
||||
Het bestand zit sinds 0.6.0 in de image en gaat door geen envsubst meer. Maar
|
||||
als iemand het ooit weer als template in een app-map zet, is dit de toets die
|
||||
het meteen ziet.
|
||||
"""
|
||||
with open(AGENT, "r", encoding="utf-8") as f:
|
||||
inhoud = f.read()
|
||||
u.check("template bevat geen dollartekens",
|
||||
u.check("agent.py bevat geen dollartekens",
|
||||
"$" not in inhoud,
|
||||
"umbreld zou die invullen en de Python-code slopen")
|
||||
"een envsubst-stap zou die invullen en de Python-code slopen")
|
||||
|
||||
|
||||
# ── Het tijdvenster ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# De image voor de app whatsnext-evolu-relay.
|
||||
#
|
||||
# Eén image voor drie containers. De compose start hem drie keer: als `relay`
|
||||
# met het standaardcommando (`node src/index.js`, als gebruiker node), als
|
||||
# `agent` met `python3 /app/agent.py` en als `server` met nginx. Tot 0.5.6 zat
|
||||
# alleen de relay in deze image en draaiden de agent en de pagina als *.template
|
||||
# op python:3-alpine en nginx:alpine; sinds 0.6.0 zit alles hier. Beslist door de
|
||||
# gebruiker op 08-09-2026, na dezelfde stap bij Electrum Gate: één image scheelt
|
||||
# een tweede recept en een tweede pin. Zie het plan Eigenimage, PLAN.md §8.
|
||||
#
|
||||
# Dit bouwt niet de relay van Evolu na: het installeert `@evolu/nodejs` uit npm
|
||||
# en start ons eigen `src/index.js`, dat alleen de twee terugroepfuncties voor de
|
||||
# toegangscontrole toevoegt.
|
||||
@@ -8,28 +16,52 @@
|
||||
# Waarom `slim` en niet `alpine`: `better-sqlite3` zit onder `@evolu/nodejs` en
|
||||
# heeft kant-en-klare binaries voor glibc, niet voor musl. Op alpine zou hij bij
|
||||
# elke bouw opnieuw gecompileerd moeten worden, met een bouwketen erbij in de
|
||||
# image.
|
||||
# image. Dat is ook de reden dat nginx en python3 hier uit apt komen en niet
|
||||
# andersom node in een nginx-image gezet is.
|
||||
#
|
||||
# De bouwcontext is de REPO-ROOT, niet deze map: icon.png blijft in de app-map
|
||||
# staan (het manifest wijst ernaar voor de tegel in de winkel) en wordt van daar
|
||||
# gekopieerd, zodat er niet twee exemplaren zijn. build.sh geeft die context mee.
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
FROM node:24-slim
|
||||
|
||||
# nginx en python3 uit Debian. Geen aanbevolen pakketten: die halen bij nginx
|
||||
# onder meer een set modules binnen die de pagina niet gebruikt. De agent heeft
|
||||
# alleen de standaardbibliotheek nodig.
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends nginx python3 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Eerst alleen het manifest, zodat een wijziging in `src/` de installatielaag niet
|
||||
# ongeldig maakt.
|
||||
COPY package.json ./
|
||||
COPY tools/evolu-relay/package.json ./
|
||||
RUN npm install --omit=dev --no-audit --no-fund
|
||||
|
||||
COPY src ./src
|
||||
COPY tools/evolu-relay/src ./src
|
||||
COPY tools/evolu-relay/agent.py ./agent.py
|
||||
|
||||
# De relay maakt zelf `data/` aan bij de start, maar dan als de gebruiker die op
|
||||
# dat moment draait. Vooraf aanmaken met de juiste eigenaar voorkomt dat een
|
||||
# gemounte map van de host als root wordt aangeraakt.
|
||||
RUN mkdir -p /app/data && chown -R node:node /app
|
||||
# gemounte map van de host als root wordt aangeraakt. Alleen `data/` en `src/` zijn
|
||||
# van node; agent.py en de rest blijven van root, want die worden alleen gelezen.
|
||||
RUN mkdir -p /app/data && chown -R node:node /app/data /app/src
|
||||
|
||||
USER node
|
||||
# De pagina. Debian zet nginx' eigen voorbeeldpagina onder /var/www/html; wij
|
||||
# gebruiken het pad dat de nginx-image ook gebruikt, zodat nginx.conf gelijk kan
|
||||
# blijven aan die van Electrum Gate.
|
||||
COPY tools/evolu-relay/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY tools/evolu-relay/index.html /usr/share/nginx/html/index.html
|
||||
COPY whatsnext-evolu-relay/icon.png /usr/share/nginx/html/icon.png
|
||||
|
||||
# Geen USER hier, en dat is met opzet: nginx moet als root beginnen om poort 80 te
|
||||
# nemen, en de agent schrijft in de gedeelde map. De relay hoort wél als node te
|
||||
# draaien, zoals hij tot 0.5.6 deed, en dat regelt de compose met `user: node`.
|
||||
|
||||
ENV NODE_ENV=production
|
||||
EXPOSE 4000
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
EXPOSE 4000 80
|
||||
|
||||
CMD ["node", "src/index.js"]
|
||||
|
||||
@@ -10,10 +10,12 @@
|
||||
# dan niet kunt reproduceren. De agent schrijft daarom uitsluitend command.json,
|
||||
# en het relay-proces past hem toe en ruimt hem op.
|
||||
#
|
||||
# LET OP: umbreld haalt dit bestand bij elke start door envsubst. Er mag dus geen
|
||||
# dollarteken in staan, ook niet in een regex of een tekst. Een accolade-variabele
|
||||
# die niet bestaat wordt leeg, en dat sloopt Python-code zonder foutmelding.
|
||||
# tests/test_appstore_vorm.py controleert dat.
|
||||
# Dit bestand zit in de image (tools/evolu-relay/Dockerfile) als /app/agent.py.
|
||||
# Tot 0.5.6 was het een *.template in de app-map en haalde umbreld het bij elke
|
||||
# start door envsubst, en daarom staat er geen dollarteken in en komen alle
|
||||
# instellingen uit de omgeving. Dat laatste is zo gebleven: de compose zet ze in
|
||||
# de omgeving neer, en dat is ook de nette weg. tests/test_relay_agent.py houdt
|
||||
# het dollarteken buiten de deur, voor het geval dit ooit weer een template wordt.
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
import json
|
||||
@@ -48,6 +50,12 @@ PUBLIC_PORT = int(os.environ.get("RELAY_PUBLIC_PORT", "3852"))
|
||||
API_PORT = int(os.environ.get("RELAY_API_PORT", "8000"))
|
||||
PROBE_INTERVAL = int(os.environ.get("RELAY_PROBE_INTERVAL", "15"))
|
||||
|
||||
# De versie uit het manifest, voor de kop van de pagina. Tot 0.5.6 vulde umbreld
|
||||
# die rechtstreeks in de pagina in; nu de pagina in de image zit, loopt het via de
|
||||
# status. Leeg betekent dat de compose hem niet doorgeeft, en dan toont de pagina
|
||||
# geen versie in plaats van een verzonnen.
|
||||
APP_VERSION = os.environ.get("RELAY_APP_VERSION", "")
|
||||
|
||||
# Wat de pagina mag vragen. Expliciet en niet doorgeven wat er binnenkomt: dit
|
||||
# bestand wordt door een ander proces uitgevoerd, en een onbekende actie hoort
|
||||
# hier te stranden en niet daar.
|
||||
@@ -260,6 +268,7 @@ def build_status():
|
||||
learning = learning_facts(state)
|
||||
|
||||
return {
|
||||
"version": APP_VERSION or None,
|
||||
"relay": {
|
||||
"reachable": probe["reachable"],
|
||||
"checked": probe["checked"],
|
||||
+64
-27
@@ -2,9 +2,10 @@
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Bouwt de image voor de app whatsnext-evolu-relay.
|
||||
#
|
||||
# Wat er gebouwd wordt is ONS programma: `src/index.js` roept `createRelay` uit
|
||||
# `@evolu/nodejs` aan met onze eigen toegangscontrole erin. De relay zelf komt
|
||||
# gewoon uit npm en wordt niet nagebouwd of aangepast.
|
||||
# Eén image voor de drie containers van de app: de relay (ons `src/index.js` om
|
||||
# `@evolu/nodejs` heen), de agent (`agent.py`) en nginx met de pagina. De relay
|
||||
# zelf komt uit npm en wordt niet nagebouwd of aangepast. Tot 0.5.6 zat alleen de
|
||||
# relay in deze image; sinds 0.6.0 alles, zie de Dockerfile.
|
||||
#
|
||||
# Dit verving op 28-08-2026 het vorige recept, dat de repo van Trezor kloonde en
|
||||
# hun Dockerfile bouwde. Dat pakket had een Postgres en een quota-manager nodig en
|
||||
@@ -17,8 +18,13 @@
|
||||
# bovendien minuten laten hangen. Het recept hoort dus in de repo en het resultaat
|
||||
# in een register; de app verwijst alleen naar de tag.
|
||||
#
|
||||
# Draaien: sh build.sh
|
||||
# Vereist: docker op de machine waar je bouwt. Git is niet meer nodig.
|
||||
# Draaien: sh tools/evolu-relay/build.sh
|
||||
# Vereist: docker op de machine waar je bouwt. Op de Umbrel is dat met sudo.
|
||||
#
|
||||
# Multi-arch: PLATFORMS="linux/amd64,linux/arm64" sh tools/evolu-relay/build.sh
|
||||
# Vraagt buildx met QEMU en duwt meteen. Nog nooit geprobeerd; zie het masterplan
|
||||
# Publicatie-Relay. Zonder PLATFORMS bouwt dit één architectuur, die van de
|
||||
# machine waarop je staat.
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
set -eu
|
||||
@@ -28,15 +34,15 @@ set -eu
|
||||
# zijn dáár de pin. Hier staat alleen het etiket op de uitkomst.
|
||||
#
|
||||
# Dit is het etiket op de IMAGE. Verhoog het als de image verandert, dus als er
|
||||
# iets in src/, package.json of de Dockerfile wijzigt, en zet dan dezelfde waarde
|
||||
# achter `image:` in de compose.
|
||||
# iets in deze map of in icon.png wijzigt, en zet dan dezelfde waarde achter
|
||||
# `image:` in de compose (drie keer: relay, agent en server delen hem).
|
||||
#
|
||||
# `version` in umbrel-app.yml is een ander nummer en mag hierop vooruitlopen: dat
|
||||
# moet bij élke wijziging aan de app omhoog, ook als alleen een template
|
||||
# verandert, want anders rolt umbrelOS hem niet uit. Dat heeft hier een keer een
|
||||
# dag gekost. Ze zijn dus gelijk zolang alleen de image wijzigt, en lopen uiteen
|
||||
# zodra er een reparatie in de app-map zit.
|
||||
VERSION="0.5.0"
|
||||
# moet bij élke wijziging aan de app omhoog, ook als alleen de compose verandert,
|
||||
# want anders rolt umbrelOS hem niet uit. Dat heeft hier een keer een dag gekost.
|
||||
# Sinds alles in de image zit lopen ze meestal gelijk; de regel blijft: verhoog je
|
||||
# VERSION, dan ook het manifest.
|
||||
VERSION="0.6.0"
|
||||
|
||||
# Het register staat er expres in en dit is geen smaakkwestie: umbreld haalt élke
|
||||
# image op via de Docker Engine API, dus een tag die alleen lokaal bestaat is voor
|
||||
@@ -45,12 +51,22 @@ VERSION="0.5.0"
|
||||
IMAGE="sc.kamenier-hamer.nl/sysop/evolu-relay:${VERSION}"
|
||||
|
||||
RECEPT="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||
# De bouwcontext is de repo-root, want icon.png komt uit de app-map. Zie de kop
|
||||
# van de Dockerfile.
|
||||
REPO="$(CDPATH= cd -- "${RECEPT}/../.." && pwd)"
|
||||
|
||||
# ── Controles vooraf ──────────────────────────────────────────────────────────
|
||||
# Beter hier hard falen dan een image bouwen die iets anders bevat dan je denkt.
|
||||
|
||||
if [ ! -f "${RECEPT}/package.json" ] || [ ! -f "${RECEPT}/src/index.js" ]; then
|
||||
echo "FOUT: package.json of src/index.js ontbreekt in ${RECEPT}" >&2
|
||||
for bestand in Dockerfile package.json src/index.js agent.py nginx.conf index.html; do
|
||||
if [ ! -f "${RECEPT}/${bestand}" ]; then
|
||||
echo "FOUT: ${bestand} ontbreekt in ${RECEPT}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -f "${REPO}/whatsnext-evolu-relay/icon.png" ]; then
|
||||
echo "FOUT: whatsnext-evolu-relay/icon.png ontbreekt in ${REPO}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -63,24 +79,45 @@ if [ ! -f "${RECEPT}/package-lock.json" ]; then
|
||||
echo
|
||||
fi
|
||||
|
||||
# Een accolade-variabele hoort hier nergens meer in: deze bestanden gaan niet
|
||||
# meer door envsubst, dus wat er staat is wat er draait. Staat er tóch een, dan
|
||||
# is dat een restant van de template-tijd en zou hij letterlijk in de pagina of
|
||||
# de configuratie terechtkomen.
|
||||
if grep -l '\${' "${RECEPT}/nginx.conf" "${RECEPT}/index.html" "${RECEPT}/agent.py" 2>/dev/null; then
|
||||
echo "FOUT: de bestanden hierboven bevatten nog een \${...}; die wordt niet meer ingevuld." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Bouwen ────────────────────────────────────────────────────────────────────
|
||||
|
||||
echo "Bouwen als ${IMAGE}"
|
||||
docker build --tag "$IMAGE" "$RECEPT"
|
||||
PLATFORMS="${PLATFORMS:-}"
|
||||
|
||||
if [ -n "$PLATFORMS" ]; then
|
||||
echo "Bouwen als ${IMAGE} voor ${PLATFORMS}, en meteen duwen"
|
||||
docker buildx build --platform "$PLATFORMS" --tag "$IMAGE" --push \
|
||||
--file "${RECEPT}/Dockerfile" "$REPO"
|
||||
echo
|
||||
echo "Geduwd. De index-digest:"
|
||||
docker buildx imagetools inspect "$IMAGE" | head -3
|
||||
else
|
||||
echo "Bouwen als ${IMAGE}"
|
||||
docker build --tag "$IMAGE" --file "${RECEPT}/Dockerfile" "$REPO"
|
||||
echo
|
||||
echo "Klaar:"
|
||||
docker image inspect --format '{{.RepoTags}} {{.Id}}' "$IMAGE"
|
||||
echo
|
||||
echo "Bouwen is niet genoeg: de app verwijst naar het register, want umbreld kan"
|
||||
echo "niet bij een image die alleen lokaal staat. Nog te doen:"
|
||||
echo
|
||||
echo " docker login sc.kamenier-hamer.nl"
|
||||
echo " docker push ${IMAGE}"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Klaar:"
|
||||
docker image inspect --format '{{.RepoTags}} {{.Id}}' "$IMAGE"
|
||||
echo
|
||||
echo "Bouwen is niet genoeg: de app verwijst naar het register, want umbreld kan"
|
||||
echo "niet bij een image die alleen lokaal staat. Nog te doen:"
|
||||
echo
|
||||
echo " docker login sc.kamenier-hamer.nl"
|
||||
echo " docker push ${IMAGE}"
|
||||
echo
|
||||
echo "Zet daarna de digest uit de push-uitvoer achter de tag in"
|
||||
echo "whatsnext-evolu-relay/docker-compose.yml, en zet \`version\` in het manifest"
|
||||
echo "op ${VERSION}. Zonder die verhoging rolt umbrelOS het niet uit."
|
||||
echo "whatsnext-evolu-relay/docker-compose.yml (drie keer: relay, agent en server),"
|
||||
echo "en zet \`version\` in het manifest op ${VERSION}. Zonder die verhoging rolt"
|
||||
echo "umbrelOS het niet uit."
|
||||
echo
|
||||
echo "Controleer dat het anoniem te halen is, want umbreld krijgt geen"
|
||||
echo "inloggegevens mee. Log uit in dezelfde context waarin je inlogde, anders"
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
Zichtbare tekst is Engels: dit is een publieke app store en dit is wat een
|
||||
bezoeker ziet. Commentaar is Nederlands.
|
||||
|
||||
LET OP, en dit is de valstrik van dit bestand: umbreld haalt elke *.template
|
||||
bij het starten door envsubst. Er mag dus GEEN dollarteken in staan behalve de
|
||||
umbrel-variabelen die hier werkelijk ingevuld moeten worden. Dat sluit ook
|
||||
JavaScript-template-literals uit, want die gebruiken accolades achter een
|
||||
dollarteken en zouden stilzwijgend leeg worden. Alles hieronder plakt strings
|
||||
dus met een plus aan elkaar. tests/test_appstore_vorm.py houdt dit dicht.
|
||||
Dit bestand zit in de image (tools/evolu-relay/Dockerfile) als
|
||||
/usr/share/nginx/html/index.html. Tot 0.5.6 was het een *.template in de
|
||||
app-map die umbreld bij het starten door envsubst haalde, en daarom plakt
|
||||
alles hieronder strings met een plus aan elkaar in plaats van met een
|
||||
template-literal. Die beperking is weg, maar de stijl is gebleven: één pagina
|
||||
in twee stijlen is erger dan één stijl die niet meer nodig is. De versie in de
|
||||
kop komt uit api/status, waar umbreld hem vroeger rechtstreeks invulde.
|
||||
|
||||
De maatvoering komt uit Electrum Gate en niet uit een eigen ontwerp: dezelfde
|
||||
breedte, hetzelfde raster, dezelfde kop met een icoon van 64 pixels, hetzelfde
|
||||
@@ -640,7 +641,7 @@ body {
|
||||
<h1 class="t-h1">Evolu Relay</h1>
|
||||
<!-- Woordelijk dezelfde regel als de tagline in umbrel-app.yml, en dat is
|
||||
het punt: één app, één regel. -->
|
||||
<p class="t-body-sm">Encrypted sync and backup for your local-first apps <span class="head-version">v${APP_VERSION}</span></p>
|
||||
<p class="t-body-sm">Encrypted sync and backup for your local-first apps <span class="head-version" id="head-version"></span></p>
|
||||
</div>
|
||||
<!-- Het menu rechtsboven, met details/summary en niet met eigen JavaScript:
|
||||
dan werkt openen en sluiten met het toetsenbord zonder dat wij daar iets
|
||||
@@ -1350,6 +1351,10 @@ body {
|
||||
}).then(function (status) {
|
||||
hide('alert-agent');
|
||||
|
||||
// De versie in de kop. Geen put(): die zet "unknown" neer als het ontbreekt,
|
||||
// en een kop met "vunknown" is erger dan een kop zonder versie.
|
||||
if (status.version) { el('head-version').textContent = 'v' + status.version; }
|
||||
|
||||
// De relay.
|
||||
var relay = el('relay-state');
|
||||
relay.classList.remove('ok', 'bad');
|
||||
@@ -6,16 +6,17 @@
|
||||
# waar de relay achter de app-proxy stond en de inlog dus uit moest; zie het plan
|
||||
# Umbrelapp, PLAN.md §4h.
|
||||
#
|
||||
# Dit is een template, en dat is bewust: umbrelOS ververst bij een update alleen
|
||||
# een whitelist van bestanden, en *.template staat daarin. Bij elke start vult
|
||||
# umbrelOS de omgevingsvariabelen in en schrijft het resultaat weg als nginx.conf.
|
||||
#
|
||||
# Let op bij het wijzigen: gebruik hier geen nginx-variabelen met een dollarteken,
|
||||
# zoals de gebruikelijke in een log_format. De invulling vervangt elke
|
||||
# accolade-variabele en zou die stilzwijgend leegmaken. Daarom staat access_log
|
||||
# uit.
|
||||
# Dit bestand zit in de image (tools/evolu-relay/Dockerfile) als
|
||||
# /etc/nginx/nginx.conf. Tot 0.5.6 was het een *.template in de app-map die
|
||||
# umbreld bij elke start door envsubst haalde, en daarom mocht er toen geen
|
||||
# nginx-variabele met een dollarteken in staan. Die beperking is weg. Dat de
|
||||
# access_log nog steeds uit staat is een keuze en geen restant: de pagina hangt
|
||||
# achter de app_proxy en wat die opvraagt is niet interessant.
|
||||
|
||||
user nginx;
|
||||
# www-data en niet nginx: deze nginx komt uit Debian (de image is node:24-slim
|
||||
# met nginx uit apt), en Debian heeft geen gebruiker nginx. Bij Electrum Gate
|
||||
# staat hier wél nginx, want die image is de officiële nginx-image.
|
||||
user www-data;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /var/run/nginx.pid;
|
||||
@@ -45,9 +46,8 @@ http {
|
||||
# geslaagde aanroep doet is de leerstand omzetten of een eigenaar
|
||||
# blokkeren, en dat is precies waar de pagina voor is.
|
||||
#
|
||||
# Geen proxy_set_header, en dat is geen vergetelheid: die zouden een
|
||||
# nginx-variabele vragen en die haalt de template-invulling weg. De agent
|
||||
# heeft ze niet nodig.
|
||||
# Geen proxy_set_header: de agent heeft ze niet nodig.
|
||||
#
|
||||
# De volledige containernaam en niet de servicenaam 'agent'. Dat stond er
|
||||
# eerst, en op het apparaat gaf het een 404 bij ongeveer elke tweede
|
||||
# aanroep (28-08-2026): Electrum Gate heeft óók een service 'agent' op
|
||||
@@ -85,6 +85,7 @@ function leesVersie(appId) {
|
||||
function relayStatus(nu) {
|
||||
const iso = (msVanaf) => new Date(nu + msVanaf).toISOString();
|
||||
return {
|
||||
version: leesVersie('whatsnext-evolu-relay'),
|
||||
relay: { reachable: true, checked: iso(-5000), publicPort: 3852 },
|
||||
owners: {
|
||||
problem: null,
|
||||
|
||||
@@ -33,39 +33,39 @@ services:
|
||||
APP_HOST: whatsnext-evolu-relay_server_1
|
||||
APP_PORT: 80
|
||||
|
||||
# Alle drie de containers draaien dezelfde image, gebouwd uit tools/evolu-relay/
|
||||
# door build.sh en geduwd naar het Gitea-register op dezelfde server als deze
|
||||
# store. Dat moet: umbreld haalt élke image op via de Docker Engine API en niet
|
||||
# via compose, dus een lokaal gebouwde tag is voor hem onbereikbaar en de
|
||||
# installatie faalt met "pull access denied". Op 25-08-2026 op het apparaat
|
||||
# vastgesteld.
|
||||
#
|
||||
# Tot 0.5.6 zat alleen de relay in die image en draaiden de agent en de pagina
|
||||
# als *.template op python:3-alpine en nginx:alpine. Sinds 0.6.0 zit alles erin;
|
||||
# zie het plan Eigenimage, PLAN.md §8.
|
||||
#
|
||||
# De digest hoort erbij en niet alleen de tag: een tag kan opnieuw geduwd worden
|
||||
# en dan draait er iets anders dan hier staat. Staan ze allebei, dan bepaalt de
|
||||
# digest wat er gehaald wordt en is de tag alleen leesbaarheid. Houd de tag
|
||||
# gelijk aan VERSION in build.sh (drie keer hier) en `version` in het manifest.
|
||||
#
|
||||
# De keerzijde bij een verhoging: een OUDE digest onder een NIEUWE tag levert
|
||||
# stilzwijgend de oude image. Bij 0.5.0 stond hier daarom even een tag zonder
|
||||
# digest, zodat het hard faalde tot de image bestond, in plaats van stil de
|
||||
# relay zonder tijdvenster te draaien. Doe dat weer zo bij elke verhoging: eerst
|
||||
# de digest weg, dan bouwen en duwen, dan de nieuwe erin.
|
||||
#
|
||||
# Gebouwd op de Umbrel zelf, dus één architectuur (amd64). Voor de officiele
|
||||
# store hoort er een multi-arch index-digest met arm64 in; zie het masterplan
|
||||
# Publicatie-Relay.
|
||||
relay:
|
||||
# Gebouwd uit tools/evolu-relay/ door build.sh en geduwd naar het
|
||||
# Gitea-register op dezelfde server als deze store. Dat moet: umbreld haalt
|
||||
# élke image op via de Docker Engine API en niet via compose, dus een lokaal
|
||||
# gebouwde tag is voor hem onbereikbaar en de installatie faalt met
|
||||
# "pull access denied". Op 25-08-2026 op het apparaat vastgesteld.
|
||||
#
|
||||
# De digest hoort erbij en niet alleen de tag: een tag kan opnieuw geduwd
|
||||
# worden en dan draait er iets anders dan hier staat. Staan ze allebei, dan
|
||||
# bepaalt de digest wat er gehaald wordt en is de tag alleen leesbaarheid.
|
||||
# Houd de tag gelijk aan `version` in het manifest en aan VERSION in build.sh.
|
||||
#
|
||||
# Let op: dit is één architectuur (amd64), want er is alleen amd64 gebouwd.
|
||||
# Voor de officiele store hoort er een multi-arch index-digest met arm64 in;
|
||||
# zie het masterplan Publicatie-Relay.
|
||||
#
|
||||
# De digest hoort erbij en niet alleen de tag: een tag kan opnieuw geduwd
|
||||
# worden en dan draait er iets anders dan hier staat. Staan ze allebei, dan
|
||||
# bepaalt de digest wat er gehaald wordt en is de tag alleen leesbaarheid.
|
||||
#
|
||||
# Dat laatste heeft een keerzijde die je moet kennen bij een verhoging: een
|
||||
# OUDE digest onder een NIEUWE tag levert stilzwijgend de oude image. Bij
|
||||
# 0.5.0 stond hier daarom even een tag zonder digest, zodat het hard faalde
|
||||
# tot de image bestond, in plaats van stil de relay zonder tijdvenster te
|
||||
# draaien. Doe dat weer zo bij de volgende verhoging: eerst de digest weg,
|
||||
# dan bouwen en duwen, dan de nieuwe erin.
|
||||
#
|
||||
# Gebouwd en geduwd op de Umbrel zelf op 30-08-2026, dus de architectuur
|
||||
# klopt per constructie. Let op: dit is één architectuur (amd64). Voor de
|
||||
# officiele store hoort er een multi-arch index-digest met arm64 in; zie het
|
||||
# masterplan Publicatie-Relay.
|
||||
image: sc.kamenier-hamer.nl/sysop/evolu-relay:0.5.0@sha256:1e4dafdcdf0c424f96100d49a53924fbd61c931517da7bd1e26ddc027acea49a
|
||||
image: sc.kamenier-hamer.nl/sysop/evolu-relay:0.6.0
|
||||
restart: on-failure
|
||||
# Als node en niet als root, zoals de image tot 0.5.6 zelf al deed met USER.
|
||||
# Nu de image ook nginx en de agent draagt, staat er geen USER meer in en
|
||||
# regelt de compose het per container; de relay is de enige die het niet
|
||||
# nodig heeft. De map data/relay is van deze gebruiker.
|
||||
user: node
|
||||
ports:
|
||||
# De relay zelf. Dit is de poort waar Zoraxy met TLS naartoe wijst, en de
|
||||
# enige die deze app publiceert; de pagina loopt via app_proxy.
|
||||
@@ -96,13 +96,17 @@ services:
|
||||
# zelf leegmaakt. Twee processen die in dezelfde allowlist schrijven is een
|
||||
# wedloop die je een keer per jaar treft en dan niet kunt reproduceren.
|
||||
agent:
|
||||
# TODO pinnen op de multi-arch index-digest, met
|
||||
# `docker buildx imagetools inspect python:3-alpine`. Geldt ook voor nginx
|
||||
# hieronder; staat als taak in het plan Umbrelapp.
|
||||
image: python:3-alpine
|
||||
image: sc.kamenier-hamer.nl/sysop/evolu-relay:0.6.0
|
||||
restart: on-failure
|
||||
command:
|
||||
- python3
|
||||
- /app/agent.py
|
||||
environment:
|
||||
RELAY_STATE_DIR: /var/lib/relay
|
||||
# De versie uit het manifest, voor de kop van de pagina. Die stond tot 0.5.6
|
||||
# rechtstreeks in de pagina, ingevuld door umbreld; nu de pagina in de image
|
||||
# zit, geeft de agent hem door via api/status.
|
||||
RELAY_APP_VERSION: ${APP_VERSION}
|
||||
# De volledige containernaam en niet de servicenaam 'relay'. Bij Electrum
|
||||
# Gate gaf de korte naam op het apparaat een geweigerde verbinding: de naam
|
||||
# loste wél op, maar naar een container van een andere app op hetzelfde
|
||||
@@ -113,33 +117,21 @@ services:
|
||||
# Moet gelijk zijn aan de hostpoort hierboven.
|
||||
RELAY_PUBLIC_PORT: "3852"
|
||||
RELAY_API_PORT: "8000"
|
||||
PYTHONUNBUFFERED: "1"
|
||||
volumes:
|
||||
# Door umbrelOS ingevuld uit agent.py.template bij het starten. Er staat
|
||||
# geen accolade-variabele in dat bestand, dus de invulling laat de
|
||||
# Python-code ongemoeid; de agent leest zijn instellingen uit de omgeving
|
||||
# hierboven. De test in tests/ controleert die aanname.
|
||||
- ${APP_DATA_DIR}/agent.py:/app/agent.py:ro
|
||||
# Dezelfde map als de relay. De agent moet hier kunnen schrijven, want de
|
||||
# opdrachten van de pagina landen hier.
|
||||
- ${APP_DATA_DIR}/data/relay:/var/lib/relay
|
||||
command:
|
||||
- python
|
||||
- /app/agent.py
|
||||
|
||||
# nginx met de pagina, uit dezelfde image. Geen mounts: pagina, configuratie en
|
||||
# icoon zitten in de image, en de pagina heeft geen eigen staat.
|
||||
server:
|
||||
image: nginx:alpine
|
||||
image: sc.kamenier-hamer.nl/sysop/evolu-relay:0.6.0
|
||||
restart: on-failure
|
||||
# De agent moet er zijn voordat nginx start: de proxy_pass naar
|
||||
# http://agent:8000 wordt bij het starten opgelost en een onbekende naam laat
|
||||
# nginx afbreken.
|
||||
command:
|
||||
- nginx
|
||||
- -g
|
||||
- daemon off;
|
||||
# De agent moet er zijn voordat nginx start: de proxy_pass naar de agent wordt
|
||||
# bij het starten opgelost en een onbekende naam laat nginx afbreken.
|
||||
depends_on:
|
||||
- agent
|
||||
volumes:
|
||||
# Beide door umbrelOS ingevuld uit een .template bij het starten.
|
||||
- ${APP_DATA_DIR}/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ${APP_DATA_DIR}/index.html:/usr/share/nginx/html/index.html:ro
|
||||
# Het app-icoon, voor de kop van de pagina en het tabblad. Geen template,
|
||||
# dus dit bestand komt alleen bij een installatie mee en niet bij een
|
||||
# update; voor een plaatje dat vrijwel nooit wijzigt is dat goed genoeg.
|
||||
- ${APP_DATA_DIR}/icon.png:/usr/share/nginx/html/icon.png:ro
|
||||
|
||||
@@ -11,7 +11,7 @@ manifestVersion: 1
|
||||
id: whatsnext-evolu-relay
|
||||
category: files
|
||||
name: Evolu Relay
|
||||
version: "0.5.6"
|
||||
version: "0.6.0"
|
||||
tagline: Encrypted sync and backup for your local-first apps
|
||||
description: >-
|
||||
Local-first apps keep your data on your own device and work whether or not you have a
|
||||
@@ -43,6 +43,15 @@ description: >-
|
||||
your app at the address shown there. Away from home you will need a way in, such as Tailscale
|
||||
or a reverse proxy with your own domain.
|
||||
releaseNotes: >-
|
||||
The whole app now ships as one image: the relay, the status page and the small helper behind it. Until
|
||||
now only the relay did, and the other two were mounted into stock images from the app folder. Nothing
|
||||
changes in what the app does; the app data folder now holds only your data, and the icon updates along
|
||||
with everything else.
|
||||
|
||||
|
||||
Everything in 0.5.6:
|
||||
|
||||
|
||||
Owners are now listed most recently seen first, in both panels. Until now the rows kept the order in
|
||||
which owners first showed up, which stops meaning anything after a week. The order follows along on its
|
||||
own: the page refreshes its lists every few seconds, so a reconnecting owner moves to the top without a
|
||||
|
||||
Reference in New Issue
Block a user