diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a812d0..d06719e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +# v0.8.70-beta — De store blijft soepel, en achtentwintig apps erbij + +**Typen in het zoekveld werd traag.** `filteredStore()` is een methode, geen +gecachte getter, en werd per repo drie keer per reactieve tick aangeroepen: in de +`x-show`, in de `x-for` en via de teller in het filtermenu. Elke aanroep liep alle +apps langs met een `toLowerCase()` op naam, map, omschrijving en elke tag — bij +iedere toetsaanslag opnieuw. De catalogus ging deze reeks van 142 naar 286 apps, +en dat begon te merken. + +Het filteren gebeurt nu één keer per filterstand en wordt vastgehouden tot je iets +verandert. Daarnaast staan er nog maar zestig kaarten tegelijk in beeld, met een +knop **Nog N tonen** eronder; die limiet valt terug zodra je het filter of de +zoekterm wijzigt, anders sta je na één zoekactie voor de rest van de sessie naar +alles te kijken. En het zoekveld wacht 200 ms voordat het filtert. + +**Achtentwintig apps** in de hoeken die het dunst waren: + +- **Beveiliging:** 2FAuth (tweestapscodes naast je kluis, niet erin), Passbolt + (wachtwoorden delen in een team), OpenBao, Trivy +- **Ontwikkeling:** Verdaccio, Docker Registry, MkDocs Material +- **AI:** LiteLLM, Flowise, Speaches +- **Spellen:** Pelican Panel, Gameyfin, EmulatorJS +- **3D-printen:** Mainsail en Fluidd — de twee interfaces voor Klipper, waar + OctoPrint niets mee doet +- **Productiviteit:** Kanboard, Wekan, Filestash +- **Documenten:** Linkwarden (bladwijzers mét een gearchiveerde kopie), Slash, + RSSHub +- **Communicatie:** Apprise (één API naar honderd meldingsdiensten), Mailpit + (vangt de mail van je eigen apps op) +- **Verder:** Dashy, Plausible, NetBird, LibreSpeed, PinePods + +Alle 318 images in de catalogus zijn opnieuw tegen hun registry gecontroleerd. + # v0.8.60-beta — Backups bevatten nu je gegevens, en Pangolin hoort erbij **Een backup gaf je niets terug.** `backups.create()` maakte een tar van de diff --git a/README.md b/README.md index b27ce50..673ec35 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ IP-adres in je netwerk geven. | | | |---|---| -| **App-catalogus** | 258 kant-en-klare apps, ingedeeld in categorieën met kleur. Zoeken, filteren en installeren met een formulier in plaats van YAML. | +| **App-catalogus** | 286 kant-en-klare apps, ingedeeld in categorieën met kleur. Zoeken, filteren en installeren met een formulier in plaats van YAML. | | **Stacks beheren** | Starten, stoppen, bijwerken en herstarten — per stack of per losse container, met logs en live CPU-/geheugengebruik. | | **Apps koppelen** | Stacks komen op een gedeeld netwerk, zodat ze elkaar op naam bereiken. Een veld dat naar een andere app verwijst toont een keuzelijst met wat je al draait. | | **Eigen IP per stack** | Met macvlan of ipvlan krijgt een app een eigen adres in je LAN in plaats van poorten op de host. | diff --git a/VERSION b/VERSION index ced6ac6..ac0a1f2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.60-beta +0.8.70-beta diff --git a/apps/2fauth/files/compose.yaml b/apps/2fauth/files/compose.yaml new file mode 100644 index 0000000..51d7756 --- /dev/null +++ b/apps/2fauth/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: 2fauth/2fauth:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - APP_KEY=<< app_key >> + - APP_URL=<< app_url >> + - IS_DEMO_APP=false + - TRUSTED_PROXIES=* + volumes: + - << appdata_dir >>/<< service_name >>:/2fauth + ports: + - "<< port >>:8000" + restart: unless-stopped diff --git a/apps/2fauth/template.json b/apps/2fauth/template.json new file mode 100644 index 0000000..564e654 --- /dev/null +++ b/apps/2fauth/template.json @@ -0,0 +1,88 @@ +{ + "kind": "compose", + "metadata": { + "name": "2FAuth", + "description": "Bewaart je tweestapscodes op je eigen server, zodat je ze niet kwijt bent met je telefoon. Naast Vaultwarden, niet erin — dan liggen wachtwoord en code niet op dezelfde plek.", + "tags": [ + "2fa", + "totp", + "beveiliging" + ], + "icon": { + "provider": "selfhst", + "id": "2fauth" + }, + "version": { + "name": "latest" + }, + "categories": [ + "beveiliging" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "2fauth", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8230, + "required": true, + "description": "Standaard 8000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8230", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "app_key", + "type": "str", + "title": "Applicatiesleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "secret_format": "laravel", + "secret_bytes": 32, + "description": "Laravel-formaat; wordt automatisch in de juiste vorm gemaakt" + } + ] + } + ] +} diff --git a/apps/apprise/files/compose.yaml b/apps/apprise/files/compose.yaml new file mode 100644 index 0000000..77bcab8 --- /dev/null +++ b/apps/apprise/files/compose.yaml @@ -0,0 +1,13 @@ +services: + << service_name >>: + image: caronc/apprise:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - APPRISE_STATEFUL_MODE=simple + - APPRISE_WORKER_COUNT=1 + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:8000" + restart: unless-stopped diff --git a/apps/apprise/template.json b/apps/apprise/template.json new file mode 100644 index 0000000..16c4668 --- /dev/null +++ b/apps/apprise/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Apprise", + "description": "Eén API die je bericht doorstuurt naar honderd diensten: Discord, Telegram, ntfy, e-mail, Signal. Je apps hoeven maar één adres te kennen.", + "tags": [ + "meldingen", + "api", + "notificaties" + ], + "icon": { + "provider": "selfhst", + "id": "apprise" + }, + "version": { + "name": "latest" + }, + "categories": [ + "communicatie" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "apprise", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8251, + "required": true, + "description": "Standaard 8000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/dashy/files/compose.yaml b/apps/dashy/files/compose.yaml new file mode 100644 index 0000000..afa57f7 --- /dev/null +++ b/apps/dashy/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: lissy93/dashy:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/user-data + ports: + - "<< port >>:8080" + restart: unless-stopped diff --git a/apps/dashy/template.json b/apps/dashy/template.json new file mode 100644 index 0000000..fa4913e --- /dev/null +++ b/apps/dashy/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Dashy", + "description": "Startpagina met statuscontrole per dienst, thema's en widgets. Alles staat in één configuratiebestand dat je ook met de hand kunt bijwerken.", + "tags": [ + "dashboard", + "startpagina", + "overzicht" + ], + "icon": { + "provider": "selfhst", + "id": "dashy" + }, + "version": { + "name": "latest" + }, + "categories": [ + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "dashy", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8252, + "required": true, + "description": "Standaard 8080; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/emulatorjs/files/compose.yaml b/apps/emulatorjs/files/compose.yaml new file mode 100644 index 0000000..e53d3f7 --- /dev/null +++ b/apps/emulatorjs/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/emulatorjs:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:80" + - "<< port_admin >>:3000" + restart: unless-stopped diff --git a/apps/emulatorjs/template.json b/apps/emulatorjs/template.json new file mode 100644 index 0000000..4cd8ed6 --- /dev/null +++ b/apps/emulatorjs/template.json @@ -0,0 +1,97 @@ +{ + "kind": "compose", + "metadata": { + "name": "EmulatorJS", + "description": "Speel je retro-spellen in de browser, zonder installatie. Draait alles van NES tot PlayStation. Let op: Zet je roms onder /data/roms met een submap per systeem.", + "tags": [ + "spellen", + "retro", + "emulator" + ], + "icon": { + "provider": "selfhst", + "id": "emulatorjs" + }, + "version": { + "name": "latest" + }, + "categories": [ + "spellen", + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "emulatorjs", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8241, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "port_admin", + "type": "int", + "title": "Beheerinterface", + "default": 8242, + "required": true, + "description": "Hier voeg je spellen toe" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Je bibliotheek, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Gebruiker", + "items": [ + { + "name": "puid", + "type": "int", + "title": "Gebruikers-ID (PUID)", + "default": 1000, + "required": true, + "description": "`id -u` op je server" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/filestash/files/compose.yaml b/apps/filestash/files/compose.yaml new file mode 100644 index 0000000..678e3c9 --- /dev/null +++ b/apps/filestash/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: machines/filestash:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - APPLICATION_URL=<< app_url >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/data/state + ports: + - "<< port >>:8334" + restart: unless-stopped diff --git a/apps/filestash/template.json b/apps/filestash/template.json new file mode 100644 index 0000000..13618bb --- /dev/null +++ b/apps/filestash/template.json @@ -0,0 +1,73 @@ +{ + "kind": "compose", + "metadata": { + "name": "Filestash", + "description": "Webbestandsbeheer over S3, SFTP, FTP, WebDAV en meer, met een voorvertoning per bestandssoort. Eén venster voor opslag die overal staat.", + "tags": [ + "bestanden", + "beheer", + "s3", + "sftp" + ], + "icon": { + "provider": "selfhst", + "id": "filestash" + }, + "version": { + "name": "latest" + }, + "categories": [ + "opslag", + "productiviteit" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "filestash", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8247, + "required": true, + "description": "Standaard 8334; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8247", + "required": true + } + ] + } + ] +} diff --git a/apps/flowise/files/compose.yaml b/apps/flowise/files/compose.yaml new file mode 100644 index 0000000..7065564 --- /dev/null +++ b/apps/flowise/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: flowiseai/flowise:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - FLOWISE_USERNAME=<< admin_user >> + - FLOWISE_PASSWORD=<< admin_password >> + - DATABASE_PATH=/root/.flowise + volumes: + - << appdata_dir >>/<< service_name >>:/root/.flowise + ports: + - "<< port >>:3000" + restart: unless-stopped diff --git a/apps/flowise/template.json b/apps/flowise/template.json new file mode 100644 index 0000000..41b14bf --- /dev/null +++ b/apps/flowise/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "Flowise", + "description": "Bouw workflows met taalmodellen door blokken aan elkaar te klikken, en zet ze weg als API.", + "tags": [ + "ai", + "llm", + "workflows" + ], + "icon": { + "provider": "selfhst", + "id": "flowise" + }, + "version": { + "name": "latest" + }, + "categories": [ + "ai", + "productiviteit" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "flowise", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8237, + "required": true, + "description": "Standaard 3000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "admin_user", + "type": "str", + "title": "Gebruikersnaam", + "default": "admin", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "admin_password", + "type": "str", + "title": "Wachtwoord", + "default": "", + "required": true, + "secret": true, + "eigen_invoer": true + } + ] + } + ] +} diff --git a/apps/fluidd/files/compose.yaml b/apps/fluidd/files/compose.yaml new file mode 100644 index 0000000..56708a0 --- /dev/null +++ b/apps/fluidd/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/fluidd-core/fluidd:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/etc/nginx/conf.d + ports: + - "<< port >>:80" + restart: unless-stopped diff --git a/apps/fluidd/template.json b/apps/fluidd/template.json new file mode 100644 index 0000000..38685ef --- /dev/null +++ b/apps/fluidd/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Fluidd", + "description": "Alternatieve webinterface voor Klipper, met een rustiger scherm dan Mainsail. Welke je prettiger vindt is smaak. Let op: Net als Mainsail praat dit met een Moonraker die op de printer draait; die vul je in de interface in.", + "tags": [ + "3d-printen", + "klipper", + "printerbeheer" + ], + "icon": { + "provider": "selfhst", + "id": "fluidd" + }, + "version": { + "name": "latest" + }, + "categories": [ + "3d-printen" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "fluidd", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8244, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/gameyfin/files/compose.yaml b/apps/gameyfin/files/compose.yaml new file mode 100644 index 0000000..7066f4a --- /dev/null +++ b/apps/gameyfin/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: ghcr.io/gameyfin/gameyfin:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/config + - << data_root >>/media:/data/media:ro + ports: + - "<< port >>:8080" + restart: unless-stopped diff --git a/apps/gameyfin/template.json b/apps/gameyfin/template.json new file mode 100644 index 0000000..748baf2 --- /dev/null +++ b/apps/gameyfin/template.json @@ -0,0 +1,68 @@ +{ + "kind": "compose", + "metadata": { + "name": "Gameyfin", + "description": "Bibliotheek voor je spellencollectie: scant je mappen, haalt omslagen en beschrijvingen op, en laat huisgenoten downloaden.", + "tags": [ + "spellen", + "bibliotheek" + ], + "icon": { + "provider": "selfhst", + "id": "gameyfin" + }, + "version": { + "name": "latest" + }, + "categories": [ + "spellen", + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "gameyfin", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8240, + "required": true, + "description": "Standaard 8080; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Je bibliotheek, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/kanboard/files/compose.yaml b/apps/kanboard/files/compose.yaml new file mode 100644 index 0000000..1776243 --- /dev/null +++ b/apps/kanboard/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: kanboard/kanboard:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/var/www/app/data + - << appdata_dir >>/<< service_name >>-plugins:/var/www/app/plugins + ports: + - "<< port >>:80" + restart: unless-stopped diff --git a/apps/kanboard/template.json b/apps/kanboard/template.json new file mode 100644 index 0000000..4cf0616 --- /dev/null +++ b/apps/kanboard/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Kanboard", + "description": "Kanbanbord dat doet wat het zegt en verder niets. Draait op een handvol megabytes en heeft geen database nodig.", + "tags": [ + "kanban", + "taken", + "projecten" + ], + "icon": { + "provider": "selfhst", + "id": "kanboard" + }, + "version": { + "name": "latest" + }, + "categories": [ + "productiviteit" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "kanboard", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8245, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/librespeed/files/compose.yaml b/apps/librespeed/files/compose.yaml new file mode 100644 index 0000000..ada6d1a --- /dev/null +++ b/apps/librespeed/files/compose.yaml @@ -0,0 +1,13 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/librespeed:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:80" + restart: unless-stopped diff --git a/apps/librespeed/template.json b/apps/librespeed/template.json new file mode 100644 index 0000000..b71d485 --- /dev/null +++ b/apps/librespeed/template.json @@ -0,0 +1,80 @@ +{ + "kind": "compose", + "metadata": { + "name": "LibreSpeed", + "description": "Snelheidstest op je eigen server, zodat je meet hoe snel je netwerk is in plaats van hoe snel de dichtstbijzijnde meetserver is.", + "tags": [ + "snelheid", + "netwerk", + "meten" + ], + "icon": { + "provider": "selfhst", + "id": "librespeed" + }, + "version": { + "name": "latest" + }, + "categories": [ + "netwerk", + "monitoring" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "librespeed", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8255, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Gebruiker", + "items": [ + { + "name": "puid", + "type": "int", + "title": "Gebruikers-ID (PUID)", + "default": 1000, + "required": true, + "description": "`id -u` op je server" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/linkwarden/files/compose.yaml b/apps/linkwarden/files/compose.yaml new file mode 100644 index 0000000..00f6eb9 --- /dev/null +++ b/apps/linkwarden/files/compose.yaml @@ -0,0 +1,26 @@ +services: + << service_name >>: + image: ghcr.io/linkwarden/linkwarden:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - NEXTAUTH_URL=<< app_url >>/api/v1/auth + - NEXTAUTH_SECRET=<< nextauth_secret >> + - DATABASE_URL=postgresql://linkwarden:<< db_password >>@<< service_name >>-db:5432/linkwarden + volumes: + - << appdata_dir >>/<< service_name >>:/data/data + ports: + - "<< port >>:3000" + depends_on: + - << service_name >>-db + restart: unless-stopped + << service_name >>-db: + image: postgres:16-alpine + container_name: << service_name >>-db + environment: + - POSTGRES_DB=linkwarden + - POSTGRES_USER=linkwarden + - POSTGRES_PASSWORD=<< db_password >> + volumes: + - << appdata_dir >>/<< service_name >>-db:/var/lib/postgresql/data + restart: unless-stopped diff --git a/apps/linkwarden/template.json b/apps/linkwarden/template.json new file mode 100644 index 0000000..66ae529 --- /dev/null +++ b/apps/linkwarden/template.json @@ -0,0 +1,95 @@ +{ + "kind": "compose", + "metadata": { + "name": "Linkwarden", + "description": "Bladwijzers mét een gearchiveerde kopie van de pagina, als schermafdruk en als pdf. Wat je bewaart blijft leesbaar, ook als de site verdwijnt.", + "tags": [ + "bladwijzers", + "archief", + "lezen" + ], + "icon": { + "provider": "selfhst", + "id": "linkwarden" + }, + "version": { + "name": "latest" + }, + "categories": [ + "documenten" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "linkwarden", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8248, + "required": true, + "description": "Standaard 3000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8248", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Wordt automatisch ingevuld en in .env bewaard" + }, + { + "name": "nextauth_secret", + "type": "str", + "title": "Sleutel voor de inlogsessies", + "default": "", + "required": true, + "secret": true, + "generate": "auto" + } + ] + } + ] +} diff --git a/apps/litellm/files/compose.yaml b/apps/litellm/files/compose.yaml new file mode 100644 index 0000000..5101666 --- /dev/null +++ b/apps/litellm/files/compose.yaml @@ -0,0 +1,23 @@ +services: + << service_name >>: + image: ghcr.io/berriai/litellm:main-latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - LITELLM_MASTER_KEY=<< master_key >> + - DATABASE_URL=postgresql://litellm:<< db_password >>@<< service_name >>-db:5432/litellm + ports: + - "<< port >>:4000" + depends_on: + - << service_name >>-db + restart: unless-stopped + << service_name >>-db: + image: postgres:16-alpine + container_name: << service_name >>-db + environment: + - POSTGRES_DB=litellm + - POSTGRES_USER=litellm + - POSTGRES_PASSWORD=<< db_password >> + volumes: + - << appdata_dir >>/<< service_name >>-db:/var/lib/postgresql/data + restart: unless-stopped diff --git a/apps/litellm/template.json b/apps/litellm/template.json new file mode 100644 index 0000000..0a601d2 --- /dev/null +++ b/apps/litellm/template.json @@ -0,0 +1,85 @@ +{ + "kind": "compose", + "metadata": { + "name": "LiteLLM", + "description": "Eén API voor OpenAI, Anthropic, Gemini en je eigen Ollama, met een sleutel en een verbruikslimiet per gebruiker.", + "tags": [ + "ai", + "llm", + "api", + "proxy" + ], + "icon": { + "provider": "selfhst", + "id": "litellm" + }, + "version": { + "name": "latest" + }, + "categories": [ + "ai" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "litellm", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8236, + "required": true, + "description": "Standaard 4000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Wordt automatisch ingevuld en in .env bewaard" + }, + { + "name": "master_key", + "type": "str", + "title": "Hoofdsleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Waarmee je de andere sleutels beheert" + } + ] + } + ] +} diff --git a/apps/mailpit/files/compose.yaml b/apps/mailpit/files/compose.yaml new file mode 100644 index 0000000..e5f84ea --- /dev/null +++ b/apps/mailpit/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: axllent/mailpit:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - MP_MAX_MESSAGES=5000 + - MP_DATABASE=/data/mailpit.db + volumes: + - << appdata_dir >>/<< service_name >>:/data + ports: + - "<< port >>:8025" + - "<< port_smtp >>:1025" + restart: unless-stopped diff --git a/apps/mailpit/template.json b/apps/mailpit/template.json new file mode 100644 index 0000000..de384eb --- /dev/null +++ b/apps/mailpit/template.json @@ -0,0 +1,67 @@ +{ + "kind": "compose", + "metadata": { + "name": "Mailpit", + "description": "Vangt de e-mail van je eigen applicaties op zodat je hem kunt bekijken zonder dat er iets de deur uit gaat. Onmisbaar bij het testen van een app die mail stuurt.", + "tags": [ + "e-mail", + "testen", + "ontwikkeling" + ], + "icon": { + "provider": "selfhst", + "id": "mailpit" + }, + "version": { + "name": "latest" + }, + "categories": [ + "communicatie", + "ontwikkeling" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "mailpit", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8025, + "required": true + }, + { + "name": "port_smtp", + "type": "int", + "title": "SMTP-poort", + "default": 1025, + "required": true, + "description": "Hier laat je je applicatie naartoe sturen" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/mainsail/files/compose.yaml b/apps/mainsail/files/compose.yaml new file mode 100644 index 0000000..5fdd215 --- /dev/null +++ b/apps/mainsail/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/mainsail-crew/mainsail:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/usr/share/nginx/html/config + ports: + - "<< port >>:80" + restart: unless-stopped diff --git a/apps/mainsail/template.json b/apps/mainsail/template.json new file mode 100644 index 0000000..78710d4 --- /dev/null +++ b/apps/mainsail/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Mainsail", + "description": "Webinterface voor Klipper: bedienen, sliceren en de temperatuurgrafieken volgen. Waar OctoPrint stopt bij Marlin, begint dit bij Klipper. Let op: Klipper en Moonraker draaien op de printer zelf, niet in deze container. Vul in de interface het adres van je Moonraker in.", + "tags": [ + "3d-printen", + "klipper", + "printerbeheer" + ], + "icon": { + "provider": "selfhst", + "id": "mainsail" + }, + "version": { + "name": "latest" + }, + "categories": [ + "3d-printen" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "mainsail", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8243, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/mkdocs-material/files/compose.yaml b/apps/mkdocs-material/files/compose.yaml new file mode 100644 index 0000000..adbd7dc --- /dev/null +++ b/apps/mkdocs-material/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: squidfunk/mkdocs-material:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/docs + command: serve --dev-addr=0.0.0.0:8000 + ports: + - "<< port >>:8000" + restart: unless-stopped diff --git a/apps/mkdocs-material/template.json b/apps/mkdocs-material/template.json new file mode 100644 index 0000000..007fa0f --- /dev/null +++ b/apps/mkdocs-material/template.json @@ -0,0 +1,60 @@ +{ + "kind": "compose", + "metadata": { + "name": "MkDocs Material", + "description": "Zet een map met markdown om in een doorzoekbare documentatiesite, en ververst live terwijl je schrijft. Let op: Zet je markdown en je mkdocs.yml in de appdata-map; die wordt als /docs gekoppeld.", + "tags": [ + "documentatie", + "markdown", + "ontwikkeling" + ], + "icon": { + "provider": "selfhst", + "id": "mkdocs" + }, + "version": { + "name": "latest" + }, + "categories": [ + "ontwikkeling", + "documenten" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "mkdocsmaterial", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8235, + "required": true, + "description": "Standaard 8000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/netbird/files/compose.yaml b/apps/netbird/files/compose.yaml new file mode 100644 index 0000000..24d37ca --- /dev/null +++ b/apps/netbird/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: netbirdio/dashboard:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - NETBIRD_MGMT_API_ENDPOINT=<< mgmt_url >> + - AUTH_AUTHORITY=<< auth_authority >> + - AUTH_CLIENT_ID=<< auth_client_id >> + - AUTH_SUPPORTED_SCOPES=openid profile email + - AUTH_AUDIENCE=<< auth_client_id >> + ports: + - "<< port >>:80" + restart: unless-stopped diff --git a/apps/netbird/template.json b/apps/netbird/template.json new file mode 100644 index 0000000..2a3a593 --- /dev/null +++ b/apps/netbird/template.json @@ -0,0 +1,85 @@ +{ + "kind": "compose", + "metadata": { + "name": "NetBird", + "description": "Beheerpaneel voor een mesh-VPN op WireGuard: je apparaten praten rechtstreeks met elkaar, waar ze ook staan. Let op: Dit is alleen het dashboard. De management-server, signal en een TURN-server draai je ernaast; zie de documentatie van NetBird.", + "tags": [ + "vpn", + "wireguard", + "mesh", + "netwerk" + ], + "icon": { + "provider": "selfhst", + "id": "netbird" + }, + "version": { + "name": "latest" + }, + "categories": [ + "netwerk", + "beveiliging" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "netbird", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8254, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "mgmt_url", + "type": "str", + "title": "Adres van de management-server", + "default": "https://netbird.example.com:33073", + "required": true + }, + { + "name": "auth_authority", + "type": "str", + "title": "OIDC-uitgever", + "default": "https://id.example.com", + "required": true, + "connect": { + "app": "authentik", + "scheme": "https", + "port": 443 + }, + "help": "NetBird logt in via een externe dienst; wijs dit naar je Authentik, Keycloak of Pocket ID." + }, + { + "name": "auth_client_id", + "type": "str", + "title": "OIDC client-id", + "default": "", + "required": true + } + ] + } + ] +} diff --git a/apps/openbao/files/compose.yaml b/apps/openbao/files/compose.yaml new file mode 100644 index 0000000..0d92fe9 --- /dev/null +++ b/apps/openbao/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: ghcr.io/openbao/openbao:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - BAO_DEV_ROOT_TOKEN_ID=<< root_token >> + volumes: + - << appdata_dir >>/<< service_name >>:/openbao/file + command: server -dev -dev-listen-address=0.0.0.0:8200 + ports: + - "<< port >>:8200" + cap_add: + - IPC_LOCK + restart: unless-stopped diff --git a/apps/openbao/template.json b/apps/openbao/template.json new file mode 100644 index 0000000..837795e --- /dev/null +++ b/apps/openbao/template.json @@ -0,0 +1,75 @@ +{ + "kind": "compose", + "metadata": { + "name": "OpenBao", + "description": "Bewaart geheimen voor machines: certificaten, API-sleutels en databasewachtwoorden, met een houdbaarheidsdatum per stuk. De opvolger van HashiCorp Vault. Let op: Draait hier in ontwikkelmodus: alles staat in het geheugen en is weg na een herstart. Voor echt gebruik zet je in het configuratiebestand een opslagbackend en zegel je hem met echte sleutels.", + "tags": [ + "geheimen", + "certificaten", + "beveiliging" + ], + "icon": { + "provider": "selfhst", + "id": "openbao" + }, + "version": { + "name": "latest" + }, + "categories": [ + "beveiliging", + "ontwikkeling" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "openbao", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8232, + "required": true, + "description": "Standaard 8200; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "root_token", + "type": "str", + "title": "Root-token", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Waarmee je de eerste keer inlogt" + } + ] + } + ] +} diff --git a/apps/passbolt/files/compose.yaml b/apps/passbolt/files/compose.yaml new file mode 100644 index 0000000..c662790 --- /dev/null +++ b/apps/passbolt/files/compose.yaml @@ -0,0 +1,30 @@ +services: + << service_name >>: + image: passbolt/passbolt:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - APP_FULL_BASE_URL=<< app_url >> + - DATASOURCES_DEFAULT_HOST=<< service_name >>-db + - DATASOURCES_DEFAULT_USERNAME=passbolt + - DATASOURCES_DEFAULT_PASSWORD=<< db_password >> + - DATASOURCES_DEFAULT_DATABASE=passbolt + volumes: + - << appdata_dir >>/<< service_name >>:/etc/passbolt/jwt + - << appdata_dir >>/<< service_name >>-gpg:/etc/passbolt/gpg + ports: + - "<< port >>:80" + depends_on: + - << service_name >>-db + restart: unless-stopped + << service_name >>-db: + image: mariadb:11 + container_name: << service_name >>-db + environment: + - MARIADB_DATABASE=passbolt + - MARIADB_USER=passbolt + - MARIADB_PASSWORD=<< db_password >> + - MARIADB_ROOT_PASSWORD=<< db_password >> + volumes: + - << appdata_dir >>/<< service_name >>-db:/var/lib/mysql + restart: unless-stopped diff --git a/apps/passbolt/template.json b/apps/passbolt/template.json new file mode 100644 index 0000000..1fe179f --- /dev/null +++ b/apps/passbolt/template.json @@ -0,0 +1,88 @@ +{ + "kind": "compose", + "metadata": { + "name": "Passbolt", + "description": "Wachtwoorden delen binnen een team, met rechten per map en een controlespoor. Vaultwarden is voor jezelf, dit voor een groep. Let op: Na de eerste start maak je de beheerder aan met `docker exec passbolt su -m -c \"/usr/share/php/passbolt/bin/cake passbolt register_user -u jij@example.com -r admin\" -s /bin/sh www-data`.", + "tags": [ + "wachtwoorden", + "team", + "beveiliging" + ], + "icon": { + "provider": "selfhst", + "id": "passbolt" + }, + "version": { + "name": "latest" + }, + "categories": [ + "beveiliging", + "zakelijk" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "passbolt", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8231, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "https://passbolt.example.com", + "required": true, + "description": "Ligt vast na de eerste start: het zit in de uitnodigingen" + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Wordt automatisch ingevuld en in .env bewaard" + } + ] + } + ] +} diff --git a/apps/pelican/files/compose.yaml b/apps/pelican/files/compose.yaml new file mode 100644 index 0000000..af77af7 --- /dev/null +++ b/apps/pelican/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: ghcr.io/pelican-dev/panel:latest + container_name: << service_name >> + environment: + - APP_URL=<< app_url >> + - APP_TIMEZONE=<< timezone >> + - APP_ENV=production + - APP_KEY=<< app_key >> + volumes: + - << appdata_dir >>/<< service_name >>:/pelican-data + ports: + - "<< port >>:80" + restart: unless-stopped diff --git a/apps/pelican/template.json b/apps/pelican/template.json new file mode 100644 index 0000000..4db397c --- /dev/null +++ b/apps/pelican/template.json @@ -0,0 +1,89 @@ +{ + "kind": "compose", + "metadata": { + "name": "Pelican Panel", + "description": "Beheerpaneel voor gameservers: meerdere spellen naast elkaar, met rechten per gebruiker en een console per server. De opvolger van Pterodactyl. Let op: Het paneel beheert de servers; de spellen zelf draaien op een of meer Wings-daemons die je apart installeert.", + "tags": [ + "spellen", + "gameserver", + "beheer" + ], + "icon": { + "provider": "selfhst", + "id": "pelican" + }, + "version": { + "name": "latest" + }, + "categories": [ + "spellen", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "pelican", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8239, + "required": true, + "description": "Standaard 80; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8239", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "app_key", + "type": "str", + "title": "Applicatiesleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "secret_format": "laravel", + "secret_bytes": 32, + "description": "Laravel-formaat; wordt automatisch in de juiste vorm gemaakt" + } + ] + } + ] +} diff --git a/apps/pinepods/files/compose.yaml b/apps/pinepods/files/compose.yaml new file mode 100644 index 0000000..f64116c --- /dev/null +++ b/apps/pinepods/files/compose.yaml @@ -0,0 +1,31 @@ +services: + << service_name >>: + image: madeofpendletonwool/pinepods:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - SEARCH_API_URL=https://search.pinepods.online/api/search + - DB_TYPE=postgresql + - DB_HOST=<< service_name >>-db + - DB_PORT=5432 + - DB_USER=pinepods + - DB_NAME=pinepods + - DB_PASSWORD=<< db_password >> + - HOSTNAME=<< app_url >> + volumes: + - << appdata_dir >>/<< service_name >>:/opt/pinepods/backend/data + ports: + - "<< port >>:8040" + depends_on: + - << service_name >>-db + restart: unless-stopped + << service_name >>-db: + image: postgres:16-alpine + container_name: << service_name >>-db + environment: + - POSTGRES_DB=pinepods + - POSTGRES_USER=pinepods + - POSTGRES_PASSWORD=<< db_password >> + volumes: + - << appdata_dir >>/<< service_name >>-db:/var/lib/postgresql/data + restart: unless-stopped diff --git a/apps/pinepods/template.json b/apps/pinepods/template.json new file mode 100644 index 0000000..1a1d827 --- /dev/null +++ b/apps/pinepods/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "PinePods", + "description": "Podcasts beheren en afspelen op je eigen server, met je afspeelpositie gedeeld tussen apparaten.", + "tags": [ + "podcasts", + "audio", + "media" + ], + "icon": { + "provider": "selfhst", + "id": "pinepods" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "pinepods", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8256, + "required": true, + "description": "Standaard 8040; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8256", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Wordt automatisch ingevuld en in .env bewaard" + } + ] + } + ] +} diff --git a/apps/plausible/files/compose.yaml b/apps/plausible/files/compose.yaml new file mode 100644 index 0000000..71e8b22 --- /dev/null +++ b/apps/plausible/files/compose.yaml @@ -0,0 +1,40 @@ +services: + << service_name >>: + image: ghcr.io/plausible/community-edition:v3 + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - BASE_URL=<< app_url >> + - SECRET_KEY_BASE=<< secret_key_base >> + - TOTP_VAULT_KEY=<< totp_vault_key >> + - DATABASE_URL=postgres://plausible:<< db_password >>@<< service_name >>-db:5432/plausible + - CLICKHOUSE_DATABASE_URL=http://<< service_name >>-clickhouse:8123/plausible_events + command: sh -c "/entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run" + ports: + - "<< port >>:8000" + depends_on: + - << service_name >>-db + - << service_name >>-clickhouse + restart: unless-stopped + << service_name >>-db: + image: postgres:16-alpine + container_name: << service_name >>-db + environment: + - POSTGRES_DB=plausible + - POSTGRES_USER=plausible + - POSTGRES_PASSWORD=<< db_password >> + volumes: + - << appdata_dir >>/<< service_name >>-db:/var/lib/postgresql/data + restart: unless-stopped + << service_name >>-clickhouse: + image: clickhouse/clickhouse-server:24.12-alpine + container_name: << service_name >>-clickhouse + environment: + - CLICKHOUSE_SKIP_USER_SETUP=1 + volumes: + - << appdata_dir >>/<< service_name >>-clickhouse:/var/lib/clickhouse + ulimits: + nofile: + soft: 262144 + hard: 262144 + restart: unless-stopped diff --git a/apps/plausible/template.json b/apps/plausible/template.json new file mode 100644 index 0000000..00fe78c --- /dev/null +++ b/apps/plausible/template.json @@ -0,0 +1,106 @@ +{ + "kind": "compose", + "metadata": { + "name": "Plausible", + "description": "Bezoekersstatistieken zonder cookies, met een script van minder dan een kilobyte. Uitgebreider dan Umami, met doelen en trechters. Let op: Clickhouse vraagt om geheugen; reken op 2 GB voor deze stack.", + "tags": [ + "analytics", + "bezoekers", + "privacy" + ], + "icon": { + "provider": "selfhst", + "id": "plausible" + }, + "version": { + "name": "latest" + }, + "categories": [ + "analytics" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "plausible", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8253, + "required": true, + "description": "Standaard 8000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8253", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Wordt automatisch ingevuld en in .env bewaard" + }, + { + "name": "secret_key_base", + "type": "str", + "title": "Sleutel voor de sessies", + "default": "", + "required": true, + "secret": true, + "generate": "auto" + }, + { + "name": "totp_vault_key", + "type": "str", + "title": "Sleutel voor tweestapsverificatie", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "secret_format": "hex", + "secret_bytes": 32 + } + ] + } + ] +} diff --git a/apps/registry/files/compose.yaml b/apps/registry/files/compose.yaml new file mode 100644 index 0000000..a5dddf2 --- /dev/null +++ b/apps/registry/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: registry:2 + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - REGISTRY_STORAGE_DELETE_ENABLED=true + volumes: + - << appdata_dir >>/<< service_name >>:/var/lib/registry + ports: + - "<< port >>:5000" + restart: unless-stopped diff --git a/apps/registry/template.json b/apps/registry/template.json new file mode 100644 index 0000000..5b15c49 --- /dev/null +++ b/apps/registry/template.json @@ -0,0 +1,60 @@ +{ + "kind": "compose", + "metadata": { + "name": "Docker Registry", + "description": "Eigen registry voor je images, zodat je ze niet bij Docker Hub hoeft neer te zetten en je server ze lokaal ophaalt. Let op: Zonder reverse proxy met TLS ervoor weigert Docker ernaartoe te pushen, tenzij je hem als insecure-registry opgeeft.", + "tags": [ + "docker", + "registry", + "images" + ], + "icon": { + "provider": "selfhst", + "id": "docker" + }, + "version": { + "name": "latest" + }, + "categories": [ + "ontwikkeling", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "registry", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Registrypoort", + "default": 8234, + "required": true, + "description": "Standaard 5000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/rsshub/files/compose.yaml b/apps/rsshub/files/compose.yaml new file mode 100644 index 0000000..321b1f2 --- /dev/null +++ b/apps/rsshub/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: diygod/rsshub:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - NODE_ENV=production + - CACHE_TYPE=memory + ports: + - "<< port >>:1200" + restart: unless-stopped diff --git a/apps/rsshub/template.json b/apps/rsshub/template.json new file mode 100644 index 0000000..9ffd77a --- /dev/null +++ b/apps/rsshub/template.json @@ -0,0 +1,51 @@ +{ + "kind": "compose", + "metadata": { + "name": "RSSHub", + "description": "Maakt een feed van sites die er geen aanbieden. Meer dan duizend bronnen worden ondersteund; koppel het aan FreshRSS of Miniflux.", + "tags": [ + "rss", + "feeds", + "nieuws" + ], + "icon": { + "provider": "selfhst", + "id": "rsshub" + }, + "version": { + "name": "latest" + }, + "categories": [ + "documenten" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "rsshub", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8250, + "required": true, + "description": "Standaard 1200; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/slash/files/compose.yaml b/apps/slash/files/compose.yaml new file mode 100644 index 0000000..bd4b6d1 --- /dev/null +++ b/apps/slash/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: yourselfhosted/slash:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/var/opt/slash + ports: + - "<< port >>:5231" + restart: unless-stopped diff --git a/apps/slash/template.json b/apps/slash/template.json new file mode 100644 index 0000000..49cc040 --- /dev/null +++ b/apps/slash/template.json @@ -0,0 +1,60 @@ +{ + "kind": "compose", + "metadata": { + "name": "Slash", + "description": "Korte links met een eigen naam, en een startpagina waarop ze allemaal staan. Handig voor adressen die je vaak deelt.", + "tags": [ + "links", + "startpagina", + "bladwijzers" + ], + "icon": { + "provider": "selfhst", + "id": "slash" + }, + "version": { + "name": "latest" + }, + "categories": [ + "documenten", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "slash", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8249, + "required": true, + "description": "Standaard 5231; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/speaches/files/compose.yaml b/apps/speaches/files/compose.yaml new file mode 100644 index 0000000..1bb8664 --- /dev/null +++ b/apps/speaches/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/speaches-ai/speaches:latest-cpu + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/home/ubuntu/.cache/huggingface + ports: + - "<< port >>:8000" + restart: unless-stopped diff --git a/apps/speaches/template.json b/apps/speaches/template.json new file mode 100644 index 0000000..ac8d4e0 --- /dev/null +++ b/apps/speaches/template.json @@ -0,0 +1,61 @@ +{ + "kind": "compose", + "metadata": { + "name": "Speaches", + "description": "Spraak naar tekst en terug, achter dezelfde API als OpenAI gebruikt. Home Assistant en bestaande tools sluiten er zo op aan. Let op: Deze variant rekent op de processor. Met een videokaart erbij gaat het een orde van grootte sneller.", + "tags": [ + "ai", + "spraak", + "transcriptie", + "api" + ], + "icon": { + "provider": "selfhst", + "id": "speaches" + }, + "version": { + "name": "latest" + }, + "categories": [ + "ai", + "domotica" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "speaches", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8238, + "required": true, + "description": "Standaard 8000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/trivy/files/compose.yaml b/apps/trivy/files/compose.yaml new file mode 100644 index 0000000..f84b2b2 --- /dev/null +++ b/apps/trivy/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: aquasec/trivy:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/root/.cache/trivy + command: server --listen 0.0.0.0:4954 + ports: + - "<< port >>:4954" + restart: unless-stopped diff --git a/apps/trivy/template.json b/apps/trivy/template.json new file mode 100644 index 0000000..1ba1d04 --- /dev/null +++ b/apps/trivy/template.json @@ -0,0 +1,60 @@ +{ + "kind": "compose", + "metadata": { + "name": "Trivy", + "description": "Scant je images op bekende kwetsbaarheden en verlopen pakketten. Draait als server zodat je hem vanaf je CI kunt aanroepen.", + "tags": [ + "beveiliging", + "scanner", + "containers" + ], + "icon": { + "provider": "selfhst", + "id": "trivy" + }, + "version": { + "name": "latest" + }, + "categories": [ + "beveiliging", + "ontwikkeling" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "trivy", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Serverpoort", + "default": 8233, + "required": true, + "description": "Standaard 4954; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/verdaccio/files/compose.yaml b/apps/verdaccio/files/compose.yaml new file mode 100644 index 0000000..c1546d8 --- /dev/null +++ b/apps/verdaccio/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: verdaccio/verdaccio:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/verdaccio/storage + ports: + - "<< port >>:4873" + restart: unless-stopped diff --git a/apps/verdaccio/template.json b/apps/verdaccio/template.json new file mode 100644 index 0000000..bb214bd --- /dev/null +++ b/apps/verdaccio/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "Verdaccio", + "description": "Eigen npm-registry die pakketten van npmjs doorgeeft en cachet, en waar je je eigen pakketten naast kunt zetten.", + "tags": [ + "npm", + "registry", + "ontwikkeling" + ], + "icon": { + "provider": "selfhst", + "id": "verdaccio" + }, + "version": { + "name": "latest" + }, + "categories": [ + "ontwikkeling" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "verdaccio", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 4873, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/wekan/files/compose.yaml b/apps/wekan/files/compose.yaml new file mode 100644 index 0000000..3637bdb --- /dev/null +++ b/apps/wekan/files/compose.yaml @@ -0,0 +1,24 @@ +services: + << service_name >>: + image: ghcr.io/wekan/wekan:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - ROOT_URL=<< app_url >> + - PORT=8080 + - MONGO_URL=mongodb://app:<< db_password >>@<< service_name >>-db:27017/wekan?authSource=admin + - WITH_API=true + ports: + - "<< port >>:8080" + depends_on: + - << service_name >>-db + restart: unless-stopped + << service_name >>-db: + image: mongo:8 + container_name: << service_name >>-db + environment: + - MONGO_INITDB_ROOT_USERNAME=app + - MONGO_INITDB_ROOT_PASSWORD=<< db_password >> + volumes: + - << appdata_dir >>/<< service_name >>-db:/data/db + restart: unless-stopped diff --git a/apps/wekan/template.json b/apps/wekan/template.json new file mode 100644 index 0000000..1efe882 --- /dev/null +++ b/apps/wekan/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "Wekan", + "description": "Kanbanbord met swimlanes, checklists en tijdregistratie. Uitgebreider dan Kanboard, met een eigen database.", + "tags": [ + "kanban", + "taken", + "projecten" + ], + "icon": { + "provider": "selfhst", + "id": "wekan" + }, + "version": { + "name": "latest" + }, + "categories": [ + "productiviteit" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "wekan", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8246, + "required": true, + "description": "Standaard 8080; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de gegevens van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Instellingen", + "items": [ + { + "name": "app_url", + "type": "str", + "title": "Publiek adres", + "default": "http://localhost:8246", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Wordt automatisch ingevuld en in .env bewaard" + } + ] + } + ] +} diff --git a/server-up/templates/index.html b/server-up/templates/index.html index 06a9c32..a48d859 100644 --- a/server-up/templates/index.html +++ b/server-up/templates/index.html @@ -490,7 +490,8 @@ tailwind.config = {
- + @@ -618,7 +619,7 @@ tailwind.config = {
-