Commit graph

96 commits

Author SHA1 Message Date
Ramon
90e4160727 v0.9.00-beta - één hoofdmap, paden kloppend en data verhuizen
Some checks failed
Deploy server-up (dev) / deploy (push) Failing after 2m40s
- LIBRARY_DIR, DATA_DIR en BACKUP_DIR worden afgeleid van BASE_DIR in plaats
  van hard op /opt/serverup te staan
- docker-compose geeft BASE_DIR nu ook aan de container door; die stond alleen
  in de mount, dus de app bleef /opt/serverup voorstellen bij een /srv-mount
- het installatieformulier vult appdata_dir met de ingestelde DATA_DIR, zodat
  alle 286 sjablonen de juiste map voorstellen
- Instellingen → Paden heeft een hoofdmap met afgeleide submappen, een
  kopieerknop per pad en "Alles overnemen"
- nieuw GET /api/paths/check: is het pad schrijfbaar en binnen de gemounte
  BASE_DIR, met de .env-regel als dat niet zo is
- nieuw POST /api/paths/move: stacks stoppen, kopiëren, controleren, paden in
  compose/.env/metadata omschrijven, stacks starten en pas dán het oude
  opruimen
- jobs.voortgang() plus een voortgangsbalk boven het terminallog
- core/paden.py met meten, bereikbaarheid, verhuizen en omschrijven
- docs/installeren.md en .env.example beschrijven BASE_DIR als de manier om
  alles te verplaatsen

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-02 14:06:17 +02:00
Ramon
b6319e8fdd v0.8.82-beta - "Poort {port} is vrij" stond er letterlijk
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 17m4s
- De poortcontrole werd aangesloten op vertaalsleutels die er al waren, en twee
  daarvan verwachten een plaatshouder die ik niet meegaf: port_free wil {port},
  port_in_use wil {port} en {by}
- Nieuwe test die elke t('sleutel', {...}) in de interface vergelijkt met de
  plaatshouders in de Nederlandse tekst, in beide richtingen en ook voor
  aanroepen zonder variabelen. Die laatste toevoeging was nodig: de eerste
  versie van de test liet juist de fout passeren waar hij voor gemaakt was
- De test kent nu ook de verkorte objectnotatie van JavaScript ({name} betekent
  {name: name}); zonder dat meldde hij vier bestaande aanroepen ten onrechte

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-02 12:57:14 +02:00
Ramon
d7c4682cc7 v0.8.81-beta - Poortcontrole ook bij Instellingen wijzigen
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 15m26s
Het scherm Instellingen wijzigen van een bestaande stack is hetzelfde formulier
als bij het installeren, maar openReconfigure() zette de poortcontrole niet in
gang. De knoppen en de handmatige controle werkten daar wel; alleen de melding
bij het openen bleef weg.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-02 09:44:35 +02:00
Ramon
ef945fcd71 v0.8.80-beta - Poortcontrole in het formulier, en installeren op een telefoon
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 15m55s
- /api/ports/check bestond al en kijkt naar wat Docker publiceert en naar wat
  er rechtstreeks op de host luistert, maar het installatieformulier riep hem
  nergens aan. Er stond hooguit een regeltje als de standaardwaarde bezet was;
  typte je zelf iets, dan hoorde je niets
- Een poortveld heeft nu een min- en plusknop, een vergrootglas om te
  controleren, en een melding: vrij, of bezet en door welke container, met een
  knop om naar de eerstvolgende vrije poort te springen. De controle loopt ook
  bij het openen van een stap
- Kan de host niet uitgelezen worden, dan zegt de melding dat "vrij" een
  aanname is in plaats van dat te verzwijgen
- De knoppen zitten alleen op velden die ook echt een poort zijn; puid en pgid
  zijn ook getallen
- De installatiemodal is op een telefoon schermvullend, met de kop en de
  knoppenbalk vast en alleen de inhoud die scrollt. Vorige en Volgende vullen
  samen de breedte
- Sluitknop in de kop van de modal: schermvullend betekent geen achtergrond meer
  om op te tikken, en die was er nog niet

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-02 07:57:05 +02:00
Ramon
0c025d657d v0.8.70-beta - De store blijft soepel, en 28 apps erbij
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 17m15s
- filteredStore() werd per repo drie keer per reactieve tick aangeroepen (in de
  x-show, de x-for en de teller in het filtermenu) en liep elke keer alle apps
  langs met een toLowerCase() per veld. Bij elke toetsaanslag. De catalogus ging
  deze reeks van 142 naar 286 apps en dat begon te merken; het filteren gebeurt
  nu een keer per filterstand
- Nog maar zestig kaarten tegelijk in de DOM, met een knop Nog N tonen eronder.
  De limiet valt terug zodra je het filter of de zoekterm wijzigt
- Het zoekveld wacht 200 ms voordat het filtert
- 28 apps in de dunste hoeken: 2FAuth, Passbolt, OpenBao, Trivy, Verdaccio,
  Docker Registry, MkDocs Material, LiteLLM, Flowise, Speaches, Pelican Panel,
  Gameyfin, EmulatorJS, Mainsail, Fluidd, Kanboard, Wekan, Filestash,
  Linkwarden, Slash, RSSHub, Apprise, Mailpit, Dashy, Plausible, NetBird,
  LibreSpeed en PinePods
- Alle 318 images opnieuw tegen hun registry gecontroleerd

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 23:56:11 +02:00
Ramon
0500e8945b v0.8.60-beta - Backups bevatten nu je gegevens, Pangolin en Newt erbij
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 15m31s
- Een backup bevatte alleen de stackmap: compose, .env en metadata.
  LIBRARY_DIR en de appdata-map staan naast elkaar, geen genestelde mappen, dus
  je maakte een backup, kreeg een groen vinkje en hield bij terugzetten een lege
  app over. Een archief heeft nu drie takken: de stackmap, de appdata van die
  stack, en een dump per database
- De dump is geen dubbelop: een tar van een draaiende PostgreSQL is een
  momentopname van bestanden die tijdens het inpakken veranderden. Bij
  terugzetten komt de dump erin nadat de container draait, met een wachtlus.
  Stond de container tijdens de backup uit, dan is dat een waarschuwing in het
  log en geen stille overslag
- Nieuwe instelling BACKUP_APPDATA (standaard aan), uit te zetten bij een
  mediabibliotheek waar dit in de honderden gigabytes loopt
- apps/newt en apps/pangolin. Server Up had al een Pangolin-integratie met een
  publiceerknop per stack, maar je moest Pangolin zelf elders vandaan halen
- Nieuwe stap in de setup-wizard na git: koppelen aan een bestaande Pangolin,
  hier installeren, of overslaan. De wizard hing zijn afhandeling aan
  stapnummers, dus met een stap ertussen ging de git-stap mis; dat gaat nu op de
  naam van de stap
- depends_on waarschuwt nu ook op de stackpagina. Haal je Mosquitto later weg,
  dan viel Zigbee2MQTT stil zonder dat iets zei waarom

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 23:20:24 +02:00
Ramon
1db3d3e8a0 v0.8.50-beta - Leesbare namen, zichtbaar wat al draait, en bruikbaar op een telefoon
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 14m6s
- Het auditlog toonde ruwe id's als 'store', 'reconfigure' en
  'credentials_view'. Die hebben nu namen, ook in de filterlijsten, en de
  kolomkoppen zijn vertaald in plaats van hardgecodeerd Nederlands. Onbekende
  waarden vallen terug op de ruwe tekst zodat een module niets kapotmaakt
- Nieuwe test die de broncode afloopt en elke audit.log() zonder vertaling
  aanwijst
- Een modulepagina heette in de titelbalk letterlijk 'mod:mijnmodule'
- De store herkende een installatie aan de mapnaam: een stack telde alleen mee
  als hij 'sonarr' of 'sonarr-...' heette. Wie zijn stack 'media-tv' noemde
  kreeg te zien dat Sonarr niet geinstalleerd was. Nu via de source uit
  .serverup.json, met een duidelijk Geinstalleerd-label per installatie waar je
  op kunt klikken om ernaartoe te gaan
- Twaalf icoonknoppen per stack werden op een telefoon drie rijen plaatjes
  zonder naam. Daar blijven starten, herstarten en logs staan, plus een menu met
  de rest, mét namen. Op een breed scherm verandert er niets
- De rij van twintig categorieknoppen boven de stacks is hetzelfde compacte menu
  geworden als in de app store

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 14:20:28 +02:00
Ramon
072fdff3a2 v0.8.40-beta - Filter in de app store is een menu geworden
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 13m11s
- Twintig categorieknoppen en veertien labelknoppen stonden altijd uitgeklapt
  boven de store; bij 256 apps vulde dat een half scherm. Nu een knop Filter
  met een popover: categorieen in een raster van twee kolommen met kleur en
  aantal, labels met een eigen zoekveld, en onderaan het aantal resultaten met
  een wisknop. Sluit met Escape of door ernaast te klikken
- De labelfilter werkte maar half: de rij was afgekapt op veertien terwijl er
  297 labels zijn, dus 283 daarvan waren niet te kiezen. Het menu zoekt nu in
  de volledige lijst; zonder zoekterm de veertig meest gebruikte, en een gekozen
  label blijft zichtbaar ook als het zeldzaam is
- Actieve filters staan als chips naast de knop, met een kruisje per stuk. Het
  zoekveld heeft een wisknop
- Nieuwe test die het hele sjabloon op gebalanceerde HTML-tags controleert. Een
  verkeerd geplaatste </div> schuift de rest van de pagina in een andere tak en
  dat merk je anders pas in de browser
- Nieuwe JS-tests voor de filterlogica: filteren op categorie en label, de
  teller, wissen, en zoeken naar een zeldzaam label

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 08:39:36 +02:00
Ramon
b54e7003e8 v0.8.30-beta - depends_on in sjablonen, en vijftien domotica-apps
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 13m41s
- Nieuwe metadata-sleutel depends_on: een sjabloon kan zeggen welke andere app
  het nodig heeft en waarom. Het installatiescherm toont dat voor het invullen,
  met een knop naar dat sjabloon. Advies, geen blokkade -- de broker of Home
  Assistant kan net zo goed op een andere machine staan
- De reden is verplicht; een waarschuwing zonder uitleg klik je weg. De korte
  vorm ["mosquitto"] werkt ook, voor sjablonen uit externe repo's
- Toegepast op acht sjablonen waar het gemis onzichtbaar was: zigbee2mqtt,
  alloy, alertmanager, node-exporter, cadvisor, collabora, double-take, soularr.
  Niet op element, open-webui, exportarr, unpackerr en onlyoffice: die werken
  met meerdere alternatieven, en depends_on kent geen "een van deze"
- Vijftien domotica-apps, van 12 naar 27 in die categorie: Piper, Whisper en
  openWakeWord (spraakbediening van Home Assistant, tot nu toe volledig
  afwezig), Matter Server, Matter Hub, AppDaemon, go2rtc, Double Take,
  Domoticz, openHAB, DSMR-reader (P1-poort slimme meter), rtl_433 (433 MHz
  sensoren naar MQTT), Traccar, Snapcast en EMQX
- Catalogus van 241 naar 256 apps; alle 285 images gecontroleerd

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 04:58:50 +02:00
Ramon
42bd87047a v0.8.20-beta - Prometheus startte niet, en 23 apps erbij
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 12m38s
- apps/prometheus was kapot: het koppelde een lege map op /etc/prometheus en
  startte met --config.file naar een bestand dat er nooit kwam. Er zit nu een
  startconfiguratie bij, met koppelvelden naar node-exporter en cAdvisor
- De meeste apps van deze ronde zijn de ontbrekende helft van wat er al stond:
  node-exporter, cAdvisor en Alertmanager maken Prometheus bruikbaar; Loki en
  Alloy bewaren logs waar Dozzle alleen live meekijkt; Unbound zoekt DNS zelf op
  in plaats van door te vragen aan Google of Cloudflare
- Domeinen die ontbraken: evcc (energie), Healthchecks (cronbewaking),
  Infisical (geheimen voor applicaties), Music Assistant, pgAdmin
- Verder Crafty, Manyfold, ErsatzTV, FitTrackee, ComfyUI, Omada, en de zwaardere
  Zabbix, Graylog, Wazuh, NetBox, Seafile en OpenCloud. Van 218 naar 241 apps
- Nieuw tools/controleer_images.py: controleert of elk image echt bestaat. De
  ad-hoc versie draaide met zestien verzoeken tegelijk en meldde negen
  ontbrekende images die alle negen wel bestonden -- registries knijpen af, en
  dat is niet te onderscheiden van een ontbrekend image. Nu vier tegelijk met
  opnieuw proberen, en als stap in de drie workflows

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 04:06:26 +02:00
Ramon
c9b73d8b69 v0.8.10-beta - Vervangers voor big tech, en sleutels in het juiste formaat
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 2m31s
- Sjablonen kunnen nu secret_format ("hex" of "laravel") en secret_bytes
  opgeven. De generator maakte altijd url-veilige base64, en dat is precies wat
  Laravel, Homarr en LibreChat weigeren
- Daarmee kwamen twee fouten uit v0.8.00 aan het licht: Homarr en LibreChat
  kregen sleutels die hun containers niet accepteren. Rechtgezet
- Snipe-IT en Invoice Ninja alsnog toegevoegd; die vielen vorige ronde af omdat
  hun APP_KEY niet te genereren was
- 19 vervangers voor big tech erbij, van 197 naar 218 apps:
  Baikal en Radicale (Google Agenda/Contacten), LibreTranslate (Translate),
  CryptPad, Collabora en ONLYOFFICE (Google Docs), Formbricks (Forms),
  Jitsi Meet (Meet/Zoom), PeerTube, Invidious en Tube Archivist (YouTube),
  Owncast (Twitch), Mastodon (X), Pixelfed (Instagram), Lemmy (Reddit),
  Cal.com (Calendly), Rallly (Doodle), DocuSeal (DocuSign), Penpot (Figma)
- Communicatie van 12 naar 16 apps, productiviteit van 21 naar 31
- Nieuwe JS-test voor de sleutelformaten; alle 242 images in de catalogus
  opnieuw tegen hun registry gecontroleerd

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-08-01 03:49:10 +02:00
Ramon
7d178a68b0 v0.8.00-beta - 55 apps erbij, en drie kapotte images gevonden
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 2m22s
- Catalogus van 142 naar 197 apps. Het zwaartepunt lag na het ARR-werk op media
  (42 apps) terwijl communicatie er 4 had, AI 4, financien 3 en foto's 2
- Drie nieuwe categorieen: Statistiek, Zakelijk en Spellen
- Homelab-gereedschap: Dockge, Komodo, Glance, Gatus, Scrutiny, Backrest,
  Headscale, Zoraxy, CrowdSec, NetAlertX, Pocket ID, Authentik
- Communicatie van 4 naar 12: Mattermost, Synapse, Element, Listmonk, Mumble,
  Roundcube, Stalwart
- Notities: Outline, Trilium, SilverBullet, Readeck, Docmost, Kiwix
- Verder LibreChat, AnythingLLM, LocalAI, Ghostfolio, Wallos, Maybe, Lychee,
  Piwigo, Homebox, wger, Donetick, Dawarich, Gitea, Adminer, code-server,
  Woodpecker, Semaphore, Opengist, MinIO, Pingvin Share, Umami, Matomo, Odoo,
  FreeScout, EspoCRM, RomM, Minecraft, Leantime, PrivateBin, Emby, ConvertX
- Drie bestaande apps waren niet installeerbaar: Forgejo wees naar een
  latest-tag die dat project niet publiceert, Planka naar een tag 1 die niet
  bestaat, en Baby Buddy naar een ghcr-pad dat er niet is. Gevonden door alle
  213 images in de catalogus langs de registries te halen
- Twee testregels waren te krap: een config.yaml in files/ die geen compose is
  telde niet mee voor "veld wordt gebruikt", en geheimen die de gebruiker zelf
  aanlevert stonden in een handmatige namenlijst. Dat laatste is nu een vlag in
  het sjabloon: "eigen_invoer": true
- Nieuwe controles voor de 36 apps met een eigen database: elke extra container
  draagt de servicenaam als voorvoegsel, geen vaste databasewachtwoorden, en er
  wacht altijd iemand met depends_on op de database

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-07-31 23:47:41 +02:00
Ramon
58d9be1f48 v0.7.90-beta - ARR-stack opgesplitst, /data-mount, netwerkopties per container
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 2m1s
- Elk *arr-onderdeel is nu ook een losse app in de store (46 nieuwe sjablonen);
  los en gebundeld komen uit één bron (tools/arr_sjablonen.py) met een test die
  bewaakt dat ze niet uiteen lopen
- Alles deelt één /data-map, zodat hardlinks werken; losse /tv-, /movies- en
  /downloads-mounts zijn eruit, UMASK=002 erbij
- Nieuwe eerste stap "Onderdelen" in het invulmenu, met kopjes per soort; de
  dubbele groepsschakelaar en de lege kaarten in Instellingen zijn weg
- Eigen IP-adres per container in plaats van per stack; containers zonder adres
  houden hun poortmapping. Ook Pangolin publiceert nu per container
- Huntarr vervangen door NeutArr (project offline na lekken, image bestaat niet
  meer), Maintainerr naar zijn nieuwe organisatie
- 31 apps toegevoegd uit het *arr-ecosysteem, alle images tegen hun registry
  gecontroleerd
- data_dir hernoemd naar appdata_dir in de hele catalogus, naast de nieuwe
  data_root; qBittorrent van poort 8080 naar 8097

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
2026-07-31 22:21:04 +02:00
Ramon
ea9b1eb668 v0.7.80-beta - Volgende-knop, tijdzones, netwerken per groepje, Pangolin
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 2m10s
De knop Volgende deed niets. Alpine haalt een boolean-attribuut alleen weg bij
null, undefined of false; het getal 0 zet het juist AAN. Mijn
:disabled="stepMissing().length" gaf bij een ingevuld formulier 0 en zette de
knop dus permanent uit. De logica klopte, de binding niet — met losse logica
niet te vinden, dus er draait nu een test die de echte modal met Alpine in een
DOM rendert en erop klikt.

Tijdzones:
- Nieuwe instelling TIMEZONE, standaard die van de server (TZ, /etc/timezone,
  /etc/localtime). In alle 77 sjablonen stond Europe/Amsterdam hard ingevuld.
- Apps zonder tijdzoneveld krijgen TZ er automatisch bij; die draaiden in UTC.

Poorten:
- _bezette_poorten() telt nu ook mee waar de host zelf op luistert, gelezen uit
  /proc/net/tcp in een hulpcontainer met --network host. Een nginx buiten
  Docker zag Server Up eerder niet.
- GET /api/ports/check geeft vrij/bezet plus een alternatief, en meldt of de
  host echt gecontroleerd kon worden.

Netwerken:
- APP_NETWORKS: meerdere gedeelde bridge-netwerken in plaats van één waar élke
  app aan hing. Per app kies je welke; aanmaken kan vanuit het invulmenu, met
  eigen naam of een voorstel (su-<appnaam>).
- add_shared_network() accepteert een lijst; één naam blijft werken.
- GET /api/networks/<n>/ip-check controleert subnet, bereik, Docker-toewijzing
  en de ARP-tabel van de host (vangt een fysiek apparaat met DHCP-adres) en
  stelt een vrij adres voor.

Pangolin (nieuw, core/pangolin.py):
- Publieke URL per app via een tunnel, zonder poorten open te zetten.
- De API veranderde in 1.9 (resource hing onder een site, staat nu los); beide
  routes worden geprobeerd en bij een fout krijg je beide meldingen.
- API-sleutel is write-only. Getest tegen een nagebouwde API, niet tegen een
  echte server.

Nieuw: docs/pangolin.md; docs/netwerken.md uitgebreid. 2369 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-28 22:25:38 +02:00
Ramon
bc55252267 v0.7.70-beta - invulmenu bij installeren, geheimen naar .env
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m34s
Invulmenu:
- Vaste stappen (Basis, Verbinden, Instellingen, Toegang, Controleren) in
  plaats van één lange lijst. Eén stap per groep werkt niet: de mediane app
  heeft één groep, arr-stack eenentwintig. Lege stappen worden overgeslagen.
- Volgende controleert de verplichte velden van die stap; die melding kwam
  eerder pas bij het installeren.
- Geavanceerde opties achter één schakelaar die op elke stap zichtbaar is,
  plus 'Alles op één pagina' voor het oude gedrag. Beide onthouden.

Geheimen naar .env:
- compose_transform.geheimen_naar_env() vervangt geheime waarden door
  ${NAAM} en schrijft ze naar .env met rechten 0600. Werkt ook midden in
  een database-URL. Poorten en paden blijven leesbaar in compose.
- .serverup.json bevat geen geheimen meer en krijgt ook 0600; daar stonden
  ze wereldleesbaar in. Het herconfiguratieformulier leest ze terug uit
  .env via een bewaarde veld-naar-sleutel-koppeling.
- docs/beveiliging.md legt uit wat dit niet oplost: docker inspect toont de
  waarde nog steeds.

Bewerken:
- Laatste stap toont het gerenderde resultaat met jouw waarden en is
  bewerkbaar; compose_override/env_override gaan mee bij het installeren.
  Ongeldige YAML wordt geweigerd voordat er een map bestaat.
- De bestaande editor heeft tabbladen (compose/.env) en biedt herstarten na
  opslaan. De .env-PUT weigert een regel zonder '=' en logt in audit.

Inloggegevens:
- /api/stacks/<n>/credentials plus paneel op de stackkaart: adres,
  gebruikersnaam, wachtwoord achter een oog-knop, kopieerknop. Alleen voor
  beheerders, elk bekijken komt in het auditlog.
- Nieuw 'credential'-kenmerk in template.json met naamherkenning als
  terugval, zodat de bestaande 96 sjablonen meteen werken.

Herstel van een regressie uit v0.7.60: acht inlogwachtwoorden hadden hun
genereerknop verloren toen die aan 'generate' werd gehangen. Terug, behalve
waar een verzonnen waarde fout is (WireGuard-sleutel, externe tokens).

De menulogica wordt getest door de echte component uit index.html in Node uit
te voeren; slaat zichzelf over waar node ontbreekt. 2295 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-28 21:31:51 +02:00
Ramon
952e7ddb7a v0.7.60-beta - app-instellingen nagelopen op fouten bij het installeren
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m27s
Aanleiding: Homepage weigerde met "Host validation failed" omdat de
standaardwaarde van allowed_hosts poort 3001 noemde terwijl het poortveld op
3002 stond. Alle 96 sjablonen zijn daarop nagelopen.

Systemisch:
- De dobbelsteenknop, waar zeventien apps in hun uitleg naar verwijzen,
  verscheen nooit: hij hing af van een veld 'secret' dat fields() niet
  meestuurde. Wachtwoorden stonden daardoor leesbaar in het formulier.
- 27 velden die je toch nooit zelf typt (databasewachtwoorden, JWT- en
  versleutelingssleutels) worden nu voorgevuld met een willekeurige waarde.
  Inlogwachtwoorden krijgen alleen een knop, want die moet je noteren.
- De knop hangt nu aan 'generate' in plaats van aan 'secret': voor een
  WireGuard-privésleutel of een token uit een andere app is een verzonnen
  waarde juist fout.
- required werd nergens gecontroleerd. Je kon installeren met een leeg
  databasewachtwoord of een lege sleutel. Nu geweigerd bij installeren en bij
  herconfigureren, met vermelding van de lege velden. Velden achter een
  uitgeschakelde groepsschakelaar tellen niet mee.
- Wachtwoorden werden uitgeschreven in het installatielog; nu gemaskeerd.

Losse fouten:
- homepage: allowed_hosts stond op localhost:3001, nu * met uitleg.
- baserow, hedgedoc, ntfy: URL in de standaardwaarde wees naar een poort waar
  niets luistert.
- Vast wachtwoord in acht sjablonen weggehaald: ghost, immich, miniflux,
  paperless-ngx, unifi-network en vikunja kregen allemaal dezelfde
  database-wachtwoorden; grafana en gotify stonden op 'admin'.
- data_dir bij keycloak, metube, miniflux en teslamate stond in het formulier
  maar kwam nergens terecht (die apps gebruiken een Docker-volume).
- puid/pgid bij freshrss: het image kent ze niet.
- prometheus gaf de gevraagde tijdzone niet door.

Nieuw tests/test_app_templates.py: rendert elke app met zijn standaardwaarden
en controleert ongedefinieerde variabelen, velden zonder werking,
niet-gedeclareerde volumes, depends_on, dubbele containernamen,
poortconflicten, poortnummers in standaardwaarden en vaste wachtwoorden.
2236 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-28 20:08:07 +02:00
Ramon
87fb9d19d1 v0.7.50-beta - meldingen, schijfruimte, backups controleren en extern wegzetten
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m22s
Het onbewaakte deel was de zwakke plek: geplande taken draaiden 's nachts en
een storing kwam alleen in het auditlog terecht.

Meldingen (core/notify.py):
- ntfy, webhook (Discord/Slack/Gotify) en e-mail, alle drie met de
  standaardbibliotheek.
- Gebeurtenissen: mislukte backup, onleesbaar archief, vastgelopen taak,
  weinig schijfruimte, beschikbare update, gestopte container.
- Eén bericht per ronde; bij schijfruimte en gestopte containers alleen bij
  de overgang, zodat je niet elk uur hetzelfde krijgt.
- Testknop die eerst opslaat, zodat je test wat je net hebt ingevuld.
- send() gooit nooit: het kanaal mag de taak die de melding veroorzaakte niet
  alsnog laten omvallen.

Schijfruimte (core/diskspace.py):
- Controle vóór elke backup; past het niet, dan weigeren in plaats van
  halverwege afbreken.
- DISK_MIN_FREE_GB blijft gereserveerd, DISK_WARN_PCT kleurt de balk rood.
- Per filesystem één regel in de backuplijst.

Backups controleren:
- Elk nieuw archief wordt helemaal uitgelezen (tar-structuur plus
  gzip-checksum, die aan het eind staat).
- Diepe variant pakt echt uit naar een tijdelijke map, met dezelfde
  beperkingen als een echt herstel.
- Resultaat staat in de metadata en als schildje in de lijst.

Backups de deur uit:
- Downloadknop.
- BACKUP_OFFSITE_DIR kopieert elke nieuwe backup naar een gemounte schijf,
  NFS- of SMB-share, via .part zodat een afgebroken kopie herkenbaar onaf is.
- Ruimtecontrole op de bestemming, want een weggevallen mount laat vaak een
  lege map op de systeemschijf achter.

NOTIFY_TOKEN en NOTIFY_EMAIL_PASSWORD zijn write-only.

Nieuw: docs/meldingen.md; docs/backups.md uitgebreid. Getest tegen een
draaiende server met een echte ontvanger. 1064 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-28 19:41:35 +02:00
Ramon
8e53b90615 v0.7.40-beta - beheerdersaccount en bind meteen klaarzetten
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m14s
Deploy server-up (prod) / deploy (push) Successful in 1m44s
Release / release (push) Successful in 5s
Het installatiescript kan nu allebei zelf regelen, zodat je na afloop niet
meer naar de webinterface hoeft om een account te claimen en niet meer in
.env hoeft te duiken om erbij te kunnen.

Beheerdersaccount:
- Op een terminal wordt gevraagd of je er meteen een wil, met naam en
  wachtwoord (twee keer, echo uit).
- Automatisch via --admin NAAM plus --admin-password-file of
  SU_ADMIN_PASSWORD; zonder bron en zonder terminal maakt het script er
  zelf een van 24 tekens en toont die.
- --admin-password weigert bewust: argumenten zijn zichtbaar in 'ps'. Het
  wachtwoord gaat via stdin naar curl, niet als argument.
- Nieuw --create-admin voor een installatie die al draait.

Bereikbaarheid:
- Keuzemenu voor BIND (deze server / hele netwerk / eigen adres), met het
  gedetecteerde serveradres erbij.
- Bij opnieuw installeren is de bestaande instelling het uitgangspunt, zodat
  enter je server niet ongemerkt terugzet op loopback.

Opgeloste fouten:
- Een bestaande .env bleef altijd ongemoeid, ook met --bind: de installatie
  leek te lukken terwijl de server op het oude adres bleef luisteren.
- --update rekende met de standaardpoort in plaats van met wat er in .env
  staat, waardoor de wachtlus en het slotadres niet klopten.
- --dry-run riep 'sudo docker' aan en vroeg dus om een wachtwoord terwijl
  het net beloofd had niets te doen; zonder terminal liep het daarop vast.
- Ongeldig bind-adres en poort buiten 1-65535 worden nu meteen geweigerd.

Getest met een pseudo-terminal voor de vragen en tegen een echt draaiende
server voor het aanmaken van het account, inclusief een wachtwoord vol
aanhalingstekens en backslashes, een geweigerd tweede account en een server
die niet reageert. De e2e-tests slaan zichzelf over waar curl ontbreekt,
zoals in het CI-image. 992 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 21:13:06 +02:00
Ramon
be1aad94ae v0.7.30 - releaseversie
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m21s
Deploy server-up (prod) / deploy (push) Successful in 42s
Release / release (push) Successful in 3s
Eerste stabiele release sinds v0.4.60: VERSION kaal, changelog-kop zonder
-beta zodat release.yml de juiste sectie vindt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 20:38:36 +02:00
Ramon
2862f7844c v0.7.30-beta - installatiescript voor Linux
Some checks failed
Deploy server-up (dev) / deploy (push) Failing after 35s
Deploy server-up (prod) / deploy (push) Failing after 40s
curl -fsSL https://git.ramonbesselink.nl/bes-r/server-up/raw/branch/main/install.sh | sh

install.sh controleert het systeem, biedt aan Docker te installeren als dat
ontbreekt, kloont de repo (of pakt het tar-archief uit als git ontbreekt), maakt
.env aan, bouwt en start, wacht op /healthz en toont waar je terecht kunt met de
waarschuwing meteen een account aan te maken.

- Opties: --dir, --port, --bind, --branch, --token, --update, --uninstall,
  --yes, --dry-run.
- --update haalt nieuwe code op en herstart; .env, stacks en gegevens blijven.
- --uninstall stopt de container maar laat gegevens staan, en vertelt hoe je
  die alsnog opruimt.
- Gebruikt alleen sudo waar nodig: kun je zelf in de doelmap schrijven en
  docker aanroepen, dan blijft alles onder je eigen account.

Tijdens het testen gevonden en verholpen:
- `docker compose --project-directory` zoekt zonder -f het compose-bestand in de
  huidige map; bij `curl | sh` is dat je thuismap. Nu altijd -f erbij.
- De wachtlus gaf anderhalve minuut geen teken van leven; nu een punt per
  poging en 90 in plaats van 120 seconden.
- Bij --dry-run braken ontbrekende Docker-onderdelen de voorvertoning af; nu
  waarschuwingen zodat je de hele gang van zaken ziet.
- De versie-uitlezing uit /healthz tolereert nu ook json met spaties.

Documentatie: docs/installeren.md met alle opties, bijwerken, verwijderen en een
probleemoplostabel; README verwijst ernaar.

Tests: syntaxis onder sh/dash/bash, geen bashismen, --help noemt alle opties,
ongeldige invoer stopt, een proefdraai maakt niets aan, en de installatieregel
in README en docs is identiek.

958 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 19:30:45 +02:00
Ramon
2ba15418ab v0.7.20-beta - instellingen wijzigen, koppelen achteraf, defect uit v0.7.00
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m13s
Defect (v0.7.00): add_shared_network() hing elke service aan het gedeelde
netwerk, ook services met network_mode. Docker compose weigert die combinatie
("declares mutually exclusive network_mode and networks"), waardoor Homebridge,
Scrypted, Beszel en de ARR-stack met Gluetun niet te installeren waren met de
standaardkeuze "Verbinden met andere apps". Die services worden nu overgeslagen;
blijft er niets over, dan ook geen netwerkblok. Test over alle 96 apps.

Instellingen wijzigen na installatie:
- De gemaakte keuzes worden bij installatie opgeslagen in .serverup.json
  (values + format); zonder die waarden viel het formulier niet te heropenen.
- GET /api/stacks/<naam>/config geeft de opgeslagen waarden plus het actuele
  veldschema; POST /reconfigure maakt een backup, rendert opnieuw, past netwerk
  en eigen IP opnieuw toe, valideert en herstart. Mislukt het valideren, dan
  wordt de backup teruggezet.
- Knop Instellingen op de stackkaart opent dezelfde modal in wijzigen-stand,
  met een waarschuwing dat handmatige compose-wijzigingen verloren gaan.
- Stacks van voor deze versie: knop uit met uitleg.

Bestaande stacks koppelen:
- POST /api/stacks/<naam>/connect zet een bestaande stack op het gedeelde
  netwerk, valideert en herstart; wordt de compose ongeldig, dan wordt de
  wijziging teruggedraaid.

Audit-log:
- audit.query()/count() accepteren filters op bron, actie, status, periode en
  vrije tekst; facets() levert de keuzelijsten. /api/audit ondersteunt die als
  queryparameters plus doorbladeren. Filterbalk in de UI.

Documentatie:
- README.md (bestond niet), docs/apps-maken.md met het volledige
  templateformaat, docs/README.md als index.
- Changelog-secties voor v0.5.44/45/46 aangevuld; release.yml haalt de notes
  daaruit, dus een tag daarop gaf een lege release. Test die afdwingt dat het
  huidige VERSION een sectie heeft.

941 tests groen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 15:43:49 +02:00
Ramon
ff1979ba51 v0.7.10-beta - categorieen met kleur in de app store en bij je apps
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m10s
- Nieuw core/categories.py: zeventien categorieen, elk met naam (nl/en), kleur
  en pictogram. Kleuren zijn middentonen die in licht en donker leesbaar zijn;
  de interface gebruikt ze als tekstkleur op een doorzichtige variant.
- Alle 96 apps ingedeeld via metadata.categories. Een app mag in meerdere
  categorieen zitten; 39 apps doen dat (Frigate onder domotica en media,
  Immich onder fotos en opslag, Kavita onder media en documenten).
- Apps uit externe repos geven geen categorieen op; die worden afgeleid uit
  tags en omschrijving, zodat ook zij een kleur en een plek in het filter
  krijgen.
- App store: gekleurde categoriebalk met aantallen, klikbare badges per app,
  werkt naast het bestaande zoekveld en de tagfilters.
- Stackslijst: dezelfde balk met alleen de categorieen die je draait, gekleurde
  rand per kaart en klikbare badges.
- Nieuw /api/categories geeft de definities met kleur, zodat interface en
  backend dezelfde kleur voor dezelfde categorie gebruiken. /api/stacks geeft
  de categorieen mee; een stack van voor deze versie valt terug op "overig"
  in plaats van kleurloos te blijven.
- Tests: elke app heeft geldige categorieen, kleuren zijn uniek, en er staat
  geen categorie in het filter zonder apps.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 14:14:25 +02:00
Ramon
4450b3c171 v0.7.00-beta - apps koppelen, eenvoudiger instellen, geavanceerde opties verborgen
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m16s
Apps onderling verbinden:
- Elke stack draaide als eigen compose-project met een eigen netwerk, waardoor
  stacks elkaar niet op naam konden bereiken. Bij installeren staat nu
  "Verbinden met andere apps" aan: de stack komt op een gedeeld bridge-netwerk
  (SHARED_NETWORK, standaard "serverup") dat op aanvraag wordt aangemaakt.
- compose_transform.add_shared_network() hangt elke service eraan en laat
  bestaande netwerken staan, dus het werkt samen met een macvlan-adres.
- Nieuw /api/apps/connectable geeft de geinstalleerde apps met hun
  containernamen, zodat de installatiemodal kan laten kiezen.

Kiezen in plaats van typen:
- Een veld met "connect": {"app": "mosquitto", "scheme": "mqtt", "port": 1883}
  toont een keuzelijst met wat er al draait, met handmatig invullen als
  terugval. Toegepast op zigbee2mqtt -> mosquitto en open-webui -> ollama.
- Is de doel-app nog niet geinstalleerd, dan zegt het veld dat.

Uitleg per instelling:
- Info-icoon per veld opent een blok met de volledige uitleg plus de
  standaardwaarde. Uitgeschreven voor de instellingen die de meeste vragen
  oproepen (downloadmap vs mediamap, shm_size bij frigate, poort 80 bij caddy,
  PUID bij de arr-stack, GPU bij ollama, publiek adres bij wg-easy).

Geavanceerde opties:
- advanced: true op een veld of groep zet het achter een uitklapblok met
  teller. Toegepast op wachtwoorden, PUID/PGID, USB-paden en bewaartermijnen
  van 28 apps.
- Test bewaakt dat elke app zichtbare velden overhoudt en dat koppelvelden naar
  een bestaande app verwijzen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 13:52:17 +02:00
Ramon
146d7ae79d v0.6.20-beta - 31 apps erbij na een rondgang langs de verzamelsites
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m24s
Van 65 naar 96 apps. Selectie op basis van awesome-selfhosted, selfh.st,
Perfect Media Server en een paar overzichtslijsten van 2026, aangevuld met de
gaten in de bestaande collectie.

- Monitoring: prometheus, influxdb, netdata, beszel
- Proxy: caddy
- Notities/kennis: memos, hedgedoc, wikijs, excalidraw, karakeep
- Data: nocodb, baserow, metabase
- Identiteit: authelia, keycloak
- Media: komga, photoprism, metube, pinchflat
- Meldingen: ntfy
- Productiviteit: planka, focalboard, kimai
- Locatie/voertuig: owntracks, teslamate
- Hulpmiddelen: shlink, cyberchef, languagetool, kopia
- AI: ollama, open-webui

Prometheus ontbrak terwijl Grafana er al stond; Authelia en Keycloak sluiten
aan op de reverse-proxy-SSO die Server Up zelf ondersteunt.

De images van de nieuwere apps (beszel, karakeep, pinchflat) zijn nagetrokken
bij de bron in plaats van uit het hoofd opgeschreven. Van karakeep is de
officiele compose overgenomen inclusief de meilisearch- en chrome-containers.

Vijftien poortbotsingen met bestaande apps automatisch rechtgezet. Caddy deelt
80/443 met traefik en nginx-proxy-manager (alternatieven voor dezelfde taak) en
staat daarvoor in de allowlist.

705 tests groen; elke app rendert naar geldige compose-YAML met gedeclareerde
volumes en zonder onvervangen variabelen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 13:37:40 +02:00
Ramon
7ae62fe78c v0.6.10-beta - ARR-stack met een schakelaar per onderdeel
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m32s
De ARR-stack installeerde altijd dezelfde zeven containers. Nu kies je per
onderdeel uit twintig:

- Media: sonarr, radarr, lidarr, readarr, whisparr
- Indexers: prowlarr, jackett, flaresolverr, bazarr
- Downloaden: qbittorrent, sabnzbd, nzbget, gluetun (VPN)
- Aanvullend: jellyseerr, recyclarr, unpackerr, tdarr, autobrr, maintainerr,
  huntarr

Standaard aan: sonarr, radarr, prowlarr, bazarr, qbittorrent, jellyseerr.

Gluetun:
- Staat die aan, dan draaien de downloadclients in diens netwerknamespace
  zonder eigen poortmapping; anders lekt hun verkeer om de VPN heen. Hun
  webinterfaces komen op de poorten van de Gluetun-container.
- qBittorrent en SABnzbd luisteren allebei standaard op 8080 en botsten
  daardoor achter een gedeelde namespace. qBittorrent draait nu intern op 8090.

Groepsschakelaars werkten niet:
- Een `toggle` op een groep in template.json was zelf geen variabele en kreeg
  dus nooit een startwaarde, waardoor elk schakelbaar onderdeel standaard uit
  stond en een stack met schakelaars leeg binnenkwam. fields() geeft de
  schakelaar nu mee als synthetisch bool-veld met een instelbare
  standaardstand (toggle_default), en de UI toont hem alleen in de kop van de
  groep in plaats van er ook nog eens onder.

Tests: elk onderdeel levert precies een service op als het aan staat en geen
spoor als het uit staat, de downloadclients zitten achter de VPN zonder eigen
poorten, en de interne poorten achter Gluetun botsen niet. Poortbotsingen met
bestaande apps rechtgezet (8090 -> 8097, 8095 -> 8098); 6881 en 5055 blijven
gedeeld met de losse variant van dezelfde app.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 09:46:01 +02:00
Ramon
b8c8e89fa0 v0.6.00-beta - 29 apps erbij, en named volumes die verdwenen
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m5s
Bij het toevoegen van de apps kwam een bestaande fout boven water.
_drop_empty_mappings ruimt sleutels op die een <% if %>-blok leeg achterlaat,
maar een named volume wordt gedeclareerd als een kale sleutel zonder waarde
(`  immich_pgdata:`). Die werd opgeruimd, waarna ook het bovenliggende
`volumes:` wegviel en de services verwezen naar een volume dat nergens meer
gedeclareerd stond. Immich, Ghost, Miniflux, Paperless-ngx, Unifi Network en
Vikunja waren daardoor niet installeerbaar: docker compose weigert met "refers
to undefined volume". Alleen bekende compose-sleutels worden nu opgeruimd.

29 nieuwe apps (teller op 65):
- Domotica: zigbee2mqtt, mosquitto, esphome, node-red, zwave-js-ui,
  homebridge, scrypted, frigate
- 3D-printen: bambuddy, octoprint, spoolman
- Gezin/huishouden: baby-buddy, grocy, tandoor, firefly-iii
- Media: audiobookshelf, navidrome, kavita, calibre-web, jellyseerr
- Kennis: bookstack, freshrss, wallabag
- Netwerk/beheer: wg-easy, homepage, searxng, duplicati, watchtower,
  technitium-dns

Nieuwe tests/test_apps.py rendert elke app met de echte engine en controleert
geldige YAML, image of build per service, gedeclareerde named volumes, geen
onvervangen variabelen en geen onbedoeld dubbele standaardpoorten. Die laatste
vond zeven botsingen tussen nieuwe en bestaande apps; rechtgezet. Logische
botsingen (reverse proxies op 80/443, dns-blokkers op 53) staan met uitleg in
een allowlist.

Het image van Bambuddy is nagetrokken op de bron
(github.com/maziggy/bambuddy): ghcr.io/maziggy/bambuddy, poort 8000.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 08:23:58 +02:00
Ramon
7f0d34cb1a v0.5.50-beta - containers tonen die niet bij een beheerde stack horen
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m5s
Het dashboard meldde 13 actieve containers en 17 images terwijl die nergens
terug te vinden waren. De tellers komen van `docker info` (de hele daemon), de
stacklijst toont alleen mappen in LIBRARY_DIR met een compose-bestand. Alles wat
buiten Server Up om gestart is telde dus wel mee maar was onzichtbaar.

- Nieuw /api/containers: alle containers op de host, met per container of hij
  bij een beheerde stack hoort (compose-project of werkmap onder LIBRARY_DIR).
- Blok "Overige containers" onder de stacklijst, met start/stop/herstart/logs.
- Dashboardteller "actief" vermeldt nu hoeveel daarvan via Server Up loopt.
- De eigen container is gemarkeerd en kan niet via dit blok gestopt worden;
  daarvoor blijft de herstartknop in de instellingen.
- Rollen: een viewer ziet de lijst maar mag niets bedienen.

Verholpen tijdens het bouwen: containers zonder poorten en zonder
compose-labels vielen uit de lijst als ze als laatste regel stonden, doordat
strip() de lege velden aan het eind wegnam en de regel daarna te weinig
kolommen leek te hebben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 07:57:35 +02:00
Ramon
8da53aba6f changelog: weggevallen tekst herstellen (backticks door de shell opgegeten)
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m17s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 00:14:18 +02:00
Ramon
b30f83866f v0.5.43-beta - van-tot omrekenen naar een CIDR-blok
Some checks failed
Deploy server-up (dev) / deploy (push) Has been cancelled
"Ik wil van 10.0.20.200 tot .254" bestaat niet als CIDR-notatie: 55 adressen,
terwijl Docker alleen uitgelijnde blokken van een macht van twee accepteert.
Dat is niet iets wat een gebruiker zelf hoort uit te rekenen.

- Nieuwe range_options(): vertaalt een gewenst begin- en eindadres naar twee
  bruikbare blokken. "Ruim" is het kleinste blok dat de hele wens omvat,
  "krap" het grootste blok dat er volledig binnen valt. Met per optie hoeveel
  adressen erbij komen of ontbreken.
- Endpoint POST /api/networks/range en een uitklapbare van-tot-hulp onder het
  IP-range-veld; klikken op een optie vult het veld.
- Voor 10.0.20.200-254 levert dat 10.0.20.192/26 op: 62 adressen, .193 t/m .254.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 00:13:53 +02:00
Ramon
cbb232d63f v0.5.42-beta - netwerk toevoegen: twee blokkades weg
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m3s
Gemeld met twee screenshots: een foutmelding dat de IP-range buiten het subnet
lag terwijl 10.0.20.240/28 gewoon binnen 10.0.20.0/24 valt, en een geval zonder
melding waarbij aanmaken toch niet lukte. Twee losse oorzaken.

1. Verouderd beoordelingsantwoord
   De live beoordeling gaat af bij elke toetsaanslag. Tijdens het typen van
   /28 kom je langs /2, en 10.0.20.240/2 normaliseert naar 0.0.0.0/2 - buiten
   het subnet. Kwam dat antwoord na het goede binnen, dan bleef die fout staan
   en bleef de knop uit.
   - Volgnummer op de verzoeken; alleen het antwoord bij de laatste vraag telt.
   - Knop niet meer uitgeschakeld op clientstatus; de server beslist bij het
     opslaan, zodat een verouderde beoordeling nooit blokkeert.

2. CIDR met hostbits
   10.0.20.200/28 leest Python met strict=False als 10.0.20.192/28, maar Docker
   weigert het met "has host bits set". We valideerden soepel en stuurden de
   ruwe tekst door, dus de interface keurde iets goed dat bij het aanmaken
   alsnog strandde.
   - normalize() zet subnet en ip_range om naar canonieke vorm voor ze naar
     Docker gaan en voor ze worden opgeslagen.
   - Waarschuwing die toont wat er van de invoer gemaakt is.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-27 00:06:12 +02:00
Ramon
4346fefe4d v0.5.41-beta - netwerk toevoegen liep vast tijdens het typen
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m10s
JSON-parsefout in de browser bij het toevoegen van een netwerk.

De live beoordeling die bij elke toetsaanslag afgaat, bouwde een lijst van alle
bruikbare adressen in het bereik. Tijdens het intypen van 192.168.1.0/24 is de
tussenstand 192.168.1.0/2 een geldig netwerk met 1.073.741.824 adressen; het
verzoek liep daarop vast en de browser kreeg geen JSON terug.

- review() rekent eerste adres, laatste adres en aantal nu uit via
  num_addresses in plaats van hosts() te doorlopen. Alle prefixes van /1 tot
  /32 antwoorden binnen 0,05 seconde.
- suggest_range() had hetzelfde probleem: die somde alle /28-blokken op, bij
  een /8 ruim een miljoen. Rekent nu van achteren naar voren, hoogstens
  zestien stappen.
- Waarschuwing bij meer dan 4096 adressen in het bereik; dat is vrijwel altijd
  een typefout in het prefix.
- Tests met /1 t/m /32, inclusief een vergelijking van _bruikbaar_bereik() met
  de uitkomst van hosts() uit de stdlib, en tijdslimieten zodat een
  herintroductie meteen opvalt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 23:42:56 +02:00
Ramon
a1fb5f5a8f v0.5.40-beta - netwerken instellen zonder uitzoekwerk
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m11s
- Automatische detectie van het hostnetwerk: interface, subnet, gateway en een
  voorgestelde vrije IP-range worden bovenaan het formulier getoond en vullen
  met een klik alles in.
- Detectie gebeurt via een kortstondige container in de netwerknamespace van de
  host, die de routetabel uitleest. Dat repareert meteen een fout: de vorige
  host_interfaces() las /sys/class/net binnen de container en toonde dus de
  bridge-interface van de container in plaats van de netwerkkaart van de host.
- Live beoordeling terwijl je typt (nieuwe endpoint /api/networks/review): laat
  zien hoeveel adressen je overhoudt en welke, en legt in gewone taal uit wat er
  niet klopt. Onderscheid tussen blokkerende fouten en waarschuwingen.
- Knop die een vrij blok voorstelt op basis van het subnet, met de gateway
  ontweken.
- Uitklapbare uitleg in het formulier over hoe subnet, gateway, IP-range en
  host-interface samenhangen, met voorbeeld.
- docs/netwerken.md uitgebreid met een schema van de adresverdeling, een tabel
  met veelgebruikte ranges, en de nadruk op het punt dat het instellen van de
  range in Server Up niets aan de router doet: daar moet het DHCP-bereik zelf
  verkleind worden.
- Bijgesteld tijdens het testen: een gateway binnen het subnet is de normale
  situatie en gold ten onrechte als fout wanneer er geen eigen range was
  opgegeven. Nu alleen een waarschuwing bij een expliciete range.
- 248 tests (21 nieuwe).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 23:16:52 +02:00
Ramon
f40fd39ed9 v0.5.30-beta - rollen, app-store-filter en twee planningsfouten
Some checks failed
Deploy server-up (dev) / deploy (push) Failing after 2s
Rollen per gebruiker:
- Drie rollen: beheerder (alles), operator (stacks, containers en backups) en
  alleen lezen. Afgedwongen in de before_request-guard, niet alleen in de UI.
- Eigen wachtwoord wijzigen mag iedereen; de laatste beheerder kan niet
  gedegradeerd of verwijderd worden.
- Proxy-gebruikers zonder eigen account krijgen AUTH.proxy_role; bestaat er wel
  een lokaal account met die naam, dan wint dat account.
- Accounts van voor deze versie hebben geen rol en gelden als beheerder.

Rechtenescalatie verholpen:
- set_password verving het hele gebruikersrecord, waardoor het role-veld
  wegviel. Een ontbrekende rol geldt als beheerder (nodig voor bestaande
  accounts), dus elke operator of viewer kon zichzelf tot beheerder promoveren
  door zijn eigen wachtwoord te wijzigen. Gevonden bij het naspelen van de
  rollenflow tegen een draaiende instantie.

Geplande backups draaiden nooit:
- De scheduler stempelde ook taken af die zichzelf hadden overgeslagen. De
  backup-taak bewaakt zelf het ingestelde uur, dus die werd afgestempeld op het
  moment van de eerste tick; 24 uur later viel het volgende moment op precies
  dat verkeerde tijdstip. Een taak stempelt nu alleen af bij True. De
  backup-taak draait op een kort interval en beslist zelf, zodat een gewijzigde
  planning meteen werkt. BACKUP_SCHEDULE_DAY toegevoegd voor wekelijks.

Verder:
- Zoekveld en tagfilters in de app store; repo's zonder treffers vallen weg.
- Opstartcontrole op de meegeleverde front-end-bestanden: mislukt het downloaden
  tijdens de image-build, dan laadde de UI zonder opmaak terwijl de server prima
  leek te draaien. Nu een duidelijke melding in het log.
- 227 tests (15 nieuwe voor rollen, 15 voor de scheduler).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 22:04:08 +02:00
Ramon
ae99df2fc7 v0.5.20-beta - complete backups en updates per app
Some checks failed
Deploy server-up (dev) / deploy (push) Failing after 6s
Backups (core/backups.py, core/scheduler.py):
- Terugzetten met een klik: stack stoppen, huidige map opzij, uitpakken,
  starten. Mislukt het uitpakken, dan wordt de oude situatie teruggeplaatst.
- Bewaarbeleid: aantal per stack en/of maximale leeftijd; de nieuwste backup
  van een stack blijft altijd staan.
- Geplande backups (dagelijks/wekelijks) via een eigen planner in de app, geen
  cron. Een gemiste ronde loopt bij de eerstvolgende gelegenheid alsnog.
- Automatisch een backup voor het bijwerken of verwijderen van een stack.
  Mislukt die, dan gaat de actie door - anders kun je een kapotte stack niet
  meer opruimen.
- Uitpakken met tarfile + filter="data": absolute paden en ..-ingangen worden
  geweigerd. Met een kaal `tar xzf` kon een geprepareerd archief buiten de
  stackmap schrijven.
- Twee bugs in de oude implementatie: de returncode van tar werd genegeerd
  (mislukte backup gold als succes) en backups binnen dezelfde seconde
  overschreven elkaar.

Updates per app (core/stackupdates.py, core/registry.py):
- Badge op de stackkaart als er een nieuwer image is; bijwerken doet de
  bestaande update-knop.
- Vergelijking via de Registry API v2 (Docker-Content-Digest) in plaats van
  `docker manifest inspect`: dat laatste geeft per platform een aparte digest
  terwijl RepoDigests de manifest-list-digest bevat, wat bij elk multi-arch
  image permanent "update beschikbaar" zou opleveren.
- Drie statussen: update / current / unknown. Lokaal gebouwd, nog niet gepulld
  of registry onbereikbaar geeft unknown en dus geen badge.
- Dagelijkse achtergrondcheck, resultaten 6 uur gecached.

Verder:
- docs/backups.md, met nadruk op wat er niet in een backup zit: de
  Docker-volumes met de eigenlijke appdata.
- Backup-instellingen onder Instellingen; backup-geschiedenis per stack.
- 197 tests groen (40 nieuwe).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 19:54:51 +02:00
Ramon
8ff5f4b1d3 v0.5.10-beta - update-systeem met kanalen en een-klik bijwerken
Some checks failed
Deploy server-up (dev) / deploy (push) Failing after 4s
- Update-kanalen stable/beta in plaats van het vinkje "pre-releases meenemen".
  Stable ziet alleen releases, beta ook pre-releases; een release telt hoger
  dan zijn eigen beta (0.5.10-beta1 < 0.5.10). UPDATE_INCLUDE_PRERELEASE
  migreert automatisch naar het beta-kanaal.
- Nieuw core/selfupdate.py: image uit de registry ophalen, SU_TAG wegschrijven
  en de eigen container laten hercreeren door een korte helper-container die op
  het nieuwe image draait (bevat de docker- en compose-CLI al). Een container
  kan zichzelf niet hercreeren, vandaar de helper.
- Deploy-map wordt uitgelezen uit de compose-labels van de eigen container.
  Ontbreken die, draait de container niet vanaf een registry-image of is de
  docker-socket er niet, dan meldt de UI waarom bijwerken niet kan.
- Vorige tag wordt onthouden; terugrolknop in de instellingen.
- Update-check een uur gecached, met geforceerde check via de knop; eerder deed
  elke paginalading een netwerkverzoek. Laatst-gecontroleerd zichtbaar.
- Registry-inloggegevens instelbaar; het token komt net als de git-tokens nooit
  terug via de API en leeg laten betekent ongewijzigd.
- docker-compose.yml gebruikt ${SU_IMAGE:-server-up}:${SU_TAG:-latest}; zonder
  SU_IMAGE blijft lokaal bouwen werken zoals voorheen.
- deploy-prod.yml bouwt en pusht het image in dezelfde job wanneer SU_IMAGE
  ingesteld is; build.yml is nu alleen handmatig. Bewust geen aparte
  build-workflow op dezelfde tag: bij een runner met een job tegelijk zou de
  deploy wachten op een build die zelf nog in de wachtrij staat.
- docs/updates.md: werking, complete Forgejo-instelling (registry, tokens,
  variables, secrets, runners), release-procedure voor stable en beta,
  terugrollen en probleemoplossing.
- Tests uitgebreid naar 148 (kanaallogica, cache, image-afleiding incl.
  registry-poortnummers, tag-validatie, .env-schrijven, tokenlek).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 15:13:18 +02:00
Ramon
8b29553a71 v0.5.00-beta - containerbeheer, eigen IP-adressen, veiliger installeren
Some checks failed
Deploy server-up (dev) / deploy (push) Failing after 3s
- Beheer per container: de stackkaart klapt uit naar de losse containers, met
  start/stop/herstart, logs en live CPU-/geheugengebruik per container. De
  containernaam wordt getoetst aan compose_ps van díé stack, zodat de route
  geen willekeurige container op de host kan raken.
- Stacks met een eigen IP-adres (macvlan/ipvlan): netwerkbeheer onder
  Instellingen → Netwerken, netwerkkeuze in de installatiemodal met voorstel
  voor het eerstvolgende vrije adres, en automatische omzetting van het
  gerenderde compose-bestand (poortmappings eruit, ipv4_address erin). De
  templates in apps/ blijven ongewijzigd.
- Toegekende IP's worden vastgehouden in .serverup.json en getoond op de
  stackkaart, zodat een volgende installatie ze niet opnieuw uitdeelt.
- Vrije poort voorstellen bij installeren: next_free_port() bestond al maar
  werd nergens gebruikt. Bezette poorten worden in de UI gemeld.
- Genereerknop voor velden die op een geheim wijzen (token/password/secret),
  lokaal gegenereerd via crypto.getRandomValues.
- Compose valideren met `docker compose config` vóór het wegschrijven, zowel
  bij de editor als na het renderen bij installatie. Ontbreekt de compose-CLI,
  dan blokkeert dat een installatie niet.
- Uitloggen in de zijbalk; gebruikersbeheer en wachtwoord wijzigen onder
  Instellingen → Beveiliging.
- docs/netwerken.md (incl. de shim-interface die de host nodig heeft om zijn
  eigen macvlan-containers te bereiken) en docs/beveiliging.md toegevoegd.
- CHANGELOG bijgewerkt; testsuite uitgebreid naar 112 tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7oLCRYzY5ixJ5Sv8Y8EFb
2026-07-26 14:51:32 +02:00
bes-r
82f68278f6 v0.4.60 - tweecijferig patch-nummer 2026-06-06 22:16:10 +02:00
bes-r
fd9b6ff53d v0.4.6 - kaal versienummer, geen -dev/-rc suffix 2026-06-06 22:12:15 +02:00
bes-r
7dd83f0a88 v0.4.5 - releases + update-check
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 1m2s
Deploy server-up (prod) / deploy (push) Successful in 41s
Release / release (push) Successful in 5s
2026-06-06 22:04:04 +02:00
bes-r
7dfb6a0abb v0.4.4 - versienummer uit centraal VERSION-bestand
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 46s
2026-06-06 21:36:32 +02:00
bes-r
1eab7c07df v0.4.3 - auto-logo's legacy-apps + fix lege Docker Images
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 53s
2026-06-06 21:13:32 +02:00
bes-r
9b388af0cc v0.4.1 - fix: @apply anim brak alle Tailwind-styling
All checks were successful
Deploy server-up (prod) / deploy (push) Successful in 51s
Deploy server-up (dev) / deploy (push) Successful in 4s
2026-06-06 20:53:14 +02:00
bes-r
79ab901d9e v0.4.0 - nieuw UI-ontwerp + SU_VERSION via build-arg/env (fix vdev)
All checks were successful
Deploy server-up (prod) / deploy (push) Successful in 6s
2026-06-06 14:00:15 +02:00
bes-r
34edd95c9b v0.3.1 - UI restyle, inklapbaar menu, taalmodule
Some checks failed
Deploy server-up (prod) / deploy (push) Successful in 6s
Build and push image / build (push) Has been cancelled
2026-06-02 23:25:30 +02:00
bes-r
0b8e3dffb8 v0.3.01 — boilerplate fixes + git-driven versioning
Some checks failed
Deploy server-up / deploy (push) Has been cancelled
2026-05-19 23:44:56 +02:00
bes-r
5580d5ec69 Initial commit: Server Up v0.3.0 2026-05-09 13:55:29 +00:00