UmbrelApps: community app store whatsnext
Electrum Gate, Evolu Relay en Atreides Assets, met de image-recepten in tools/ en de tests in tests/. Begonnen zonder voorgeschiedenis op 09-10-2026. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
85d85a1295
63 files changed
+13987
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,137 @@
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# Evolu Relay - je eigen sync-server voor apps die op Evolu gebouwd zijn.
|
||||
#
|
||||
# Drie containers: de relay, een agent voor de statuspagina, en nginx die die
|
||||
# pagina serveert. Geen Postgres en geen quota-manager meer; die hoorden bij de
|
||||
# relay van Trezor, en die is als zelf-gehoste relay in de kern onbruikbaar omdat
|
||||
# de cliënt bij een eigen relay-URL nooit een eigenaar registreert. Zie het plan
|
||||
# Umbrelapp, OPEN.md punt 6, en de proef in PLAN.md §6a.
|
||||
#
|
||||
# De poortindeling is omgedraaid ten opzichte van 25-08-2026, en dat is de kern
|
||||
# van dit bestand:
|
||||
#
|
||||
# - de PAGINA hangt achter app_proxy, mét de inlog van umbrelOS. Vroeger stond de
|
||||
# relay daar en moest de inlog dus uit, waardoor een statuspagina net zo
|
||||
# onbeschermd zou zijn als de relay zelf;
|
||||
# - de RELAY publiceert zijn eigen poort, waar Zoraxy met TLS naartoe wijst.
|
||||
# een sync-cliënt is geen browser met een sessiecookie en zou achter de inlog
|
||||
# een inlogpagina krijgen in plaats van de relay.
|
||||
#
|
||||
# Dat is hetzelfde patroon als Electrum Gate in deze store: de web-UI via de
|
||||
# proxy, het protocol op een eigen poort. Zie PLAN.md §4h.
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
services:
|
||||
# umbrelOS genereert deze service zelf; wij vullen alleen in waar hij heen moet
|
||||
# wijzen. De hostnaam heeft de vorm <app-id>_<compose-service>_1.
|
||||
#
|
||||
# PROXY_AUTH_ADD staat hier bewust NIET op "false". Dat stond er tot 0.0.2 wel,
|
||||
# toen de relay hierachter hing. Nu wijst dit naar de statuspagina, en die hoort
|
||||
# juist achter de inlog. Zet het niet terug zonder §4h te lezen.
|
||||
app_proxy:
|
||||
environment:
|
||||
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:
|
||||
image: sc.kamenier-hamer.nl/sysop/evolu-relay:0.7.1@sha256:a701032aae4aba8fd7acace0c0d6c900ad6ace32eee03762b36b00c7e8c0ce6c
|
||||
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.
|
||||
#
|
||||
# 3852 op de host en niet 4000: dat laatste is een veelgebruikte poort en
|
||||
# een botsing merk je pas als de app niet start. Dezelfde les als bij
|
||||
# Electrum Gate, dat om die reden 50022 gebruikt in plaats van 50002.
|
||||
# Binnen de container blijft het 4000, want dat is wat de relay verwacht.
|
||||
- "3852:4000"
|
||||
environment:
|
||||
RELAY_PORT: "4000"
|
||||
# Per schrijfactie en niet per eigenaar; zo is isOwnerWithinQuota bij Evolu
|
||||
# bedoeld. Eén labelwijziging is klein, dus een schrijfactie hierboven is
|
||||
# eerder een fout of misbruik dan normaal gebruik. Zie PLAN.md §4g.
|
||||
RELAY_MAX_WRITE_BYTES: "1048576"
|
||||
volumes:
|
||||
# De database van de relay én onze allowlist ernaast, in dezelfde map. Het
|
||||
# programma doet chdir naar `data`, net als de relay van Evolu zelf, dus dit
|
||||
# pad ligt vast.
|
||||
#
|
||||
# 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 synchronisatie een
|
||||
# herinstallatie van de app niet overleven.
|
||||
- ${APP_DATA_DIR}/data/relay:/app/data
|
||||
|
||||
# De agent bedient de statuspagina. Hij beslist niets: hij leest wat het
|
||||
# relay-proces heeft opgeschreven en legt opdrachten in een postbus die de relay
|
||||
# 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:
|
||||
image: sc.kamenier-hamer.nl/sysop/evolu-relay:0.7.1@sha256:a701032aae4aba8fd7acace0c0d6c900ad6ace32eee03762b36b00c7e8c0ce6c
|
||||
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
|
||||
# netwerk. De vorm <app-id>_<service>_1 is uniek per app.
|
||||
RELAY_HOST: whatsnext-evolu-relay_relay_1
|
||||
RELAY_PORT: "4000"
|
||||
# Alleen om op de pagina het adres te tonen dat je in je cliënt invult.
|
||||
# Moet gelijk zijn aan de hostpoort hierboven.
|
||||
RELAY_PUBLIC_PORT: "3852"
|
||||
RELAY_API_PORT: "8000"
|
||||
volumes:
|
||||
# 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
|
||||
|
||||
# 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: sc.kamenier-hamer.nl/sysop/evolu-relay:0.7.1@sha256:a701032aae4aba8fd7acace0c0d6c900ad6ace32eee03762b36b00c7e8c0ce6c
|
||||
restart: on-failure
|
||||
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
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
@@ -0,0 +1,195 @@
|
||||
# De veldvolgorde hieronder is niet vrij: de packaging-documentatie van de
|
||||
# officiele appstore schrijft hem voor. Zie de tabel in
|
||||
# HomeGit/Docs/Referenties/UmbrelApps/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: files
|
||||
name: Evolu Relay
|
||||
version: "0.7.1"
|
||||
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
|
||||
connection. A relay is what lets a second device catch up: it holds the encrypted changes
|
||||
until your other devices come online. This app runs that relay on your Umbrel, so the copy
|
||||
in the middle sits on hardware you own.
|
||||
|
||||
|
||||
It is the relay from the Evolu project, taken straight from the package they publish and not
|
||||
reimplemented here. Any app built on Evolu can use it.
|
||||
|
||||
|
||||
Your data is encrypted on your device before it leaves. The relay holds encrypted blobs,
|
||||
padded so their size says nothing, and never has the key. What it can see is an owner id,
|
||||
which identifies data without identifying you, along with timestamps and the addresses that
|
||||
connect. Self-hosting does not make the data more secret than it already is; what it changes
|
||||
is who keeps the encrypted copy, who can see that you are syncing at all, and whether anyone
|
||||
can pull the service out from under you.
|
||||
|
||||
|
||||
What this app adds is the part a self-hosted relay needs and a public one does not: control
|
||||
over who may use it. New owners are accepted one at a time. The first one that connects is
|
||||
remembered, and you close the door again once your own devices are paired; anything new is
|
||||
refused until you open it. Any owner can be blocked or removed later.
|
||||
|
||||
|
||||
The tile opens a status page behind your umbrelOS login, showing whether the relay is
|
||||
running, how much it holds, when it was last written to, and which owners are allowed. Point
|
||||
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: >-
|
||||
Tidying up the two owner panels. They are called Accepted and Waiting now, the count of owners waiting
|
||||
sits in that panel's own heading instead of a widget at the top, the note under the relay address is
|
||||
gone, and a row on the waiting list no longer carries a "Waiting" tag: the panel it sits in already says
|
||||
that, and a blocked owner is now the only row with a tag.
|
||||
|
||||
|
||||
Every row is the same height as well, in both panels. A row used to grow the moment you gave it a
|
||||
name, because the name pushed the owner id onto a line of its own; the id now shares the second line
|
||||
with the timestamps.
|
||||
|
||||
|
||||
About this app no longer insists the sync address must start with http. Which scheme the field in your
|
||||
app wants depends on the app; the host and the port are the same either way.
|
||||
|
||||
|
||||
Everything in 0.6.0:
|
||||
|
||||
|
||||
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
|
||||
reload.
|
||||
|
||||
|
||||
Everything in 0.5.4:
|
||||
|
||||
|
||||
The status widget has moved to the right of the top row and is now called Status, matching Electrum
|
||||
Gate. The two pages are one app store and they should read the same way.
|
||||
|
||||
|
||||
Everything in 0.5.3:
|
||||
|
||||
|
||||
Two adjustments to the refresh. The Relay card reads in the accent colour again when it says
|
||||
Running, and on a phone the page drops back to the flat look: the glow is wider than a phone screen,
|
||||
so it stopped being a gradient and became a haze over everything.
|
||||
|
||||
|
||||
Everything in 0.5.2:
|
||||
|
||||
|
||||
A visual refresh, shared with the other apps in this store. The page now has a soft glow behind it in
|
||||
the accent colour, and the cards are translucent with a light edge and a shadow, so they read as
|
||||
panels sitting on the page instead of flat blocks painted on it. Card corners are a little tighter,
|
||||
and every framed element now uses the same corner radius. Nothing about what the relay does has
|
||||
changed.
|
||||
|
||||
|
||||
Everything in 0.5.1:
|
||||
|
||||
|
||||
Fixes a message at the top of the page that never went away. Confirming that a command was sent is worth
|
||||
saying for a second or two, but it stayed until you reloaded the page, so it was still there long after it
|
||||
stopped being true. It now clears itself as soon as the relay has picked the command up. A refusal is the
|
||||
exception and stays put: that is the only explanation you get of what went wrong.
|
||||
|
||||
|
||||
Everything in 0.5.0, released the same day:
|
||||
|
||||
|
||||
Accepting a new owner is now a two minute window instead of a switch you have to remember to turn
|
||||
back off. Open it, pair your device, and it closes on its own; you can close it early or restart the
|
||||
two minutes if you need longer. The countdown runs on the Umbrel, so closing the page does not leave
|
||||
the door open.
|
||||
|
||||
|
||||
Owner ids can be given a name. They are long strings of random characters that say nothing about
|
||||
which of your devices or wallets they are, so hover a row and label it. Names are kept on your Umbrel
|
||||
and are never sent anywhere.
|
||||
|
||||
|
||||
Blocked owners and refused attempts were two lists and are now one, because what you do with them is
|
||||
the same: allow, or forget. Each row carries a badge saying which it was.
|
||||
|
||||
|
||||
The page itself has been rebuilt to match Electrum Gate in this store: the same width, the same
|
||||
layout, the same header, and the version number where you can see it. Buttons appear when you hover a
|
||||
row, so a page you are only reading stays quiet. Explanatory paragraphs have moved into a new
|
||||
"About this app" item in the menu, which also spells out what the relay can and cannot see.
|
||||
|
||||
|
||||
Earlier releases:
|
||||
|
||||
|
||||
0.4.0 fixed a status page that alternated between working and showing an error. It reached its helper
|
||||
by a short name that another app in this store uses as well, so about half of its requests ended up
|
||||
at the wrong app.
|
||||
|
||||
|
||||
0.4.0 also dropped the wording that tied the app to one particular client. It is a general purpose
|
||||
Evolu relay: any app built on Evolu can use it.
|
||||
|
||||
|
||||
0.2.0 replaced the relay this app shipped with. Until 0.0.2 it packaged a vendor's own deployment,
|
||||
which came with a quota manager and a PostgreSQL database and could not work outside that vendor's
|
||||
service: clients skip the quota manager as soon as you point them at a relay of your own, while
|
||||
that relay refuses every owner the quota manager never registered. 0.2.0 uses the relay from the
|
||||
Evolu project instead. Measured, not assumed: a client synced to it and the data arrived. Three
|
||||
containers became one relay plus a status page, and the database and its password are gone.
|
||||
|
||||
|
||||
0.2.0 also added the status page behind your umbrelOS login, and control over who may sync.
|
||||
|
||||
|
||||
Not verified yet: reading back from a second device, and whether every client platform can use a
|
||||
relay of your own.
|
||||
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. Sinds 0.1.0 is dat de STATUSPAGINA
|
||||
# en niet de relay: de app-proxy zet er de inlog van umbrelOS voor, en daar hoort
|
||||
# een pagina wel achter en een relay niet. De cliënt wijst naar 3852, die de
|
||||
# relay zelf publiceert. Zie docker-compose.yml en het plan Umbrelapp, PLAN.md §4h.
|
||||
#
|
||||
# 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 ────────────────
|
||||
#
|
||||
# Het icoon, sinds 28-08-2026. Het bestand staat in deze repo en wordt door Gitea
|
||||
# rauw uitgeleverd; dezelfde constructie als bij Electrum Gate. Bij inlevering in
|
||||
# de officiële store moet deze regel juist weg, want die host iconen apart.
|
||||
# Daarom staat hij als laatste: dan is het één regel schrappen.
|
||||
icon: https://sc.kamenier-hamer.nl/sysop/UmbrelApps/raw/branch/main/whatsnext-evolu-relay/icon.png
|
||||
|
||||
# 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