diff --git a/CHANGELOG.md b/CHANGELOG.md index 9beecff..b4b6b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,59 @@ +# v0.7.90-beta — De ARR-stack uit elkaar, en netwerkopties per container + +**Elk *arr-onderdeel is nu een losse app.** Wie alleen Sonarr wil, hoefde eerst +de hele ARR-stack te nemen. Er staan nu zesenveertig losse sjablonen in de store +— Sonarr, Radarr, Prowlarr, Bazarr, Gluetun, en alles daaromheen — en de +gecombineerde stack blijft bestaan als "alles in één keer". Het zijn dezelfde +containers: beide verpakkingen komen uit één bron (`tools/arr_sjablonen.py`) en +een test draait die opnieuw en vergelijkt het resultaat, zodat ze niet stilletjes +uit elkaar groeien. Die test vond meteen zijn eerste geval: los koppelde +qBittorrent zijn interne poort aan de hostpoort die jij koos, wat niet meer klopt +zodra hij achter een VPN zit. + +**Hardlinks werkten niet, en dat was niet zichtbaar.** Elke app kreeg losse +mounts — `/tv`, `/movies`, `/downloads`. Voor Sonarr zijn dat twee verschillende +bestandssystemen, ook al staat alles op dezelfde schijf, dus werd élke voltooide +download naar je bibliotheek *gekopieerd* in plaats van gelinkt: traag, tijdelijk +alles dubbel, en je torrent stopte met seeden zodra je opruimde. De beschrijving +waarschuwde wel voor "zet ze op hetzelfde bestandssysteem", maar de mounts maakten +het alsnog onmogelijk. Alles deelt nu één map die als `/data` binnenkomt, met +`UMASK=002` zodat de apps bij elkaars bestanden kunnen. + +**Negentien lege kaarten.** De schakelaar van een onderdeel stond hard in de stap +*Instellingen*, terwijl je hem ook in de kop van zijn eigen groep in *Basis* zag +staan: elk onderdeel had twee schakelaars in twee schermen, en *Instellingen* +bestond voor het grootste deel uit kaarten zonder inhoud. Er is nu een eerste +stap **Onderdelen** waar alle schakelaars bij elkaar staan, gegroepeerd per soort +— bij negenenveertig onderdelen scheelt dat nogal. Wat je uitzet verdwijnt uit de +volgende stappen in plaats van als lege kaart te blijven staan. + +**Een eigen IP-adres ging per stack, niet per container.** Bij een app met één +container klopt dat. Bij een stack met twintig webinterfaces kreeg de eerste +container het adres en raakten **alle andere hun poortmappings kwijt** zonder er +iets voor terug te krijgen — daarna waren ze nergens meer te bereiken. Je wijst +nu per container een adres toe; wie er geen krijgt, houdt gewoon zijn poort. +Hetzelfde gold voor Pangolin, dat één URL per stack maakte op de eerste poort die +het tegenkwam: dat gaat nu ook per container. + +**Huntarr is eruit.** Het project werd in februari 2026 offline gehaald nadat er +onder meer authenticatie-bypasses en API-sleutels in platte tekst waren gevonden; +de auteur heeft de repo verwijderd. Het image dat in het sjabloon stond bestaat +niet meer — een controle langs alle registries bevestigde dat. Vervangen door +NeutArr, de fork van de laatste schone versie. In diezelfde ronde bleek +Maintainerr verhuisd naar een andere organisatie. + +**Nieuw in de catalogus:** Overseerr, Cleanuparr, Decluttarr, Janitorr, +cross-seed, Configarr, Profilarr, Byparr, Kometa, Tautulli, Jellystat, Wizarr, +SuggestArr, Trailarr, Lingarr, NZBHydra2, Deluge, Transmission, slskd, Soularr, +Mylar3, Kapowarr, Pulsarr, Prefetcharr, Posterizarr, Notifiarr, Exportarr, +Autopulse, Requestrr, Homarr en NeutArr. Alle images zijn tegen hun registry +gecontroleerd. + +**Twee mappen die allebei "data" heetten.** `data_dir` was de map waar een app +zijn eigen spullen bewaart; daar kwam nu een gedeelde `/data` naast. Die heten nu +`appdata_dir` en `data_root`, in alle sjablonen. En qBittorrent stond standaard op +poort 8080, samen met zes andere apps; die staat nu op 8097. + # v0.7.80-beta — De knop Volgende, tijdzones, en netwerken per groepje **De knop Volgende deed niets.** Alpine haalt een boolean-attribuut alleen weg diff --git a/VERSION b/VERSION index f0facb8..8d57ee5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.7.80-beta +0.7.90-beta diff --git a/apps/actual-budget/files/compose.yaml b/apps/actual-budget/files/compose.yaml index c4f441d..4d69884 100644 --- a/apps/actual-budget/files/compose.yaml +++ b/apps/actual-budget/files/compose.yaml @@ -5,5 +5,5 @@ services: ports: - "<< port >>:5006" volumes: - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data restart: unless-stopped diff --git a/apps/actual-budget/template.json b/apps/actual-budget/template.json index 2a7e0f6..9408144 100644 --- a/apps/actual-budget/template.json +++ b/apps/actual-budget/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/adguard-home/files/compose.yaml b/apps/adguard-home/files/compose.yaml index 62d06db..bfaa931 100644 --- a/apps/adguard-home/files/compose.yaml +++ b/apps/adguard-home/files/compose.yaml @@ -7,6 +7,6 @@ services: - "<< port_dns >>:53/tcp" - "<< port_dns >>:53/udp" volumes: - - << data_dir >>/<< service_name >>/work:/opt/adguardhome/work - - << data_dir >>/<< service_name >>/conf:/opt/adguardhome/conf + - << appdata_dir >>/<< service_name >>/work:/opt/adguardhome/work + - << appdata_dir >>/<< service_name >>/conf:/opt/adguardhome/conf restart: unless-stopped diff --git a/apps/adguard-home/template.json b/apps/adguard-home/template.json index 851a3c9..611f585 100644 --- a/apps/adguard-home/template.json +++ b/apps/adguard-home/template.json @@ -33,9 +33,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/arr-stack/files/compose.yaml b/apps/arr-stack/files/compose.yaml index 04a0cd1..befcf92 100644 --- a/apps/arr-stack/files/compose.yaml +++ b/apps/arr-stack/files/compose.yaml @@ -1,43 +1,29 @@ # ARR-stack — kies per onderdeel of je het wilt. # -# Aandachtspunten: -# * Zet de download- en mediamap op hetzelfde bestandssysteem, anders kopieert -# elke voltooide download in plaats van te verplaatsen (traag, dubbele opslag). -# * Draai je met Gluetun, dan zitten de downloadclients in het netwerk van die -# container en bereik je hun webinterface via de Gluetun-poorten. +# Alles deelt één map, gekoppeld als /data. Dat is geen smaakkwestie: +# staan je downloads en je bibliotheek op verschillende mounts, dan kan +# Sonarr geen hardlink maken en kopieert elke voltooide download naar je +# bibliotheek. Traag, en je hebt alles tijdelijk dubbel op de schijf. +# +# /data/media/{films,series,muziek,boeken} je bibliotheek +# /data/torrents/ torrents (blijven seeden) +# /data/usenet/ usenet-downloads +# +# Draai je met Gluetun, dan zitten de downloadclients in het netwerk van +# die container en bereik je hun webinterface via de Gluetun-poorten. services: -<%- if enable_sonarr %> - << service_name >>-sonarr: - image: lscr.io/linuxserver/sonarr:latest - container_name: << service_name >>-sonarr +<%- if enable_kapowarr %> + << service_name >>-kapowarr: + image: mrcas/kapowarr:latest + container_name: << service_name >>-kapowarr environment: - - PUID=<< puid >> - - PGID=<< pgid >> - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/sonarr:/config - - << media_dir >>/series:/tv - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/kapowarr:/app/db + - << data_root >>:/data ports: - - "<< port_sonarr >>:8989" - restart: unless-stopped -<%- endif %> - -<%- if enable_radarr %> - << service_name >>-radarr: - image: lscr.io/linuxserver/radarr:latest - container_name: << service_name >>-radarr - environment: - - PUID=<< puid >> - - PGID=<< pgid >> - - TZ=<< timezone >> - volumes: - - << data_dir >>/<< service_name >>/radarr:/config - - << media_dir >>/films:/movies - - << downloads_dir >>:/downloads - ports: - - "<< port_radarr >>:7878" + - "<< port_kapowarr >>:5656" restart: unless-stopped <%- endif %> @@ -49,15 +35,49 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/lidarr:/config - - << media_dir >>/muziek:/music - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/lidarr:/config + - << data_root >>:/data ports: - "<< port_lidarr >>:8686" restart: unless-stopped <%- endif %> +<%- if enable_mylar3 %> + << service_name >>-mylar3: + image: lscr.io/linuxserver/mylar3:latest + container_name: << service_name >>-mylar3 + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/mylar3:/config + - << data_root >>:/data + ports: + - "<< port_mylar3 >>:8090" + restart: unless-stopped +<%- endif %> + +<%- if enable_radarr %> + << service_name >>-radarr: + image: lscr.io/linuxserver/radarr:latest + container_name: << service_name >>-radarr + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/radarr:/config + - << data_root >>:/data + ports: + - "<< port_radarr >>:7878" + restart: unless-stopped +<%- endif %> + <%- if enable_readarr %> << service_name >>-readarr: image: lscr.io/linuxserver/readarr:develop @@ -66,15 +86,32 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/readarr:/config - - << media_dir >>/boeken:/books - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/readarr:/config + - << data_root >>:/data ports: - "<< port_readarr >>:8787" restart: unless-stopped <%- endif %> +<%- if enable_sonarr %> + << service_name >>-sonarr: + image: lscr.io/linuxserver/sonarr:latest + container_name: << service_name >>-sonarr + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/sonarr:/config + - << data_root >>:/data + ports: + - "<< port_sonarr >>:8989" + restart: unless-stopped +<%- endif %> + <%- if enable_whisparr %> << service_name >>-whisparr: image: ghcr.io/hotio/whisparr:latest @@ -83,27 +120,39 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/whisparr:/config - - << media_dir >>/volwassen:/adult - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/whisparr:/config + - << data_root >>:/data ports: - "<< port_whisparr >>:6969" restart: unless-stopped <%- endif %> -<%- if enable_prowlarr %> - << service_name >>-prowlarr: - image: lscr.io/linuxserver/prowlarr:latest - container_name: << service_name >>-prowlarr +<%- if enable_byparr %> + << service_name >>-byparr: + image: ghcr.io/thephaseless/byparr:latest + container_name: << service_name >>-byparr environment: - - PUID=<< puid >> - - PGID=<< pgid >> - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/prowlarr:/config + - << appdata_dir >>/<< service_name >>/byparr:/config ports: - - "<< port_prowlarr >>:9696" + - "<< port_byparr >>:8191" + restart: unless-stopped +<%- endif %> + +<%- if enable_flaresolverr %> + << service_name >>-flaresolverr: + image: ghcr.io/flaresolverr/flaresolverr:latest + container_name: << service_name >>-flaresolverr + environment: + - TZ=<< timezone >> + - LOG_LEVEL=info + volumes: + - << appdata_dir >>/<< service_name >>/flaresolverr:/config + ports: + - "<< port_flaresolverr >>:8191" restart: unless-stopped <%- endif %> @@ -115,88 +164,58 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/jackett:/config + - << appdata_dir >>/<< service_name >>/jackett:/config ports: - "<< port_jackett >>:9117" restart: unless-stopped <%- endif %> -<%- if enable_bazarr %> - << service_name >>-bazarr: - image: lscr.io/linuxserver/bazarr:latest - container_name: << service_name >>-bazarr +<%- if enable_nzbhydra2 %> + << service_name >>-nzbhydra2: + image: lscr.io/linuxserver/nzbhydra2:latest + container_name: << service_name >>-nzbhydra2 environment: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/bazarr:/config - - << media_dir >>/films:/movies - - << media_dir >>/series:/tv + - << appdata_dir >>/<< service_name >>/nzbhydra2:/config ports: - - "<< port_bazarr >>:6767" + - "<< port_nzbhydra2 >>:5076" restart: unless-stopped <%- endif %> -<%- if enable_flaresolverr %> - << service_name >>-flaresolverr: - image: ghcr.io/flaresolverr/flaresolverr:latest - container_name: << service_name >>-flaresolverr - environment: - - TZ=<< timezone >> - - LOG_LEVEL=info - ports: - - "<< port_flaresolverr >>:8191" - restart: unless-stopped -<%- endif %> - -<%- if enable_gluetun %> - << service_name >>-gluetun: - image: qmcgaw/gluetun:latest - container_name: << service_name >>-gluetun - cap_add: - - NET_ADMIN - devices: - - /dev/net/tun:/dev/net/tun - environment: - - TZ=<< timezone >> - - VPN_SERVICE_PROVIDER=<< vpn_provider >> - - VPN_TYPE=<< vpn_type >> - - WIREGUARD_PRIVATE_KEY=<< wireguard_private_key >> - - WIREGUARD_ADDRESSES=<< wireguard_addresses >> - - OPENVPN_USER=<< openvpn_user >> - - OPENVPN_PASSWORD=<< openvpn_password >> - ports: - # De downloadclients delen dit netwerk, dus hun poorten staan hier. -<%- if enable_qbittorrent %> - - "<< port_qbittorrent >>:8090" - - "<< port_qbittorrent_tcp >>:6881" - - "<< port_qbittorrent_tcp >>:6881/udp" -<%- endif %> -<%- if enable_sabnzbd %> - - "<< port_sabnzbd >>:8080" -<%- endif %> -<%- if enable_nzbget %> - - "<< port_nzbget >>:6789" -<%- endif %> - volumes: - - << data_dir >>/<< service_name >>/gluetun:/gluetun - restart: unless-stopped -<%- endif %> - -<%- if enable_qbittorrent %> - << service_name >>-qbittorrent: - image: lscr.io/linuxserver/qbittorrent:latest - container_name: << service_name >>-qbittorrent +<%- if enable_prowlarr %> + << service_name >>-prowlarr: + image: lscr.io/linuxserver/prowlarr:latest + container_name: << service_name >>-prowlarr environment: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> - - WEBUI_PORT=8090 + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/qbittorrent:/config - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/prowlarr:/config + ports: + - "<< port_prowlarr >>:9696" + restart: unless-stopped +<%- endif %> + +<%- if enable_deluge %> + << service_name >>-deluge: + image: lscr.io/linuxserver/deluge:latest + container_name: << service_name >>-deluge + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/deluge:/config + - << data_root >>:/data <%- if enable_gluetun %> network_mode: "service:<< service_name >>-gluetun" depends_on: @@ -204,32 +223,9 @@ services: <%- endif %> <%- if not enable_gluetun %> ports: - - "<< port_qbittorrent >>:8090" - - "<< port_qbittorrent_tcp >>:6881" - - "<< port_qbittorrent_tcp >>:6881/udp" -<%- endif %> - restart: unless-stopped -<%- endif %> - -<%- if enable_sabnzbd %> - << service_name >>-sabnzbd: - image: lscr.io/linuxserver/sabnzbd:latest - container_name: << service_name >>-sabnzbd - environment: - - PUID=<< puid >> - - PGID=<< pgid >> - - TZ=<< timezone >> - volumes: - - << data_dir >>/<< service_name >>/sabnzbd:/config - - << downloads_dir >>:/downloads -<%- if enable_gluetun %> - network_mode: "service:<< service_name >>-gluetun" - depends_on: - - << service_name >>-gluetun -<%- endif %> -<%- if not enable_gluetun %> - ports: - - "<< port_sabnzbd >>:8080" + - "<< port_deluge >>:8112" + - "<< port_deluge_torrent >>:6881" + - "<< port_deluge_torrent >>:6881/udp" <%- endif %> restart: unless-stopped <%- endif %> @@ -242,9 +238,10 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/nzbget:/config - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/nzbget:/config + - << data_root >>:/data <%- if enable_gluetun %> network_mode: "service:<< service_name >>-gluetun" depends_on: @@ -257,44 +254,134 @@ services: restart: unless-stopped <%- endif %> -<%- if enable_jellyseerr %> - << service_name >>-jellyseerr: - image: fallenbagel/jellyseerr:latest - container_name: << service_name >>-jellyseerr +<%- if enable_qbittorrent %> + << service_name >>-qbittorrent: + image: lscr.io/linuxserver/qbittorrent:latest + container_name: << service_name >>-qbittorrent environment: + - PUID=<< puid >> + - PGID=<< pgid >> - TZ=<< timezone >> - - LOG_LEVEL=info + - UMASK=002 + - WEBUI_PORT=8090 volumes: - - << data_dir >>/<< service_name >>/jellyseerr:/app/config + - << appdata_dir >>/<< service_name >>/qbittorrent:/config + - << data_root >>:/data +<%- if enable_gluetun %> + network_mode: "service:<< service_name >>-gluetun" + depends_on: + - << service_name >>-gluetun +<%- endif %> +<%- if not enable_gluetun %> ports: - - "<< port_jellyseerr >>:5055" + - "<< port_qbittorrent >>:8090" + - "<< port_qbittorrent_torrent >>:6881" + - "<< port_qbittorrent_torrent >>:6881/udp" +<%- endif %> restart: unless-stopped <%- endif %> -<%- if enable_recyclarr %> - << service_name >>-recyclarr: - image: ghcr.io/recyclarr/recyclarr:latest - container_name: << service_name >>-recyclarr - user: << puid >>:<< pgid >> +<%- if enable_sabnzbd %> + << service_name >>-sabnzbd: + image: lscr.io/linuxserver/sabnzbd:latest + container_name: << service_name >>-sabnzbd environment: + - PUID=<< puid >> + - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/recyclarr:/config + - << appdata_dir >>/<< service_name >>/sabnzbd:/config + - << data_root >>:/data +<%- if enable_gluetun %> + network_mode: "service:<< service_name >>-gluetun" + depends_on: + - << service_name >>-gluetun +<%- endif %> +<%- if not enable_gluetun %> + ports: + - "<< port_sabnzbd >>:8080" +<%- endif %> restart: unless-stopped <%- endif %> -<%- if enable_unpackerr %> - << service_name >>-unpackerr: - image: ghcr.io/unpackerr/unpackerr:latest - container_name: << service_name >>-unpackerr - user: << puid >>:<< pgid >> +<%- if enable_slskd %> + << service_name >>-slskd: + image: slskd/slskd:latest + container_name: << service_name >>-slskd environment: - TZ=<< timezone >> - - UN_SONARR_0_URL=http://<< service_name >>-sonarr:8989 - - UN_RADARR_0_URL=http://<< service_name >>-radarr:7878 + - SLSKD_REMOTE_CONFIGURATION=true volumes: - - << data_dir >>/<< service_name >>/unpackerr:/config - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>/slskd:/app + - << data_root >>:/data +<%- if enable_gluetun %> + network_mode: "service:<< service_name >>-gluetun" + depends_on: + - << service_name >>-gluetun +<%- endif %> +<%- if not enable_gluetun %> + ports: + - "<< port_slskd >>:5030" + - "<< port_slskd_listen >>:50300" +<%- endif %> + restart: unless-stopped +<%- endif %> + +<%- if enable_transmission %> + << service_name >>-transmission: + image: lscr.io/linuxserver/transmission:latest + container_name: << service_name >>-transmission + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/transmission:/config + - << data_root >>:/data +<%- if enable_gluetun %> + network_mode: "service:<< service_name >>-gluetun" + depends_on: + - << service_name >>-gluetun +<%- endif %> +<%- if not enable_gluetun %> + ports: + - "<< port_transmission >>:9091" + - "<< port_transmission_torrent >>:51413" + - "<< port_transmission_torrent >>:51413/udp" +<%- endif %> + restart: unless-stopped +<%- endif %> + +<%- if enable_bazarr %> + << service_name >>-bazarr: + image: lscr.io/linuxserver/bazarr:latest + container_name: << service_name >>-bazarr + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/bazarr:/config + - << data_root >>:/data + ports: + - "<< port_bazarr >>:6767" + restart: unless-stopped +<%- endif %> + +<%- if enable_lingarr %> + << service_name >>-lingarr: + image: lingarr/lingarr:latest + container_name: << service_name >>-lingarr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/lingarr:/app/config + - << data_root >>:/data + ports: + - "<< port_lingarr >>:9876" restart: unless-stopped <%- endif %> @@ -306,57 +393,453 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 - serverIP=0.0.0.0 - serverPort=8266 - webUIPort=8265 - internalNode=true volumes: - - << data_dir >>/<< service_name >>/tdarr/server:/app/server - - << data_dir >>/<< service_name >>/tdarr/configs:/app/configs - - << media_dir >>:/media - - << downloads_dir >>/tdarr-cache:/temp + - << appdata_dir >>/<< service_name >>/tdarr:/app/server + - << data_root >>:/data + - << appdata_dir >>/<< service_name >>/tdarr-configs:/app/configs ports: - "<< port_tdarr >>:8265" - "<< port_tdarr_server >>:8266" restart: unless-stopped <%- endif %> -<%- if enable_autobrr %> - << service_name >>-autobrr: - image: ghcr.io/autobrr/autobrr:latest - container_name: << service_name >>-autobrr +<%- if enable_unpackerr %> + << service_name >>-unpackerr: + image: ghcr.io/unpackerr/unpackerr:latest + container_name: << service_name >>-unpackerr + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UN_SONARR_0_URL=<< sonarr_url >> + - UN_SONARR_0_API_KEY=<< sonarr_apikey >> + - UN_RADARR_0_URL=<< radarr_url >> + - UN_RADARR_0_API_KEY=<< radarr_apikey >> + volumes: + - << appdata_dir >>/<< service_name >>/unpackerr:/config + - << data_root >>:/data + restart: unless-stopped +<%- endif %> + +<%- if enable_jellyseerr %> + << service_name >>-jellyseerr: + image: fallenbagel/jellyseerr:latest + container_name: << service_name >>-jellyseerr + environment: + - TZ=<< timezone >> + - LOG_LEVEL=info + volumes: + - << appdata_dir >>/<< service_name >>/jellyseerr:/app/config + ports: + - "<< port_jellyseerr >>:5055" + restart: unless-stopped +<%- endif %> + +<%- if enable_overseerr %> + << service_name >>-overseerr: + image: sctx/overseerr:latest + container_name: << service_name >>-overseerr + environment: + - TZ=<< timezone >> + - LOG_LEVEL=info + volumes: + - << appdata_dir >>/<< service_name >>/overseerr:/app/config + ports: + - "<< port_overseerr >>:5055" + restart: unless-stopped +<%- endif %> + +<%- if enable_prefetcharr %> + << service_name >>-prefetcharr: + image: phueber/prefetcharr:latest + container_name: << service_name >>-prefetcharr environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/autobrr:/config + - << appdata_dir >>/<< service_name >>/prefetcharr:/config + restart: unless-stopped +<%- endif %> + +<%- if enable_pulsarr %> + << service_name >>-pulsarr: + image: lakker/pulsarr:latest + container_name: << service_name >>-pulsarr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/pulsarr:/app/data ports: - - "<< port_autobrr >>:7474" + - "<< port_pulsarr >>:3003" + restart: unless-stopped +<%- endif %> + +<%- if enable_requestrr %> + << service_name >>-requestrr: + image: thomst08/requestrr:latest + container_name: << service_name >>-requestrr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/requestrr:/root/config + ports: + - "<< port_requestrr >>:4545" + restart: unless-stopped +<%- endif %> + +<%- if enable_suggestarr %> + << service_name >>-suggestarr: + image: ciuse99/suggestarr:latest + container_name: << service_name >>-suggestarr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/suggestarr:/app/config + ports: + - "<< port_suggestarr >>:5000" + restart: unless-stopped +<%- endif %> + +<%- if enable_wizarr %> + << service_name >>-wizarr: + image: ghcr.io/wizarrrr/wizarr:latest + container_name: << service_name >>-wizarr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/wizarr:/data/database + ports: + - "<< port_wizarr >>:5690" + restart: unless-stopped +<%- endif %> + +<%- if enable_cleanuparr %> + << service_name >>-cleanuparr: + image: ghcr.io/cleanuparr/cleanuparr:latest + container_name: << service_name >>-cleanuparr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/cleanuparr:/config + - << data_root >>:/data + ports: + - "<< port_cleanuparr >>:11011" + restart: unless-stopped +<%- endif %> + +<%- if enable_crossseed %> + << service_name >>-crossseed: + image: ghcr.io/cross-seed/cross-seed:latest + container_name: << service_name >>-crossseed + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/crossseed:/config + - << data_root >>:/data + command: daemon + ports: + - "<< port_crossseed >>:2468" + restart: unless-stopped +<%- endif %> + +<%- if enable_decluttarr %> + << service_name >>-decluttarr: + image: ghcr.io/manimatter/decluttarr:latest + container_name: << service_name >>-decluttarr + environment: + - TZ=<< timezone >> + - SONARR_URL=<< sonarr_url >> + - SONARR_KEY=<< sonarr_apikey >> + - RADARR_URL=<< radarr_url >> + - RADARR_KEY=<< radarr_apikey >> + - LOG_LEVEL=INFO + volumes: + - << appdata_dir >>/<< service_name >>/decluttarr:/config + restart: unless-stopped +<%- endif %> + +<%- if enable_janitorr %> + << service_name >>-janitorr: + image: ghcr.io/schaka/janitorr:native-stable + container_name: << service_name >>-janitorr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/janitorr:/config + - << data_root >>:/data + ports: + - "<< port_janitorr >>:8978" restart: unless-stopped <%- endif %> <%- if enable_maintainerr %> << service_name >>-maintainerr: - image: ghcr.io/jorenn92/maintainerr:latest + image: ghcr.io/maintainerr/maintainerr:latest container_name: << service_name >>-maintainerr - user: << puid >>:<< pgid >> environment: + - PUID=<< puid >> + - PGID=<< pgid >> - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/maintainerr:/opt/data + - << appdata_dir >>/<< service_name >>/maintainerr:/opt/data ports: - "<< port_maintainerr >>:6246" restart: unless-stopped <%- endif %> -<%- if enable_huntarr %> - << service_name >>-huntarr: - image: ghcr.io/plexguide/huntarr:latest - container_name: << service_name >>-huntarr +<%- if enable_neutarr %> + << service_name >>-neutarr: + image: iampuid0/neutarr:latest + container_name: << service_name >>-neutarr environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/huntarr:/config + - << appdata_dir >>/<< service_name >>/neutarr:/config ports: - - "<< port_huntarr >>:9705" + - "<< port_neutarr >>:9705" + restart: unless-stopped +<%- endif %> + +<%- if enable_configarr %> + << service_name >>-configarr: + image: ghcr.io/raydak-labs/configarr:latest + container_name: << service_name >>-configarr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/configarr:/app/config + restart: unless-stopped +<%- endif %> + +<%- if enable_profilarr %> + << service_name >>-profilarr: + image: santiagosayshey/profilarr:latest + container_name: << service_name >>-profilarr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/profilarr:/config + ports: + - "<< port_profilarr >>:6868" + restart: unless-stopped +<%- endif %> + +<%- if enable_recyclarr %> + << service_name >>-recyclarr: + image: ghcr.io/recyclarr/recyclarr:latest + container_name: << service_name >>-recyclarr + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/recyclarr:/config + restart: unless-stopped +<%- endif %> + +<%- if enable_kometa %> + << service_name >>-kometa: + image: kometateam/kometa:latest + container_name: << service_name >>-kometa + environment: + - TZ=<< timezone >> + - KOMETA_RUN=false + volumes: + - << appdata_dir >>/<< service_name >>/kometa:/config + - << data_root >>:/data + restart: unless-stopped +<%- endif %> + +<%- if enable_posterizarr %> + << service_name >>-posterizarr: + image: ghcr.io/fscorrupt/posterizarr:latest + container_name: << service_name >>-posterizarr + environment: + - TZ=<< timezone >> + - RUN_TIME=disabled + volumes: + - << appdata_dir >>/<< service_name >>/posterizarr:/config + - << data_root >>:/data + restart: unless-stopped +<%- endif %> + +<%- if enable_trailarr %> + << service_name >>-trailarr: + image: nandyalu/trailarr:latest + container_name: << service_name >>-trailarr + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/trailarr:/config + - << data_root >>:/data + ports: + - "<< port_trailarr >>:7889" + restart: unless-stopped +<%- endif %> + +<%- if enable_autopulse %> + << service_name >>-autopulse: + image: ghcr.io/dan-online/autopulse:latest + container_name: << service_name >>-autopulse + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/autopulse:/app/config + ports: + - "<< port_autopulse >>:2875" + restart: unless-stopped +<%- endif %> + +<%- if enable_exportarr %> + << service_name >>-exportarr: + image: ghcr.io/onedr0p/exportarr:latest + container_name: << service_name >>-exportarr + environment: + - TZ=<< timezone >> + - URL=<< arr_url >> + - APIKEY=<< arr_apikey >> + - PORT=<< port_exportarr >> + volumes: + - << appdata_dir >>/<< service_name >>/exportarr:/config + command: << arr_soort >> + ports: + - "<< port_exportarr >>:9707" + restart: unless-stopped +<%- endif %> + +<%- if enable_homarr %> + << service_name >>-homarr: + image: ghcr.io/homarr-labs/homarr:latest + container_name: << service_name >>-homarr + environment: + - TZ=<< timezone >> + - SECRET_ENCRYPTION_KEY=<< homarr_encryption_key >> + volumes: + - << appdata_dir >>/<< service_name >>/homarr:/appdata + ports: + - "<< port_homarr >>:7575" + restart: unless-stopped +<%- endif %> + +<%- if enable_jellystat %> + << service_name >>-jellystat: + image: cyfershepard/jellystat:latest + container_name: << service_name >>-jellystat + environment: + - TZ=<< timezone >> + - POSTGRES_USER=jellystat + - POSTGRES_PASSWORD=<< db_password >> + - POSTGRES_IP=<< service_name >>-jellystat-db + - POSTGRES_PORT=5432 + - JWT_SECRET=<< jwt_secret >> + volumes: + - << appdata_dir >>/<< service_name >>/jellystat:/app/backend/backup-data + ports: + - "<< port_jellystat >>:3000" + depends_on: + - << service_name >>-jellystat-db + restart: unless-stopped + << service_name >>-jellystat-db: + image: postgres:16-alpine + container_name: << service_name >>-jellystat-db + environment: + - POSTGRES_USER=jellystat + - POSTGRES_PASSWORD=<< db_password >> + - POSTGRES_DB=jfstat + volumes: + - << appdata_dir >>/<< service_name >>-jellystat-db:/var/lib/postgresql/data + restart: unless-stopped +<%- endif %> + +<%- if enable_notifiarr %> + << service_name >>-notifiarr: + image: golift/notifiarr:latest + container_name: << service_name >>-notifiarr + environment: + - TZ=<< timezone >> + - DN_API_KEY=<< notifiarr_apikey >> + volumes: + - << appdata_dir >>/<< service_name >>/notifiarr:/config + ports: + - "<< port_notifiarr >>:5454" + restart: unless-stopped +<%- endif %> + +<%- if enable_tautulli %> + << service_name >>-tautulli: + image: lscr.io/linuxserver/tautulli:latest + container_name: << service_name >>-tautulli + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>/tautulli:/config + ports: + - "<< port_tautulli >>:8181" + restart: unless-stopped +<%- endif %> + +<%- if enable_soularr %> + << service_name >>-soularr: + image: mrusse08/soularr:latest + container_name: << service_name >>-soularr + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>/soularr:/data + - << data_root >>:/data + restart: unless-stopped +<%- endif %> + +<%- if enable_gluetun %> + << service_name >>-gluetun: + image: qmcgaw/gluetun:latest + container_name: << service_name >>-gluetun + environment: + - TZ=<< timezone >> + - VPN_SERVICE_PROVIDER=<< vpn_provider >> + - VPN_TYPE=<< vpn_type >> + - SERVER_COUNTRIES=<< vpn_landen >> + - WIREGUARD_PRIVATE_KEY=<< wireguard_private_key >> + - WIREGUARD_ADDRESSES=<< wireguard_addresses >> + - OPENVPN_USER=<< openvpn_user >> + - OPENVPN_PASSWORD=<< openvpn_password >> + volumes: + - << appdata_dir >>/<< service_name >>/gluetun:/gluetun + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun + ports: + # De downloadclients delen dit netwerk, dus hun webinterfaces + # staan hier. Inkomende torrentpoorten niet: die regelt je + # VPN-aanbieder met port forwarding. +<%- if enable_deluge %> + - "<< port_deluge >>:8112" +<%- endif %> +<%- if enable_nzbget %> + - "<< port_nzbget >>:6789" +<%- endif %> +<%- if enable_qbittorrent %> + - "<< port_qbittorrent >>:8090" +<%- endif %> +<%- if enable_sabnzbd %> + - "<< port_sabnzbd >>:8080" +<%- endif %> +<%- if enable_slskd %> + - "<< port_slskd >>:5030" +<%- endif %> +<%- if enable_transmission %> + - "<< port_transmission >>:9091" +<%- endif %> restart: unless-stopped <%- endif %> diff --git a/apps/arr-stack/template.json b/apps/arr-stack/template.json index ab1b42b..441307c 100644 --- a/apps/arr-stack/template.json +++ b/apps/arr-stack/template.json @@ -2,7 +2,7 @@ "kind": "compose", "metadata": { "name": "ARR-stack", - "description": "Media-automatisering met een schakelaar per onderdeel: Sonarr, Radarr, Lidarr, Readarr, Whisparr, Prowlarr, Jackett, Bazarr, FlareSolverr, qBittorrent, SABnzbd, NZBGet, Gluetun (VPN), Jellyseerr, Recyclarr, Unpackerr, Tdarr, Autobrr, Maintainerr en Huntarr.", + "description": "Alles voor media-automatisering in één keer, met een schakelaar per onderdeel: de *arr-apps, indexers, downloadclients, ondertitels, verzoeken, opruimen en statistiek. Elk onderdeel bestaat ook als losse app in de store; hier zet je in één keer neer wat je nodig hebt, op één gedeelde /data-map zodat hardlinks werken.", "tags": [ "media", "automatisering", @@ -35,28 +35,21 @@ "description": "Wordt het voorvoegsel van elke container, bv. arr-sonarr" }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Configuratiemap", + "title": "Appdata-map", "default": "/opt/serverup/appdata", - "required": true + "required": true, + "description": "Basismap voor de instellingen van elk onderdeel" }, { - "name": "media_dir", + "name": "data_root", "type": "str", - "title": "Mediamap", - "default": "/mnt/media", + "title": "Gedeelde datamap", + "default": "/mnt/data", "required": true, - "description": "Hier komen films/, series/, muziek/ en boeken/ onder te staan" - }, - { - "name": "downloads_dir", - "type": "str", - "title": "Downloadmap", - "default": "/mnt/downloads", - "required": true, - "description": "Zet deze op hetzelfde bestandssysteem als de mediamap, anders kopieert elke download in plaats van te verplaatsen", - "help": "Zet deze map op hetzelfde bestandssysteem als je mediamap. Staan ze op verschillende schijven of volumes, dan kopieert elke voltooide download in plaats van te verplaatsen: traag, en je hebt alles tijdelijk dubbel." + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." }, { "name": "timezone", @@ -71,8 +64,7 @@ "title": "Gebruikers-ID (PUID)", "default": 1000, "required": true, - "description": "`id -u` op je host; bepaalt de eigenaar van bestanden", - "help": "Het gebruikersnummer waaronder de containers draaien. Klopt dit niet met de eigenaar van je mediamap, dan kunnen de apps er niet in schrijven. Vind het met `id -u` op je server." + "description": "`id -u` op je server; bepaalt de eigenaar van de bestanden" }, { "name": "pgid", @@ -84,190 +76,258 @@ ] }, { - "title": "Sonarr — series", + "title": "Kapowarr", + "section": "Bibliotheken", + "toggle": "enable_kapowarr", + "toggle_default": false, + "description": "Bouwt en beheert een stripbibliotheek, met eigen bestandsnaamgeving en kwaliteitsregels.", "items": [ { - "name": "port_sonarr", + "name": "port_kapowarr", "type": "int", - "title": "Poort", - "default": 8989, - "required": true + "title": "Webinterface", + "default": 5656, + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_sonarr", - "toggle_default": true, - "description": "Zoekt, downloadt en hernoemt series" + ] }, { - "title": "Radarr — films", - "items": [ - { - "name": "port_radarr", - "type": "int", - "title": "Poort", - "default": 7878, - "required": true - } - ], - "toggle": "enable_radarr", - "toggle_default": true, - "description": "Zoekt, downloadt en hernoemt films" - }, - { - "title": "Lidarr — muziek", + "title": "Lidarr", + "section": "Bibliotheken", + "toggle": "enable_lidarr", + "toggle_default": false, + "description": "Beheert je muziekbibliotheek: volgt artiesten en haalt nieuwe albums binnen.", "items": [ { "name": "port_lidarr", "type": "int", - "title": "Poort", + "title": "Webinterface", "default": 8686, - "required": true + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_lidarr", - "toggle_default": false + ] }, { - "title": "Readarr — boeken", + "title": "Mylar3", + "section": "Bibliotheken", + "toggle": "enable_mylar3", + "toggle_default": false, + "description": "Volgt stripseries en haalt nieuwe uitgaven binnen. De *arr-aanpak, maar voor comics.", + "items": [ + { + "name": "port_mylar3", + "type": "int", + "title": "Webinterface", + "default": 8115, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 8090; hier verplaatst omdat die poort al bezet is" + } + ] + }, + { + "title": "Radarr", + "section": "Bibliotheken", + "toggle": "enable_radarr", + "toggle_default": true, + "description": "Zoekt, downloadt en hernoemt films. Dezelfde aanpak als Sonarr, maar dan voor je filmbibliotheek.", + "items": [ + { + "name": "port_radarr", + "type": "int", + "title": "Webinterface", + "default": 7878, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Readarr", + "section": "Bibliotheken", + "toggle": "enable_readarr", + "toggle_default": false, + "description": "Beheert e-boeken en luisterboeken. Let op: de ontwikkeling is stilgelegd; het draait nog wel, maar er komen geen nieuwe versies meer.", "items": [ { "name": "port_readarr", "type": "int", - "title": "Poort", + "title": "Webinterface", "default": 8787, - "required": true + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_readarr", - "toggle_default": false, - "description": "Let op: de ontwikkeling van Readarr is stilgelegd; het draait nog wel" + ] }, { - "title": "Whisparr — volwassenen", + "title": "Sonarr", + "section": "Bibliotheken", + "toggle": "enable_sonarr", + "toggle_default": true, + "description": "Zoekt, downloadt en hernoemt series. Houdt bij welke afleveringen je mist en pakt ze op zodra ze verschijnen.", + "items": [ + { + "name": "port_sonarr", + "type": "int", + "title": "Webinterface", + "default": 8989, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Whisparr", + "section": "Bibliotheken", + "toggle": "enable_whisparr", + "toggle_default": false, + "description": "Dezelfde automatisering als Sonarr en Radarr, gericht op materiaal voor volwassenen.", "items": [ { "name": "port_whisparr", "type": "int", - "title": "Poort", + "title": "Webinterface", "default": 6969, - "required": true + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_whisparr", - "toggle_default": false + ] }, { - "title": "Prowlarr — indexerbeheer", - "items": [ - { - "name": "port_prowlarr", - "type": "int", - "title": "Poort", - "default": 9696, - "required": true - } - ], - "toggle": "enable_prowlarr", - "toggle_default": true, - "description": "Beheert je indexers centraal en duwt ze naar de andere *arr-apps" - }, - { - "title": "Jackett — indexerproxy", - "items": [ - { - "name": "port_jackett", - "type": "int", - "title": "Poort", - "default": 9117, - "required": true - } - ], - "toggle": "enable_jackett", + "title": "Byparr", + "section": "Indexers", + "toggle": "enable_byparr", "toggle_default": false, - "description": "Ouder alternatief voor Prowlarr; meestal heb je er maar één nodig" + "description": "Nieuwer alternatief voor FlareSolverr, gebouwd op SeleniumBase. Spreekt dezelfde API, dus je kunt het er zo voor in de plaats zetten.", + "items": [ + { + "name": "port_byparr", + "type": "int", + "title": "Poort", + "default": 8119, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Byparr luistert intern op 8191, net als FlareSolverr" + } + ] }, { - "title": "FlareSolverr — Cloudflare omzeilen", + "title": "FlareSolverr", + "section": "Indexers", + "toggle": "enable_flaresolverr", + "toggle_default": false, + "description": "Haalt pagina's op die achter een Cloudflare-controle zitten, zodat je indexers er alsnog bij kunnen.", "items": [ { "name": "port_flaresolverr", "type": "int", "title": "Poort", "default": 8191, - "required": true + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_flaresolverr", + ] + }, + { + "title": "Jackett", + "section": "Indexers", + "toggle": "enable_jackett", "toggle_default": false, - "description": "Nodig voor indexers die achter een Cloudflare-controle zitten" - }, - { - "title": "Bazarr — ondertitels", + "description": "Vertaalt trackers naar één API voor je *arr-apps. Ouder alternatief voor Prowlarr; meestal heb je er maar één nodig.", "items": [ { - "name": "port_bazarr", - "type": "int", - "title": "Poort", - "default": 6767, - "required": true - } - ], - "toggle": "enable_bazarr", - "toggle_default": true - }, - { - "title": "qBittorrent — torrents", - "items": [ - { - "name": "port_qbittorrent", + "name": "port_jackett", "type": "int", "title": "Webinterface", - "default": 8097, - "required": true + "default": 9117, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "NZBHydra2", + "section": "Indexers", + "toggle": "enable_nzbhydra2", + "toggle_default": false, + "description": "Bundelt meerdere usenet-indexers tot één zoekbron, met eigen statistieken per indexer.", + "items": [ + { + "name": "port_nzbhydra2", + "type": "int", + "title": "Webinterface", + "default": 5076, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Prowlarr", + "section": "Indexers", + "toggle": "enable_prowlarr", + "toggle_default": true, + "description": "Beheert je indexers op één plek en duwt ze door naar Sonarr, Radarr en de rest. Scheelt overal apart instellen.", + "items": [ + { + "name": "port_prowlarr", + "type": "int", + "title": "Webinterface", + "default": 9696, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Deluge", + "section": "Downloadclients", + "toggle": "enable_deluge", + "toggle_default": false, + "description": "Lichte torrentclient met webinterface en een uitgebreid plugin-systeem.", + "items": [ + { + "name": "port_deluge", + "type": "int", + "title": "Webinterface", + "default": 8113, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 8112; hier verplaatst omdat die poort al bezet is" }, { - "name": "port_qbittorrent_tcp", + "name": "port_deluge_torrent", "type": "int", "title": "Inkomende poort", - "default": 6881, - "required": true + "default": 6882, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Zet deze poort open in je router voor betere snelheden" } - ], - "toggle": "enable_qbittorrent", - "toggle_default": true, - "description": "Torrentclient met webinterface" + ] }, { - "title": "SABnzbd — usenet", - "items": [ - { - "name": "port_sabnzbd", - "type": "int", - "title": "Poort", - "default": 8098, - "required": true - } - ], - "toggle": "enable_sabnzbd", - "toggle_default": false - }, - { - "title": "NZBGet — usenet (lichter)", - "items": [ - { - "name": "port_nzbget", - "type": "int", - "title": "Poort", - "default": 6789, - "required": true - } - ], - "toggle": "enable_nzbget", + "title": "Gluetun", + "section": "Downloadclients", + "toggle": "enable_gluetun", "toggle_default": false, - "description": "Zuiniger alternatief voor SABnzbd" - }, - { - "title": "Gluetun — VPN voor de downloadclient", + "description": "VPN-container waar je andere containers doorheen laat lopen. Zet je downloadclient erachter met `network_mode: service:gluetun`.", "items": [ { "name": "vpn_provider", @@ -275,7 +335,7 @@ "title": "VPN-aanbieder", "default": "mullvad", "required": true, - "description": "Bijvoorbeeld mullvad, nordvpn, protonvpn of surfshark" + "description": "Bijvoorbeeld mullvad, nordvpn, protonvpn, airvpn of surfshark" }, { "name": "vpn_type", @@ -290,12 +350,27 @@ ] } }, + { + "name": "vpn_landen", + "type": "str", + "title": "Landen", + "default": "Netherlands", + "required": false, + "description": "Komma-gescheiden; leeg laten kiest willekeurig" + }, { "name": "wireguard_private_key", "type": "str", "title": "WireGuard privésleutel", "default": "", "required": false, + "secret": true, + "needs": [ + { + "name": "vpn_type", + "value": "wireguard" + } + ], "config": { "placeholder": "alleen bij wireguard" } @@ -306,6 +381,12 @@ "title": "WireGuard adressen", "default": "", "required": false, + "needs": [ + { + "name": "vpn_type", + "value": "wireguard" + } + ], "config": { "placeholder": "10.64.0.2/32" } @@ -315,115 +396,790 @@ "type": "str", "title": "OpenVPN gebruiker", "default": "", - "required": false + "required": false, + "needs": [ + { + "name": "vpn_type", + "value": "openvpn" + } + ] }, { "name": "openvpn_password", "type": "str", "title": "OpenVPN wachtwoord", "default": "", - "required": false + "required": false, + "secret": true, + "needs": [ + { + "name": "vpn_type", + "value": "openvpn" + } + ] } - ], - "toggle": "enable_gluetun", - "toggle_default": false, - "description": "Leidt al je downloadverkeer door een VPN. De downloadclients delen dan het netwerk van deze container, dus hun poorten komen hier te liggen." + ] }, { - "title": "Jellyseerr — verzoeken", + "title": "NZBGet", + "section": "Downloadclients", + "toggle": "enable_nzbget", + "toggle_default": false, + "description": "Zuinige usenet-downloader. Lichter dan SABnzbd en daarmee prettig op een kleine server.", "items": [ { - "name": "port_jellyseerr", + "name": "port_nzbget", "type": "int", - "title": "Poort", - "default": 5055, - "required": true + "title": "Webinterface", + "default": 6789, + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_jellyseerr", + ] + }, + { + "title": "qBittorrent", + "section": "Downloadclients", + "toggle": "enable_qbittorrent", "toggle_default": true, - "description": "Laat huisgenoten films en series aanvragen" + "description": "Torrentclient met webinterface. De meest gebruikte keuze naast de *arr-apps.", + "items": [ + { + "name": "port_qbittorrent", + "type": "int", + "title": "Webinterface", + "default": 8097, + "required": true, + "advanced": true, + "step": "instellingen" + }, + { + "name": "port_qbittorrent_torrent", + "type": "int", + "title": "Inkomende poort", + "default": 6881, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] }, { - "title": "Recyclarr — TRaSH-instellingen", - "items": [], - "toggle": "enable_recyclarr", + "title": "SABnzbd", + "section": "Downloadclients", + "toggle": "enable_sabnzbd", "toggle_default": false, - "description": "Synchroniseert kwaliteitsprofielen uit de TRaSH-gidsen naar Sonarr en Radarr" + "description": "Usenet-downloader met webinterface.", + "items": [ + { + "name": "port_sabnzbd", + "type": "int", + "title": "Webinterface", + "default": 8098, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] }, { - "title": "Unpackerr — archieven uitpakken", - "items": [], - "toggle": "enable_unpackerr", + "title": "slskd", + "section": "Downloadclients", + "toggle": "enable_slskd", "toggle_default": false, - "description": "Pakt gedownloade rar-archieven automatisch uit" + "description": "Soulseek-client met webinterface. In combinatie met Soularr vult het gaten in je muziekbibliotheek die de gewone indexers niet hebben.", + "items": [ + { + "name": "port_slskd", + "type": "int", + "title": "Webinterface", + "default": 5030, + "required": true, + "advanced": true, + "step": "instellingen" + }, + { + "name": "port_slskd_listen", + "type": "int", + "title": "Luisterpoort", + "default": 50300, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Zet deze poort open in je router, anders kun je alleen downloaden van gebruikers die zelf bereikbaar zijn" + } + ] }, { - "title": "Tdarr — hercoderen", + "title": "Transmission", + "section": "Downloadclients", + "toggle": "enable_transmission", + "toggle_default": false, + "description": "Sobere, stabiele torrentclient. Weinig knoppen, doet gewoon zijn werk.", + "items": [ + { + "name": "port_transmission", + "type": "int", + "title": "Webinterface", + "default": 8114, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 9091; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "port_transmission_torrent", + "type": "int", + "title": "Inkomende poort", + "default": 6883, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Zet deze poort open in je router voor betere snelheden" + } + ] + }, + { + "title": "Bazarr", + "section": "Ondertitels en verwerking", + "toggle": "enable_bazarr", + "toggle_default": true, + "description": "Zoekt en downloadt ondertitels bij wat Sonarr en Radarr al hebben binnengehaald.", + "items": [ + { + "name": "port_bazarr", + "type": "int", + "title": "Webinterface", + "default": 6767, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Lingarr", + "section": "Ondertitels en verwerking", + "toggle": "enable_lingarr", + "toggle_default": false, + "description": "Vertaalt ondertitels automatisch, met een lokaal model of een vertaaldienst naar keuze.", + "items": [ + { + "name": "port_lingarr", + "type": "int", + "title": "Webinterface", + "default": 9876, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Tdarr", + "section": "Ondertitels en verwerking", + "toggle": "enable_tdarr", + "toggle_default": false, + "description": "Zet je bibliotheek om naar een zuiniger formaat, verdeeld over meerdere machines als je wilt.", "items": [ { "name": "port_tdarr", "type": "int", "title": "Webinterface", "default": 8265, - "required": true + "required": true, + "advanced": true, + "step": "instellingen" }, { "name": "port_tdarr_server", "type": "int", "title": "Serverpoort", "default": 8266, - "required": true + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Waar de rekenknooppunten verbinding mee maken" } - ], - "toggle": "enable_tdarr", - "toggle_default": false, - "description": "Zet je bibliotheek om naar een zuiniger formaat" + ] }, { - "title": "Autobrr — automatisch grijpen", + "title": "Unpackerr", + "section": "Ondertitels en verwerking", + "toggle": "enable_unpackerr", + "toggle_default": false, + "description": "Pakt gedownloade rar-archieven uit zodra ze klaar zijn, en ruimt de restanten op.", "items": [ { - "name": "port_autobrr", - "type": "int", - "title": "Poort", - "default": 7474, - "required": true + "name": "sonarr_url", + "type": "str", + "title": "Sonarr", + "default": "http://sonarr:8989", + "required": false, + "connect": { + "app": "sonarr", + "scheme": "http", + "port": 8989 + }, + "help": "Het adres waarop Unpackerr Sonarr kan bereiken. Draaien ze allebei op hetzelfde gedeelde netwerk, dan is de containernaam genoeg." + }, + { + "name": "sonarr_apikey", + "type": "str", + "title": "Sonarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Sonarr onder Settings → General" + }, + { + "name": "radarr_url", + "type": "str", + "title": "Radarr", + "default": "http://radarr:7878", + "required": false, + "connect": { + "app": "radarr", + "scheme": "http", + "port": 7878 + }, + "help": "Het adres waarop Unpackerr Radarr kan bereiken." + }, + { + "name": "radarr_apikey", + "type": "str", + "title": "Radarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Radarr onder Settings → General" } - ], - "toggle": "enable_autobrr", - "toggle_default": false, - "description": "Reageert direct op aankondigingen in plaats van periodiek te zoeken" + ] }, { - "title": "Maintainerr — opruimen", + "title": "Jellyseerr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_jellyseerr", + "toggle_default": true, + "description": "Laat huisgenoten films en series aanvragen, gekoppeld aan Jellyfin, Emby of Plex.", + "items": [ + { + "name": "port_jellyseerr", + "type": "int", + "title": "Webinterface", + "default": 5055, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Overseerr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_overseerr", + "toggle_default": false, + "description": "Laat huisgenoten films en series aanvragen, gekoppeld aan Plex. Voor Jellyfin en Emby gebruik je Jellyseerr.", + "items": [ + { + "name": "port_overseerr", + "type": "int", + "title": "Webinterface", + "default": 8120, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 5055; hier verplaatst omdat Jellyseerr die al gebruikt" + } + ] + }, + { + "title": "Prefetcharr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_prefetcharr", + "toggle_default": false, + "description": "Laat Sonarr het volgende seizoen ophalen zodra je aan de laatste afleveringen van het huidige begint.", + "items": [] + }, + { + "title": "Pulsarr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_pulsarr", + "toggle_default": false, + "description": "Koppelt Plex-watchlists aan Sonarr en Radarr: wat je op je lijst zet, wordt opgehaald.", + "items": [ + { + "name": "port_pulsarr", + "type": "int", + "title": "Webinterface", + "default": 8117, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 3003; hier verplaatst omdat die poort al bezet is" + } + ] + }, + { + "title": "Requestrr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_requestrr", + "toggle_default": false, + "description": "Discord-bot waarmee je huisgenoten films en series kunnen aanvragen zonder een webinterface te openen.", + "items": [ + { + "name": "port_requestrr", + "type": "int", + "title": "Webinterface", + "default": 4545, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "SuggestArr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_suggestarr", + "toggle_default": false, + "description": "Kijkt wat er gekeken is en zet automatisch aanbevelingen klaar in Sonarr en Radarr.", + "items": [ + { + "name": "port_suggestarr", + "type": "int", + "title": "Webinterface", + "default": 8116, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 5000; hier verplaatst omdat die poort al bezet is" + } + ] + }, + { + "title": "Wizarr", + "section": "Verzoeken en gebruikers", + "toggle": "enable_wizarr", + "toggle_default": false, + "description": "Nodigt nieuwe gebruikers uit voor Plex, Jellyfin of Emby met een uitnodigingslink, inclusief uitleg voor de nieuwkomer.", + "items": [ + { + "name": "port_wizarr", + "type": "int", + "title": "Webinterface", + "default": 5690, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Cleanuparr", + "section": "Opruimen en onderhoud", + "toggle": "enable_cleanuparr", + "toggle_default": false, + "description": "Ruimt dode en kwaadaardige torrents op, en downloads waar niemand meer naar verwijst.", + "items": [ + { + "name": "port_cleanuparr", + "type": "int", + "title": "Webinterface", + "default": 11011, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "cross-seed", + "section": "Opruimen en onderhoud", + "toggle": "enable_crossseed", + "toggle_default": false, + "description": "Zoekt dezelfde bestanden bij andere trackers, zodat je één download op meerdere plekken kunt seeden.", + "items": [ + { + "name": "port_crossseed", + "type": "int", + "title": "Poort", + "default": 2468, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Decluttarr", + "section": "Opruimen en onderhoud", + "toggle": "enable_decluttarr", + "toggle_default": false, + "description": "Houdt de downloadwachtrij schoon: gooit weg wat vastloopt of niet meer nodig is.", + "items": [ + { + "name": "sonarr_url", + "type": "str", + "title": "Sonarr", + "default": "http://sonarr:8989", + "required": false, + "connect": { + "app": "sonarr", + "scheme": "http", + "port": 8989 + }, + "help": "Adres van Sonarr. Laat leeg als je Sonarr niet gebruikt." + }, + { + "name": "sonarr_apikey", + "type": "str", + "title": "Sonarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Sonarr onder Settings → General" + }, + { + "name": "radarr_url", + "type": "str", + "title": "Radarr", + "default": "http://radarr:7878", + "required": false, + "connect": { + "app": "radarr", + "scheme": "http", + "port": 7878 + }, + "help": "Adres van Radarr. Laat leeg als je Radarr niet gebruikt." + }, + { + "name": "radarr_apikey", + "type": "str", + "title": "Radarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Radarr onder Settings → General" + } + ] + }, + { + "title": "Janitorr", + "section": "Opruimen en onderhoud", + "toggle": "enable_janitorr", + "toggle_default": false, + "description": "Ruimt oude media op voordat je schijf volloopt, met regels per bibliotheek.", + "items": [ + { + "name": "port_janitorr", + "type": "int", + "title": "Webinterface", + "default": 8978, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Maintainerr", + "section": "Opruimen en onderhoud", + "toggle": "enable_maintainerr", + "toggle_default": false, + "description": "Ruimt media op volgens regels die je zelf samenstelt, met een voorvertoning van wat er weg zou gaan.", "items": [ { "name": "port_maintainerr", "type": "int", - "title": "Poort", + "title": "Webinterface", "default": 6246, - "required": true + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_maintainerr", - "toggle_default": false, - "description": "Ruimt media op volgens regels die je zelf instelt" + ] }, { - "title": "Huntarr — gaten opvullen", + "title": "NeutArr", + "section": "Opruimen en onderhoud", + "toggle": "enable_neutarr", + "toggle_default": false, + "description": "Zoekt gericht naar ontbrekende afleveringen en naar wat beter kan. Opvolger van Huntarr, dat in februari 2026 offline ging na een reeks lekken; dit is de fork van de laatste schone versie.", "items": [ { - "name": "port_huntarr", + "name": "port_neutarr", + "type": "int", + "title": "Webinterface", + "default": 9705, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Configarr", + "section": "Instellingen synchroniseren", + "toggle": "enable_configarr", + "toggle_default": false, + "description": "Zelfde idee als Recyclarr, maar met eigen aanpassingen bovenop de TRaSH-gidsen.", + "items": [] + }, + { + "title": "Profilarr", + "section": "Instellingen synchroniseren", + "toggle": "enable_profilarr", + "toggle_default": false, + "description": "Beheert kwaliteitsprofielen en custom formats met versiebeheer, en deelt ze tussen instanties.", + "items": [ + { + "name": "port_profilarr", + "type": "int", + "title": "Webinterface", + "default": 6868, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Recyclarr", + "section": "Instellingen synchroniseren", + "toggle": "enable_recyclarr", + "toggle_default": false, + "description": "Zet de kwaliteitsprofielen uit de TRaSH-gidsen in Sonarr en Radarr, en houdt ze bij.", + "items": [] + }, + { + "title": "Kometa", + "section": "Metadata en artwork", + "toggle": "enable_kometa", + "toggle_default": false, + "description": "Bouwt collecties, overlays en metadata op in Plex, Jellyfin of Emby. Voorheen Plex Meta Manager.", + "items": [] + }, + { + "title": "Posterizarr", + "section": "Metadata en artwork", + "toggle": "enable_posterizarr", + "toggle_default": false, + "description": "Maakt automatisch posters en titelkaarten voor je bibliotheek, in een stijl die je zelf instelt.", + "items": [] + }, + { + "title": "Trailarr", + "section": "Metadata en artwork", + "toggle": "enable_trailarr", + "toggle_default": false, + "description": "Haalt trailers op bij de films en series in Radarr en Sonarr, en zet ze naast je media.", + "items": [ + { + "name": "port_trailarr", + "type": "int", + "title": "Webinterface", + "default": 7889, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Autopulse", + "section": "Statistiek en meldingen", + "toggle": "enable_autopulse", + "toggle_default": false, + "description": "Laat Plex of Jellyfin meteen een nieuwe aflevering zien, in plaats van te wachten op de volgende scan.", + "items": [ + { + "name": "port_autopulse", "type": "int", "title": "Poort", - "default": 9705, - "required": true + "default": 2875, + "required": true, + "advanced": true, + "step": "instellingen" } - ], - "toggle": "enable_huntarr", + ] + }, + { + "title": "Exportarr", + "section": "Statistiek en meldingen", + "toggle": "enable_exportarr", "toggle_default": false, - "description": "Zoekt gericht naar ontbrekende en te verbeteren afleveringen" + "description": "Zet de cijfers van één *arr-app om in Prometheus-metrics, zodat je er in Grafana naar kunt kijken.", + "items": [ + { + "name": "port_exportarr", + "type": "int", + "title": "Metrics-poort", + "default": 9707, + "required": true, + "advanced": true, + "step": "instellingen" + }, + { + "name": "arr_soort", + "type": "enum", + "title": "Soort", + "default": "sonarr", + "required": true, + "config": { + "options": [ + "sonarr", + "radarr", + "lidarr", + "readarr", + "prowlarr" + ] + }, + "description": "Eén Exportarr meet één app; draai er meerdere voor meerdere apps" + }, + { + "name": "arr_url", + "type": "str", + "title": "Adres van die app", + "default": "http://sonarr:8989", + "required": true, + "connect": { + "app": "sonarr", + "scheme": "http", + "port": 8989 + }, + "help": "Het adres waarop Exportarr de *arr-app kan bereiken." + }, + { + "name": "arr_apikey", + "type": "str", + "title": "API-sleutel", + "default": "", + "required": true, + "secret": true, + "description": "Te vinden in de app onder Settings → General" + } + ] + }, + { + "title": "Homarr", + "section": "Statistiek en meldingen", + "toggle": "enable_homarr", + "toggle_default": false, + "description": "Startpagina die je *arr-apps, downloadclients en mediaserver op één scherm laat zien, met live cijfers per app.", + "items": [ + { + "name": "port_homarr", + "type": "int", + "title": "Webinterface", + "default": 7575, + "required": true, + "advanced": true, + "step": "instellingen" + }, + { + "name": "homarr_encryption_key", + "type": "str", + "title": "Versleutelingssleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "64 tekens; versleutelt de opgeslagen API-sleutels van je apps" + } + ] + }, + { + "title": "Jellystat", + "section": "Statistiek en meldingen", + "toggle": "enable_jellystat", + "toggle_default": false, + "description": "Kijkstatistieken voor Jellyfin: wie keek wat, hoe lang en hoe vaak. Brengt zijn eigen database mee.", + "items": [ + { + "name": "port_jellystat", + "type": "int", + "title": "Webinterface", + "default": 8118, + "required": true, + "advanced": true, + "step": "instellingen", + "description": "Standaard 3000; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto" + }, + { + "name": "jwt_secret", + "type": "str", + "title": "JWT-sleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Ondertekent de inlogsessies" + } + ] + }, + { + "title": "Notifiarr", + "section": "Statistiek en meldingen", + "toggle": "enable_notifiarr", + "toggle_default": false, + "description": "Stuurt meldingen van je *arr-apps naar Discord, en houdt tegelijk je server in de gaten.", + "items": [ + { + "name": "port_notifiarr", + "type": "int", + "title": "Webinterface", + "default": 5454, + "required": true, + "advanced": true, + "step": "instellingen" + }, + { + "name": "notifiarr_apikey", + "type": "str", + "title": "Notifiarr API-sleutel", + "default": "", + "required": true, + "secret": true, + "description": "Haal je op in je profiel op notifiarr.com" + } + ] + }, + { + "title": "Tautulli", + "section": "Statistiek en meldingen", + "toggle": "enable_tautulli", + "toggle_default": false, + "description": "Laat zien wie wat kijkt op je Plex-server, met grafieken en meldingen.", + "items": [ + { + "name": "port_tautulli", + "type": "int", + "title": "Webinterface", + "default": 8181, + "required": true, + "advanced": true, + "step": "instellingen" + } + ] + }, + { + "title": "Soularr", + "section": "Muziek", + "toggle": "enable_soularr", + "toggle_default": false, + "description": "Laat Lidarr zoeken via Soulseek (slskd) voor albums die op de gewone indexers niet te vinden zijn.", + "items": [] } ] } diff --git a/apps/audiobookshelf/files/compose.yaml b/apps/audiobookshelf/files/compose.yaml index 6219468..458245a 100644 --- a/apps/audiobookshelf/files/compose.yaml +++ b/apps/audiobookshelf/files/compose.yaml @@ -8,6 +8,6 @@ services: - TZ=<< timezone >> volumes: - << media_dir >>:/audiobooks - - << data_dir >>/<< service_name >>/config:/config - - << data_dir >>/<< service_name >>/metadata:/metadata + - << appdata_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/metadata:/metadata restart: unless-stopped diff --git a/apps/audiobookshelf/template.json b/apps/audiobookshelf/template.json index b563aa2..fd8ff90 100644 --- a/apps/audiobookshelf/template.json +++ b/apps/audiobookshelf/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/authelia/files/compose.yaml b/apps/authelia/files/compose.yaml index 5be34dc..98d5b92 100644 --- a/apps/authelia/files/compose.yaml +++ b/apps/authelia/files/compose.yaml @@ -11,5 +11,5 @@ services: - AUTHELIA_STORAGE_ENCRYPTION_KEY=<< storage_key >> volumes: # Zet hier configuration.yml en users_database.yml neer voor de eerste start. - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config restart: unless-stopped diff --git a/apps/authelia/template.json b/apps/authelia/template.json index c5f0ab0..efa971d 100644 --- a/apps/authelia/template.json +++ b/apps/authelia/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/autopulse/files/compose.yaml b/apps/autopulse/files/compose.yaml new file mode 100644 index 0000000..7075b42 --- /dev/null +++ b/apps/autopulse/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/dan-online/autopulse:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/config + ports: + - "<< port >>:2875" + restart: unless-stopped diff --git a/apps/autopulse/template.json b/apps/autopulse/template.json new file mode 100644 index 0000000..f1e6b6f --- /dev/null +++ b/apps/autopulse/template.json @@ -0,0 +1,57 @@ +{ + "kind": "compose", + "metadata": { + "name": "Autopulse", + "description": "Laat Plex of Jellyfin meteen een nieuwe aflevering zien, in plaats van te wachten op de volgende scan.", + "tags": [ + "media", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "autopulse" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "autopulse", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Poort", + "default": 2875, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/baby-buddy/files/compose.yaml b/apps/baby-buddy/files/compose.yaml index f0bd466..04b966f 100644 --- a/apps/baby-buddy/files/compose.yaml +++ b/apps/baby-buddy/files/compose.yaml @@ -12,5 +12,5 @@ services: - ALLOWED_HOSTS=<< allowed_hosts >> - CSRF_TRUSTED_ORIGINS=http://<< allowed_hosts >> volumes: - - << data_dir >>/<< service_name >>/config:/app/data + - << appdata_dir >>/<< service_name >>/config:/app/data restart: unless-stopped diff --git a/apps/baby-buddy/template.json b/apps/baby-buddy/template.json index d7d6b69..0969fd3 100644 --- a/apps/baby-buddy/template.json +++ b/apps/baby-buddy/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/bambuddy/files/compose.yaml b/apps/bambuddy/files/compose.yaml index 79a59e8..96507dc 100644 --- a/apps/bambuddy/files/compose.yaml +++ b/apps/bambuddy/files/compose.yaml @@ -10,8 +10,8 @@ services: - PGID=<< pgid >> - PORT=8000 volumes: - - << data_dir >>/<< service_name >>/data:/app/data - - << data_dir >>/<< service_name >>/logs:/app/logs + - << appdata_dir >>/<< service_name >>/data:/app/data + - << appdata_dir >>/<< service_name >>/logs:/app/logs cap_add: - NET_BIND_SERVICE stop_grace_period: 30s diff --git a/apps/bambuddy/template.json b/apps/bambuddy/template.json index 427984e..f45b78d 100644 --- a/apps/bambuddy/template.json +++ b/apps/bambuddy/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/baserow/files/compose.yaml b/apps/baserow/files/compose.yaml index 29b2c04..9dde49b 100644 --- a/apps/baserow/files/compose.yaml +++ b/apps/baserow/files/compose.yaml @@ -8,5 +8,5 @@ services: - TZ=<< timezone >> - BASEROW_PUBLIC_URL=<< public_url >> volumes: - - << data_dir >>/<< service_name >>:/baserow/data + - << appdata_dir >>/<< service_name >>:/baserow/data restart: unless-stopped diff --git a/apps/baserow/template.json b/apps/baserow/template.json index 3b3a23f..c623747 100644 --- a/apps/baserow/template.json +++ b/apps/baserow/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/bazarr/files/compose.yaml b/apps/bazarr/files/compose.yaml new file mode 100644 index 0000000..df7abcb --- /dev/null +++ b/apps/bazarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/bazarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:6767" + restart: unless-stopped diff --git a/apps/bazarr/template.json b/apps/bazarr/template.json new file mode 100644 index 0000000..00f86b9 --- /dev/null +++ b/apps/bazarr/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "Bazarr", + "description": "Zoekt en downloadt ondertitels bij wat Sonarr en Radarr al hebben binnengehaald.", + "tags": [ + "media", + "ondertitels" + ], + "icon": { + "provider": "selfhst", + "id": "bazarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "bazarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 6767, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/beszel/files/compose.yaml b/apps/beszel/files/compose.yaml index 3b124fa..4132674 100644 --- a/apps/beszel/files/compose.yaml +++ b/apps/beszel/files/compose.yaml @@ -7,7 +7,7 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/data:/beszel_data + - << appdata_dir >>/<< service_name >>/data:/beszel_data restart: unless-stopped << service_name >>-agent: diff --git a/apps/beszel/template.json b/apps/beszel/template.json index 75bc0eb..797399c 100644 --- a/apps/beszel/template.json +++ b/apps/beszel/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/bookstack/files/compose.yaml b/apps/bookstack/files/compose.yaml index aaa7e09..8b88862 100644 --- a/apps/bookstack/files/compose.yaml +++ b/apps/bookstack/files/compose.yaml @@ -15,7 +15,7 @@ services: - DB_PASSWORD=<< db_password >> - DB_DATABASE=bookstack volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config depends_on: - << service_name >>-db restart: unless-stopped @@ -32,5 +32,5 @@ services: - MYSQL_USER=bookstack - MYSQL_PASSWORD=<< db_password >> volumes: - - << data_dir >>/<< service_name >>/db:/config + - << appdata_dir >>/<< service_name >>/db:/config restart: unless-stopped diff --git a/apps/bookstack/template.json b/apps/bookstack/template.json index 974791b..f14dfb0 100644 --- a/apps/bookstack/template.json +++ b/apps/bookstack/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/byparr/files/compose.yaml b/apps/byparr/files/compose.yaml new file mode 100644 index 0000000..45f59f9 --- /dev/null +++ b/apps/byparr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/thephaseless/byparr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:8191" + restart: unless-stopped diff --git a/apps/byparr/template.json b/apps/byparr/template.json new file mode 100644 index 0000000..8793373 --- /dev/null +++ b/apps/byparr/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Byparr", + "description": "Nieuwer alternatief voor FlareSolverr, gebouwd op SeleniumBase. Spreekt dezelfde API, dus je kunt het er zo voor in de plaats zetten.", + "tags": [ + "indexers", + "downloaden", + "proxy" + ], + "icon": { + "provider": "selfhst", + "id": "byparr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "byparr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Poort", + "default": 8119, + "required": true, + "description": "Byparr luistert intern op 8191, net als FlareSolverr" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/caddy/files/compose.yaml b/apps/caddy/files/compose.yaml index 9284546..b686db7 100644 --- a/apps/caddy/files/compose.yaml +++ b/apps/caddy/files/compose.yaml @@ -10,7 +10,7 @@ services: - TZ=<< timezone >> volumes: # Zet hier je Caddyfile neer; Caddy regelt de certificaten daarna zelf. - - << data_dir >>/<< service_name >>/Caddyfile:/etc/caddy/Caddyfile + - << appdata_dir >>/<< service_name >>/Caddyfile:/etc/caddy/Caddyfile - << service_name >>_data:/data - << service_name >>_config:/config restart: unless-stopped diff --git a/apps/caddy/template.json b/apps/caddy/template.json index cdd2a77..2c94e65 100644 --- a/apps/caddy/template.json +++ b/apps/caddy/template.json @@ -40,9 +40,9 @@ "help": "Caddy vraagt zelf certificaten aan bij Let's Encrypt en heeft daarvoor poort 80 nodig, ook als je alles via HTTPS aanbiedt." }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/calibre-web/files/compose.yaml b/apps/calibre-web/files/compose.yaml index a55ede0..c903167 100644 --- a/apps/calibre-web/files/compose.yaml +++ b/apps/calibre-web/files/compose.yaml @@ -9,6 +9,6 @@ services: - PUID=<< puid >> - PGID=<< pgid >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - << books_dir >>:/books restart: unless-stopped diff --git a/apps/calibre-web/template.json b/apps/calibre-web/template.json index 1ea48eb..09cc00b 100644 --- a/apps/calibre-web/template.json +++ b/apps/calibre-web/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/changedetection-io/files/compose.yaml b/apps/changedetection-io/files/compose.yaml index 4b62e89..378a71d 100644 --- a/apps/changedetection-io/files/compose.yaml +++ b/apps/changedetection-io/files/compose.yaml @@ -9,5 +9,5 @@ services: - CHANGEDETECTION_PASSWORD=<< password >> <% endif %> volumes: - - << data_dir >>/<< service_name >>/data:/datastore + - << appdata_dir >>/<< service_name >>/data:/datastore restart: unless-stopped diff --git a/apps/changedetection-io/template.json b/apps/changedetection-io/template.json index 0f625a3..33ed56c 100644 --- a/apps/changedetection-io/template.json +++ b/apps/changedetection-io/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/cleanuparr/files/compose.yaml b/apps/cleanuparr/files/compose.yaml new file mode 100644 index 0000000..0721040 --- /dev/null +++ b/apps/cleanuparr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: ghcr.io/cleanuparr/cleanuparr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:11011" + restart: unless-stopped diff --git a/apps/cleanuparr/template.json b/apps/cleanuparr/template.json new file mode 100644 index 0000000..6635bca --- /dev/null +++ b/apps/cleanuparr/template.json @@ -0,0 +1,67 @@ +{ + "kind": "compose", + "metadata": { + "name": "Cleanuparr", + "description": "Ruimt dode en kwaadaardige torrents op, en downloads waar niemand meer naar verwijst.", + "tags": [ + "downloaden", + "onderhoud" + ], + "icon": { + "provider": "selfhst", + "id": "cleanuparr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "cleanuparr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 11011, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/configarr/files/compose.yaml b/apps/configarr/files/compose.yaml new file mode 100644 index 0000000..47be1ba --- /dev/null +++ b/apps/configarr/files/compose.yaml @@ -0,0 +1,9 @@ +services: + << service_name >>: + image: ghcr.io/raydak-labs/configarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/config + restart: unless-stopped diff --git a/apps/configarr/template.json b/apps/configarr/template.json new file mode 100644 index 0000000..5fbfdab --- /dev/null +++ b/apps/configarr/template.json @@ -0,0 +1,51 @@ +{ + "kind": "compose", + "metadata": { + "name": "Configarr", + "description": "Zelfde idee als Recyclarr, maar met eigen aanpassingen bovenop de TRaSH-gidsen.", + "tags": [ + "media", + "configuratie" + ], + "icon": { + "provider": "selfhst", + "id": "configarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "configarr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/cross-seed/files/compose.yaml b/apps/cross-seed/files/compose.yaml new file mode 100644 index 0000000..360681e --- /dev/null +++ b/apps/cross-seed/files/compose.yaml @@ -0,0 +1,13 @@ +services: + << service_name >>: + image: ghcr.io/cross-seed/cross-seed:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + command: daemon + ports: + - "<< port >>:2468" + restart: unless-stopped diff --git a/apps/cross-seed/template.json b/apps/cross-seed/template.json new file mode 100644 index 0000000..9ee1a40 --- /dev/null +++ b/apps/cross-seed/template.json @@ -0,0 +1,66 @@ +{ + "kind": "compose", + "metadata": { + "name": "cross-seed", + "description": "Zoekt dezelfde bestanden bij andere trackers, zodat je één download op meerdere plekken kunt seeden.", + "tags": [ + "torrents", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "cross-seed" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "crossseed", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Poort", + "default": 2468, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/decluttarr/files/compose.yaml b/apps/decluttarr/files/compose.yaml new file mode 100644 index 0000000..7be6b23 --- /dev/null +++ b/apps/decluttarr/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: ghcr.io/manimatter/decluttarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - SONARR_URL=<< sonarr_url >> + - SONARR_KEY=<< sonarr_apikey >> + - RADARR_URL=<< radarr_url >> + - RADARR_KEY=<< radarr_apikey >> + - LOG_LEVEL=INFO + volumes: + - << appdata_dir >>/<< service_name >>:/config + restart: unless-stopped diff --git a/apps/decluttarr/template.json b/apps/decluttarr/template.json new file mode 100644 index 0000000..07b5542 --- /dev/null +++ b/apps/decluttarr/template.json @@ -0,0 +1,100 @@ +{ + "kind": "compose", + "metadata": { + "name": "Decluttarr", + "description": "Houdt de downloadwachtrij schoon: gooit weg wat vastloopt of niet meer nodig is.", + "tags": [ + "downloaden", + "onderhoud" + ], + "icon": { + "provider": "selfhst", + "id": "decluttarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "decluttarr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Koppelingen", + "items": [ + { + "name": "sonarr_url", + "type": "str", + "title": "Sonarr", + "default": "http://sonarr:8989", + "required": false, + "connect": { + "app": "sonarr", + "scheme": "http", + "port": 8989 + }, + "help": "Adres van Sonarr. Laat leeg als je Sonarr niet gebruikt." + }, + { + "name": "sonarr_apikey", + "type": "str", + "title": "Sonarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Sonarr onder Settings → General" + }, + { + "name": "radarr_url", + "type": "str", + "title": "Radarr", + "default": "http://radarr:7878", + "required": false, + "connect": { + "app": "radarr", + "scheme": "http", + "port": 7878 + }, + "help": "Adres van Radarr. Laat leeg als je Radarr niet gebruikt." + }, + { + "name": "radarr_apikey", + "type": "str", + "title": "Radarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Radarr onder Settings → General" + } + ] + } + ] +} diff --git a/apps/deluge/files/compose.yaml b/apps/deluge/files/compose.yaml new file mode 100644 index 0000000..4e1ce13 --- /dev/null +++ b/apps/deluge/files/compose.yaml @@ -0,0 +1,17 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/deluge:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:8112" + - "<< port_torrent >>:6881" + - "<< port_torrent >>:6881/udp" + restart: unless-stopped diff --git a/apps/deluge/template.json b/apps/deluge/template.json new file mode 100644 index 0000000..84f9b37 --- /dev/null +++ b/apps/deluge/template.json @@ -0,0 +1,95 @@ +{ + "kind": "compose", + "metadata": { + "name": "Deluge", + "description": "Lichte torrentclient met webinterface en een uitgebreid plugin-systeem.", + "tags": [ + "torrents", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "deluge" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "deluge", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8113, + "required": true, + "description": "Standaard 8112; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "port_torrent", + "type": "int", + "title": "Inkomende poort", + "default": 6882, + "required": true, + "description": "Zet deze poort open in je router voor betere snelheden" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/duplicati/files/compose.yaml b/apps/duplicati/files/compose.yaml index 15f0903..6478e1d 100644 --- a/apps/duplicati/files/compose.yaml +++ b/apps/duplicati/files/compose.yaml @@ -9,7 +9,7 @@ services: - PUID=<< puid >> - PGID=<< pgid >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - << source_dir >>:/source:ro - << backup_dir >>:/backups restart: unless-stopped diff --git a/apps/duplicati/template.json b/apps/duplicati/template.json index 187f6cf..bf28b36 100644 --- a/apps/duplicati/template.json +++ b/apps/duplicati/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/esphome/files/compose.yaml b/apps/esphome/files/compose.yaml index 8ed9a23..fc98e02 100644 --- a/apps/esphome/files/compose.yaml +++ b/apps/esphome/files/compose.yaml @@ -7,6 +7,6 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - /etc/localtime:/etc/localtime:ro restart: unless-stopped diff --git a/apps/esphome/template.json b/apps/esphome/template.json index 40688ef..0ab89ef 100644 --- a/apps/esphome/template.json +++ b/apps/esphome/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/exportarr/files/compose.yaml b/apps/exportarr/files/compose.yaml new file mode 100644 index 0000000..d6c26ef --- /dev/null +++ b/apps/exportarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: ghcr.io/onedr0p/exportarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - URL=<< arr_url >> + - APIKEY=<< arr_apikey >> + - PORT=<< port >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + command: << arr_soort >> + ports: + - "<< port >>:9707" + restart: unless-stopped diff --git a/apps/exportarr/template.json b/apps/exportarr/template.json new file mode 100644 index 0000000..d5071be --- /dev/null +++ b/apps/exportarr/template.json @@ -0,0 +1,101 @@ +{ + "kind": "compose", + "metadata": { + "name": "Exportarr", + "description": "Zet de cijfers van één *arr-app om in Prometheus-metrics, zodat je er in Grafana naar kunt kijken.", + "tags": [ + "monitoring", + "metrics" + ], + "icon": { + "provider": "selfhst", + "id": "prometheus" + }, + "version": { + "name": "latest" + }, + "categories": [ + "monitoring" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "exportarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Metrics-poort", + "default": 9707, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Welke app meten we?", + "items": [ + { + "name": "arr_soort", + "type": "enum", + "title": "Soort", + "default": "sonarr", + "required": true, + "config": { + "options": [ + "sonarr", + "radarr", + "lidarr", + "readarr", + "prowlarr" + ] + }, + "description": "Eén Exportarr meet één app; draai er meerdere voor meerdere apps" + }, + { + "name": "arr_url", + "type": "str", + "title": "Adres van die app", + "default": "http://sonarr:8989", + "required": true, + "connect": { + "app": "sonarr", + "scheme": "http", + "port": 8989 + }, + "help": "Het adres waarop Exportarr de *arr-app kan bereiken." + }, + { + "name": "arr_apikey", + "type": "str", + "title": "API-sleutel", + "default": "", + "required": true, + "secret": true, + "description": "Te vinden in de app onder Settings → General" + } + ] + } + ] +} diff --git a/apps/filebrowser/files/compose.yaml b/apps/filebrowser/files/compose.yaml index 094140c..722ab36 100644 --- a/apps/filebrowser/files/compose.yaml +++ b/apps/filebrowser/files/compose.yaml @@ -6,6 +6,6 @@ services: - "<< port >>:80" volumes: - << files_dir >>:/srv - - << data_dir >>/<< service_name >>/filebrowser.db:/database/filebrowser.db - - << data_dir >>/<< service_name >>/.filebrowser.json:/.filebrowser.json + - << appdata_dir >>/<< service_name >>/filebrowser.db:/database/filebrowser.db + - << appdata_dir >>/<< service_name >>/.filebrowser.json:/.filebrowser.json restart: unless-stopped diff --git a/apps/filebrowser/template.json b/apps/filebrowser/template.json index 0d2a01a..865d69c 100644 --- a/apps/filebrowser/template.json +++ b/apps/filebrowser/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Map voor configuratie en database" diff --git a/apps/firefly-iii/files/compose.yaml b/apps/firefly-iii/files/compose.yaml index 7d5c49c..a5fde10 100644 --- a/apps/firefly-iii/files/compose.yaml +++ b/apps/firefly-iii/files/compose.yaml @@ -14,7 +14,7 @@ services: - DB_USERNAME=firefly - DB_PASSWORD=<< db_password >> volumes: - - << data_dir >>/<< service_name >>/upload:/var/www/html/storage/upload + - << appdata_dir >>/<< service_name >>/upload:/var/www/html/storage/upload depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/firefly-iii/template.json b/apps/firefly-iii/template.json index a2d42c0..90896a7 100644 --- a/apps/firefly-iii/template.json +++ b/apps/firefly-iii/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/flaresolverr/files/compose.yaml b/apps/flaresolverr/files/compose.yaml new file mode 100644 index 0000000..6192997 --- /dev/null +++ b/apps/flaresolverr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: ghcr.io/flaresolverr/flaresolverr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - LOG_LEVEL=info + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:8191" + restart: unless-stopped diff --git a/apps/flaresolverr/template.json b/apps/flaresolverr/template.json new file mode 100644 index 0000000..aea637e --- /dev/null +++ b/apps/flaresolverr/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "FlareSolverr", + "description": "Haalt pagina's op die achter een Cloudflare-controle zitten, zodat je indexers er alsnog bij kunnen.", + "tags": [ + "indexers", + "downloaden", + "proxy" + ], + "icon": { + "provider": "selfhst", + "id": "flaresolverr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "flaresolverr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Poort", + "default": 8191, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/focalboard/files/compose.yaml b/apps/focalboard/files/compose.yaml index a9cab86..48e10a8 100644 --- a/apps/focalboard/files/compose.yaml +++ b/apps/focalboard/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>:/opt/focalboard/data + - << appdata_dir >>/<< service_name >>:/opt/focalboard/data restart: unless-stopped diff --git a/apps/focalboard/template.json b/apps/focalboard/template.json index e906d08..c26c728 100644 --- a/apps/focalboard/template.json +++ b/apps/focalboard/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/forgejo/files/compose.yaml b/apps/forgejo/files/compose.yaml index f19ac12..6d96d0a 100644 --- a/apps/forgejo/files/compose.yaml +++ b/apps/forgejo/files/compose.yaml @@ -11,7 +11,7 @@ services: - FORGEJO__server__SSH_PORT=<< port_ssh >> - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro restart: unless-stopped diff --git a/apps/forgejo/template.json b/apps/forgejo/template.json index 2a656bf..3c2b70a 100644 --- a/apps/forgejo/template.json +++ b/apps/forgejo/template.json @@ -32,9 +32,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/freshrss/files/compose.yaml b/apps/freshrss/files/compose.yaml index f9bb928..280a660 100644 --- a/apps/freshrss/files/compose.yaml +++ b/apps/freshrss/files/compose.yaml @@ -8,6 +8,6 @@ services: - TZ=<< timezone >> - CRON_MIN=*/20 volumes: - - << data_dir >>/<< service_name >>/data:/var/www/FreshRSS/data - - << data_dir >>/<< service_name >>/extensions:/var/www/FreshRSS/extensions + - << appdata_dir >>/<< service_name >>/data:/var/www/FreshRSS/data + - << appdata_dir >>/<< service_name >>/extensions:/var/www/FreshRSS/extensions restart: unless-stopped diff --git a/apps/freshrss/template.json b/apps/freshrss/template.json index 384902d..f7e2b84 100644 --- a/apps/freshrss/template.json +++ b/apps/freshrss/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/frigate/files/compose.yaml b/apps/frigate/files/compose.yaml index 0f830f3..ae96501 100644 --- a/apps/frigate/files/compose.yaml +++ b/apps/frigate/files/compose.yaml @@ -9,8 +9,8 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/config - - << data_dir >>/<< service_name >>/media:/media/frigate + - << appdata_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/media:/media/frigate - /etc/localtime:/etc/localtime:ro # Opnamebuffer in geheugen; voorkomt slijtage van je SSD - type: tmpfs diff --git a/apps/frigate/template.json b/apps/frigate/template.json index 04ef78c..ddb61d5 100644 --- a/apps/frigate/template.json +++ b/apps/frigate/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/ghost/files/compose.yaml b/apps/ghost/files/compose.yaml index dc0cbda..ed47540 100644 --- a/apps/ghost/files/compose.yaml +++ b/apps/ghost/files/compose.yaml @@ -24,7 +24,7 @@ services: - database__connection__password=<< db_password >> - database__connection__database=ghost volumes: - - << data_dir >>/<< service_name >>/content:/var/lib/ghost/content + - << appdata_dir >>/<< service_name >>/content:/var/lib/ghost/content depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/ghost/template.json b/apps/ghost/template.json index dfc2ecd..26f8c8f 100644 --- a/apps/ghost/template.json +++ b/apps/ghost/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/gluetun/files/compose.yaml b/apps/gluetun/files/compose.yaml new file mode 100644 index 0000000..9a48ce7 --- /dev/null +++ b/apps/gluetun/files/compose.yaml @@ -0,0 +1,20 @@ +services: + << service_name >>: + image: qmcgaw/gluetun:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - VPN_SERVICE_PROVIDER=<< vpn_provider >> + - VPN_TYPE=<< vpn_type >> + - SERVER_COUNTRIES=<< vpn_landen >> + - WIREGUARD_PRIVATE_KEY=<< wireguard_private_key >> + - WIREGUARD_ADDRESSES=<< wireguard_addresses >> + - OPENVPN_USER=<< openvpn_user >> + - OPENVPN_PASSWORD=<< openvpn_password >> + volumes: + - << appdata_dir >>/<< service_name >>:/gluetun + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun:/dev/net/tun + restart: unless-stopped diff --git a/apps/gluetun/template.json b/apps/gluetun/template.json new file mode 100644 index 0000000..161f2d6 --- /dev/null +++ b/apps/gluetun/template.json @@ -0,0 +1,146 @@ +{ + "kind": "compose", + "metadata": { + "name": "Gluetun", + "description": "VPN-container waar je andere containers doorheen laat lopen. Zet je downloadclient erachter met `network_mode: service:gluetun`.", + "tags": [ + "vpn", + "netwerk", + "privacy" + ], + "icon": { + "provider": "selfhst", + "id": "gluetun" + }, + "version": { + "name": "latest" + }, + "categories": [ + "netwerk", + "beveiliging" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "gluetun", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "VPN", + "items": [ + { + "name": "vpn_provider", + "type": "str", + "title": "VPN-aanbieder", + "default": "mullvad", + "required": true, + "description": "Bijvoorbeeld mullvad, nordvpn, protonvpn, airvpn of surfshark" + }, + { + "name": "vpn_type", + "type": "enum", + "title": "Protocol", + "default": "wireguard", + "required": true, + "config": { + "options": [ + "wireguard", + "openvpn" + ] + } + }, + { + "name": "vpn_landen", + "type": "str", + "title": "Landen", + "default": "Netherlands", + "required": false, + "description": "Komma-gescheiden; leeg laten kiest willekeurig" + }, + { + "name": "wireguard_private_key", + "type": "str", + "title": "WireGuard privésleutel", + "default": "", + "required": false, + "secret": true, + "needs": [ + { + "name": "vpn_type", + "value": "wireguard" + } + ], + "config": { + "placeholder": "alleen bij wireguard" + } + }, + { + "name": "wireguard_addresses", + "type": "str", + "title": "WireGuard adressen", + "default": "", + "required": false, + "needs": [ + { + "name": "vpn_type", + "value": "wireguard" + } + ], + "config": { + "placeholder": "10.64.0.2/32" + } + }, + { + "name": "openvpn_user", + "type": "str", + "title": "OpenVPN gebruiker", + "default": "", + "required": false, + "needs": [ + { + "name": "vpn_type", + "value": "openvpn" + } + ] + }, + { + "name": "openvpn_password", + "type": "str", + "title": "OpenVPN wachtwoord", + "default": "", + "required": false, + "secret": true, + "needs": [ + { + "name": "vpn_type", + "value": "openvpn" + } + ] + } + ] + } + ] +} diff --git a/apps/gotify/files/compose.yaml b/apps/gotify/files/compose.yaml index 3fb902b..34743b8 100644 --- a/apps/gotify/files/compose.yaml +++ b/apps/gotify/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - GOTIFY_DEFAULTUSER_PASS=<< default_password >> volumes: - - << data_dir >>/<< service_name >>/data:/app/data + - << appdata_dir >>/<< service_name >>/data:/app/data restart: unless-stopped diff --git a/apps/gotify/template.json b/apps/gotify/template.json index 47bb9b4..b2a7481 100644 --- a/apps/gotify/template.json +++ b/apps/gotify/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/grafana/files/compose.yaml b/apps/grafana/files/compose.yaml index 21c677b..30ac33f 100644 --- a/apps/grafana/files/compose.yaml +++ b/apps/grafana/files/compose.yaml @@ -8,5 +8,5 @@ services: - GF_SECURITY_ADMIN_USER=<< admin_user >> - GF_SECURITY_ADMIN_PASSWORD=<< admin_password >> volumes: - - << data_dir >>/<< service_name >>/data:/var/lib/grafana + - << appdata_dir >>/<< service_name >>/data:/var/lib/grafana restart: unless-stopped diff --git a/apps/grafana/template.json b/apps/grafana/template.json index 2dab580..36ab151 100644 --- a/apps/grafana/template.json +++ b/apps/grafana/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/grocy/files/compose.yaml b/apps/grocy/files/compose.yaml index 05b9516..d22f5be 100644 --- a/apps/grocy/files/compose.yaml +++ b/apps/grocy/files/compose.yaml @@ -9,5 +9,5 @@ services: - PUID=<< puid >> - PGID=<< pgid >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config restart: unless-stopped diff --git a/apps/grocy/template.json b/apps/grocy/template.json index f486ce3..65e515f 100644 --- a/apps/grocy/template.json +++ b/apps/grocy/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/hedgedoc/files/compose.yaml b/apps/hedgedoc/files/compose.yaml index 924350a..bbe59ef 100644 --- a/apps/hedgedoc/files/compose.yaml +++ b/apps/hedgedoc/files/compose.yaml @@ -11,7 +11,7 @@ services: - CMD_URL_ADDPORT=false - CMD_ALLOW_ANONYMOUS=false volumes: - - << data_dir >>/<< service_name >>/uploads:/hedgedoc/public/uploads + - << appdata_dir >>/<< service_name >>/uploads:/hedgedoc/public/uploads depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/hedgedoc/template.json b/apps/hedgedoc/template.json index bf9dff5..9ce3bf2 100644 --- a/apps/hedgedoc/template.json +++ b/apps/hedgedoc/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/homarr/files/compose.yaml b/apps/homarr/files/compose.yaml new file mode 100644 index 0000000..af6505d --- /dev/null +++ b/apps/homarr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: ghcr.io/homarr-labs/homarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - SECRET_ENCRYPTION_KEY=<< homarr_encryption_key >> + volumes: + - << appdata_dir >>/<< service_name >>:/appdata + ports: + - "<< port >>:7575" + restart: unless-stopped diff --git a/apps/homarr/template.json b/apps/homarr/template.json new file mode 100644 index 0000000..9d96e2e --- /dev/null +++ b/apps/homarr/template.json @@ -0,0 +1,72 @@ +{ + "kind": "compose", + "metadata": { + "name": "Homarr", + "description": "Startpagina die je *arr-apps, downloadclients en mediaserver op één scherm laat zien, met live cijfers per app.", + "tags": [ + "dashboard", + "overzicht" + ], + "icon": { + "provider": "selfhst", + "id": "homarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "homarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 7575, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "homarr_encryption_key", + "type": "str", + "title": "Versleutelingssleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "64 tekens; versleutelt de opgeslagen API-sleutels van je apps" + } + ] + } + ] +} diff --git a/apps/home-assistant/files/compose.yaml b/apps/home-assistant/files/compose.yaml index b589f38..6820af8 100644 --- a/apps/home-assistant/files/compose.yaml +++ b/apps/home-assistant/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config restart: unless-stopped diff --git a/apps/home-assistant/template.json b/apps/home-assistant/template.json index d09d334..fbaf6eb 100644 --- a/apps/home-assistant/template.json +++ b/apps/home-assistant/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/homeassistant-mcp/files/compose.yaml b/apps/homeassistant-mcp/files/compose.yaml index 274010b..4d7787b 100644 --- a/apps/homeassistant-mcp/files/compose.yaml +++ b/apps/homeassistant-mcp/files/compose.yaml @@ -12,5 +12,5 @@ services: - PORT=3000 - NODE_ENV=production volumes: - - << data_dir >>/<< service_name >>:/app/data + - << appdata_dir >>/<< service_name >>:/app/data restart: unless-stopped diff --git a/apps/homeassistant-mcp/template.json b/apps/homeassistant-mcp/template.json index 205342a..2efd615 100644 --- a/apps/homeassistant-mcp/template.json +++ b/apps/homeassistant-mcp/template.json @@ -42,9 +42,9 @@ "description": "Poort waarop de MCP-server bereikbaar is" }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/homebridge/files/compose.yaml b/apps/homebridge/files/compose.yaml index 85a9bb4..9ed99d9 100644 --- a/apps/homebridge/files/compose.yaml +++ b/apps/homebridge/files/compose.yaml @@ -9,5 +9,5 @@ services: - TZ=<< timezone >> - HOMEBRIDGE_CONFIG_UI_PORT=<< port >> volumes: - - << data_dir >>/<< service_name >>:/homebridge + - << appdata_dir >>/<< service_name >>:/homebridge restart: unless-stopped diff --git a/apps/homebridge/template.json b/apps/homebridge/template.json index 90e8a35..42820ef 100644 --- a/apps/homebridge/template.json +++ b/apps/homebridge/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/homepage/files/compose.yaml b/apps/homepage/files/compose.yaml index 80b5a25..609ec96 100644 --- a/apps/homepage/files/compose.yaml +++ b/apps/homepage/files/compose.yaml @@ -8,7 +8,7 @@ services: - TZ=<< timezone >> - HOMEPAGE_ALLOWED_HOSTS=<< allowed_hosts >> volumes: - - << data_dir >>/<< service_name >>/config:/app/config + - << appdata_dir >>/<< service_name >>/config:/app/config # Alleen-lezen socket voor de Docker-widget die containers toont - /var/run/docker.sock:/var/run/docker.sock:ro restart: unless-stopped diff --git a/apps/homepage/template.json b/apps/homepage/template.json index b76127e..f9e3518 100644 --- a/apps/homepage/template.json +++ b/apps/homepage/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/immich/files/compose.yaml b/apps/immich/files/compose.yaml index 58cbca4..7b45746 100644 --- a/apps/immich/files/compose.yaml +++ b/apps/immich/files/compose.yaml @@ -12,7 +12,7 @@ services: - REDIS_HOSTNAME=<< service_name >>-redis - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/upload:/usr/src/app/upload + - << appdata_dir >>/<< service_name >>/upload:/usr/src/app/upload depends_on: - << service_name >>-redis - << service_name >>-postgres diff --git a/apps/immich/template.json b/apps/immich/template.json index bd997e9..4baaf75 100644 --- a/apps/immich/template.json +++ b/apps/immich/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Upload directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Basismap voor foto-uploads en database", diff --git a/apps/influxdb/files/compose.yaml b/apps/influxdb/files/compose.yaml index db28bc9..3ead45f 100644 --- a/apps/influxdb/files/compose.yaml +++ b/apps/influxdb/files/compose.yaml @@ -12,6 +12,6 @@ services: - DOCKER_INFLUXDB_INIT_ORG=<< org >> - DOCKER_INFLUXDB_INIT_BUCKET=<< bucket >> volumes: - - << data_dir >>/<< service_name >>/data:/var/lib/influxdb2 - - << data_dir >>/<< service_name >>/config:/etc/influxdb2 + - << appdata_dir >>/<< service_name >>/data:/var/lib/influxdb2 + - << appdata_dir >>/<< service_name >>/config:/etc/influxdb2 restart: unless-stopped diff --git a/apps/influxdb/template.json b/apps/influxdb/template.json index 8e3d5e2..5329abc 100644 --- a/apps/influxdb/template.json +++ b/apps/influxdb/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/jackett/files/compose.yaml b/apps/jackett/files/compose.yaml new file mode 100644 index 0000000..fd2ec92 --- /dev/null +++ b/apps/jackett/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/jackett:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:9117" + restart: unless-stopped diff --git a/apps/jackett/template.json b/apps/jackett/template.json new file mode 100644 index 0000000..24d7b1b --- /dev/null +++ b/apps/jackett/template.json @@ -0,0 +1,78 @@ +{ + "kind": "compose", + "metadata": { + "name": "Jackett", + "description": "Vertaalt trackers naar één API voor je *arr-apps. Ouder alternatief voor Prowlarr; meestal heb je er maar één nodig.", + "tags": [ + "media", + "indexers", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "jackett" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "jackett", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 9117, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/janitorr/files/compose.yaml b/apps/janitorr/files/compose.yaml new file mode 100644 index 0000000..693195d --- /dev/null +++ b/apps/janitorr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: ghcr.io/schaka/janitorr:native-stable + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:8978" + restart: unless-stopped diff --git a/apps/janitorr/template.json b/apps/janitorr/template.json new file mode 100644 index 0000000..c9952ca --- /dev/null +++ b/apps/janitorr/template.json @@ -0,0 +1,68 @@ +{ + "kind": "compose", + "metadata": { + "name": "Janitorr", + "description": "Ruimt oude media op voordat je schijf volloopt, met regels per bibliotheek.", + "tags": [ + "media", + "opruimen", + "opslag" + ], + "icon": { + "provider": "selfhst", + "id": "janitorr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "opslag" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "janitorr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8978, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/jellyfin/files/compose.yaml b/apps/jellyfin/files/compose.yaml index 97f30fc..5d64d87 100644 --- a/apps/jellyfin/files/compose.yaml +++ b/apps/jellyfin/files/compose.yaml @@ -7,7 +7,9 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/config - - << data_dir >>/<< service_name >>/cache:/cache - - << media_dir >>:/media:ro + - << appdata_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/cache:/cache + # Alleen de bibliotheek, alleen-lezen: een mediaserver hoeft niet bij je + # downloads te kunnen en hoeft er zeker niets in te schrijven. + - << data_root >>/media:/data/media:ro restart: unless-stopped diff --git a/apps/jellyfin/template.json b/apps/jellyfin/template.json index b8482ec..e5fa8ca 100644 --- a/apps/jellyfin/template.json +++ b/apps/jellyfin/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Basismap voor configuratie en cache" @@ -59,12 +59,13 @@ "title": "Media", "items": [ { - "name": "media_dir", + "name": "data_root", "type": "str", - "title": "Media directory", - "default": "/mnt/media", + "title": "Gedeelde datamap", + "default": "/mnt/data", "required": true, - "description": "Map met je films, series en muziek (wordt read-only gemount)" + "description": "Je media staat onder /data/media en wordt alleen-lezen gekoppeld", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." } ] } diff --git a/apps/jellyseerr/files/compose.yaml b/apps/jellyseerr/files/compose.yaml index fdccca4..95ed65f 100644 --- a/apps/jellyseerr/files/compose.yaml +++ b/apps/jellyseerr/files/compose.yaml @@ -8,5 +8,5 @@ services: - TZ=<< timezone >> - LOG_LEVEL=info volumes: - - << data_dir >>/<< service_name >>/config:/app/config + - << appdata_dir >>/<< service_name >>/config:/app/config restart: unless-stopped diff --git a/apps/jellyseerr/template.json b/apps/jellyseerr/template.json index 1226c06..f36703b 100644 --- a/apps/jellyseerr/template.json +++ b/apps/jellyseerr/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/jellystat/files/compose.yaml b/apps/jellystat/files/compose.yaml new file mode 100644 index 0000000..5295a79 --- /dev/null +++ b/apps/jellystat/files/compose.yaml @@ -0,0 +1,28 @@ +services: + << service_name >>: + image: cyfershepard/jellystat:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - POSTGRES_USER=jellystat + - POSTGRES_PASSWORD=<< db_password >> + - POSTGRES_IP=<< service_name >>-db + - POSTGRES_PORT=5432 + - JWT_SECRET=<< jwt_secret >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/backend/backup-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_USER=jellystat + - POSTGRES_PASSWORD=<< db_password >> + - POSTGRES_DB=jfstat + volumes: + - << appdata_dir >>/<< service_name >>-db:/var/lib/postgresql/data + restart: unless-stopped diff --git a/apps/jellystat/template.json b/apps/jellystat/template.json new file mode 100644 index 0000000..8ca922f --- /dev/null +++ b/apps/jellystat/template.json @@ -0,0 +1,84 @@ +{ + "kind": "compose", + "metadata": { + "name": "Jellystat", + "description": "Kijkstatistieken voor Jellyfin: wie keek wat, hoe lang en hoe vaak. Brengt zijn eigen database mee.", + "tags": [ + "media", + "statistiek", + "monitoring" + ], + "icon": { + "provider": "selfhst", + "id": "jellystat" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "monitoring" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "jellystat", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8118, + "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 instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Database", + "items": [ + { + "name": "db_password", + "type": "str", + "title": "Databasewachtwoord", + "default": "", + "required": true, + "secret": true, + "generate": "auto" + }, + { + "name": "jwt_secret", + "type": "str", + "title": "JWT-sleutel", + "default": "", + "required": true, + "secret": true, + "generate": "auto", + "description": "Ondertekent de inlogsessies" + } + ] + } + ] +} diff --git a/apps/kapowarr/files/compose.yaml b/apps/kapowarr/files/compose.yaml new file mode 100644 index 0000000..593645a --- /dev/null +++ b/apps/kapowarr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: mrcas/kapowarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/db + - << data_root >>:/data + ports: + - "<< port >>:5656" + restart: unless-stopped diff --git a/apps/kapowarr/template.json b/apps/kapowarr/template.json new file mode 100644 index 0000000..416593a --- /dev/null +++ b/apps/kapowarr/template.json @@ -0,0 +1,67 @@ +{ + "kind": "compose", + "metadata": { + "name": "Kapowarr", + "description": "Bouwt en beheert een stripbibliotheek, met eigen bestandsnaamgeving en kwaliteitsregels.", + "tags": [ + "media", + "strips", + "boeken" + ], + "icon": { + "provider": "selfhst", + "id": "kapowarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "kapowarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 5656, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/karakeep/files/compose.yaml b/apps/karakeep/files/compose.yaml index 1b4b5e0..34938ec 100644 --- a/apps/karakeep/files/compose.yaml +++ b/apps/karakeep/files/compose.yaml @@ -12,7 +12,7 @@ services: - DATA_DIR=/data - OPENAI_API_KEY=<< openai_key >> volumes: - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data depends_on: - << service_name >>-meilisearch - << service_name >>-chrome diff --git a/apps/karakeep/template.json b/apps/karakeep/template.json index 3ab8ad3..805c888 100644 --- a/apps/karakeep/template.json +++ b/apps/karakeep/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/kavita/files/compose.yaml b/apps/kavita/files/compose.yaml index 740396a..c03baa2 100644 --- a/apps/kavita/files/compose.yaml +++ b/apps/kavita/files/compose.yaml @@ -9,6 +9,6 @@ services: - PUID=<< puid >> - PGID=<< pgid >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - << library_dir >>:/library restart: unless-stopped diff --git a/apps/kavita/template.json b/apps/kavita/template.json index cfbaae9..f1fba51 100644 --- a/apps/kavita/template.json +++ b/apps/kavita/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/kimai/files/compose.yaml b/apps/kimai/files/compose.yaml index 6ce5bcb..d042cfd 100644 --- a/apps/kimai/files/compose.yaml +++ b/apps/kimai/files/compose.yaml @@ -10,7 +10,7 @@ services: - ADMINMAIL=<< admin_email >> - ADMINPASS=<< admin_password >> volumes: - - << data_dir >>/<< service_name >>/data:/opt/kimai/var/data + - << appdata_dir >>/<< service_name >>/data:/opt/kimai/var/data depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/kimai/template.json b/apps/kimai/template.json index d3074f0..5402fca 100644 --- a/apps/kimai/template.json +++ b/apps/kimai/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/kometa/files/compose.yaml b/apps/kometa/files/compose.yaml new file mode 100644 index 0000000..4fb9dbb --- /dev/null +++ b/apps/kometa/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: kometateam/kometa:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - KOMETA_RUN=false + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + restart: unless-stopped diff --git a/apps/kometa/template.json b/apps/kometa/template.json new file mode 100644 index 0000000..74a396d --- /dev/null +++ b/apps/kometa/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Kometa", + "description": "Bouwt collecties, overlays en metadata op in Plex, Jellyfin of Emby. Voorheen Plex Meta Manager.", + "tags": [ + "media", + "metadata" + ], + "icon": { + "provider": "selfhst", + "id": "kometa" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "kometa", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/komga/files/compose.yaml b/apps/komga/files/compose.yaml index 53340df..80d2eaf 100644 --- a/apps/komga/files/compose.yaml +++ b/apps/komga/files/compose.yaml @@ -8,6 +8,6 @@ services: - TZ=<< timezone >> user: "<< puid >>:<< pgid >>" volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - << library_dir >>:/data restart: unless-stopped diff --git a/apps/komga/template.json b/apps/komga/template.json index be65e33..377753a 100644 --- a/apps/komga/template.json +++ b/apps/komga/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/kopia/files/compose.yaml b/apps/kopia/files/compose.yaml index edd1877..809aec2 100644 --- a/apps/kopia/files/compose.yaml +++ b/apps/kopia/files/compose.yaml @@ -14,8 +14,8 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/app/config - - << data_dir >>/<< service_name >>/cache:/app/cache + - << appdata_dir >>/<< service_name >>/config:/app/config + - << appdata_dir >>/<< service_name >>/cache:/app/cache - << source_dir >>:/data:ro - << repo_dir >>:/repository restart: unless-stopped diff --git a/apps/kopia/template.json b/apps/kopia/template.json index c654386..6521f6b 100644 --- a/apps/kopia/template.json +++ b/apps/kopia/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/lidarr/files/compose.yaml b/apps/lidarr/files/compose.yaml new file mode 100644 index 0000000..23b289a --- /dev/null +++ b/apps/lidarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/lidarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:8686" + restart: unless-stopped diff --git a/apps/lidarr/template.json b/apps/lidarr/template.json new file mode 100644 index 0000000..baa6753 --- /dev/null +++ b/apps/lidarr/template.json @@ -0,0 +1,87 @@ +{ + "kind": "compose", + "metadata": { + "name": "Lidarr", + "description": "Beheert je muziekbibliotheek: volgt artiesten en haalt nieuwe albums binnen.", + "tags": [ + "media", + "muziek", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "lidarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "lidarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8686, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/lingarr/files/compose.yaml b/apps/lingarr/files/compose.yaml new file mode 100644 index 0000000..ea77210 --- /dev/null +++ b/apps/lingarr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: lingarr/lingarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/config + - << data_root >>:/data + ports: + - "<< port >>:9876" + restart: unless-stopped diff --git a/apps/lingarr/template.json b/apps/lingarr/template.json new file mode 100644 index 0000000..b687249 --- /dev/null +++ b/apps/lingarr/template.json @@ -0,0 +1,67 @@ +{ + "kind": "compose", + "metadata": { + "name": "Lingarr", + "description": "Vertaalt ondertitels automatisch, met een lokaal model of een vertaaldienst naar keuze.", + "tags": [ + "media", + "ondertitels", + "ai" + ], + "icon": { + "provider": "selfhst", + "id": "lingarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "lingarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 9876, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/linkding/files/compose.yaml b/apps/linkding/files/compose.yaml index 96d6d5c..b9e345c 100644 --- a/apps/linkding/files/compose.yaml +++ b/apps/linkding/files/compose.yaml @@ -8,5 +8,5 @@ services: - LD_SUPERUSER_NAME=<< superuser_name >> - LD_SUPERUSER_PASSWORD=<< superuser_password >> volumes: - - << data_dir >>/<< service_name >>/data:/etc/linkding/data + - << appdata_dir >>/<< service_name >>/data:/etc/linkding/data restart: unless-stopped diff --git a/apps/linkding/template.json b/apps/linkding/template.json index 28b8155..0190a27 100644 --- a/apps/linkding/template.json +++ b/apps/linkding/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/maintainerr/files/compose.yaml b/apps/maintainerr/files/compose.yaml new file mode 100644 index 0000000..8508874 --- /dev/null +++ b/apps/maintainerr/files/compose.yaml @@ -0,0 +1,13 @@ +services: + << service_name >>: + image: ghcr.io/maintainerr/maintainerr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/opt/data + ports: + - "<< port >>:6246" + restart: unless-stopped diff --git a/apps/maintainerr/template.json b/apps/maintainerr/template.json new file mode 100644 index 0000000..a026309 --- /dev/null +++ b/apps/maintainerr/template.json @@ -0,0 +1,77 @@ +{ + "kind": "compose", + "metadata": { + "name": "Maintainerr", + "description": "Ruimt media op volgens regels die je zelf samenstelt, met een voorvertoning van wat er weg zou gaan.", + "tags": [ + "media", + "opruimen" + ], + "icon": { + "provider": "selfhst", + "id": "maintainerr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "maintainerr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 6246, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/mealie/files/compose.yaml b/apps/mealie/files/compose.yaml index c284676..a35a7a7 100644 --- a/apps/mealie/files/compose.yaml +++ b/apps/mealie/files/compose.yaml @@ -9,5 +9,5 @@ services: - ALLOW_SIGNUP=<< allow_signup | lower >> - BASE_URL=http://localhost:<< port >> volumes: - - << data_dir >>/<< service_name >>/data:/app/data + - << appdata_dir >>/<< service_name >>/data:/app/data restart: unless-stopped diff --git a/apps/mealie/template.json b/apps/mealie/template.json index 4e5a9cd..80c5102 100644 --- a/apps/mealie/template.json +++ b/apps/mealie/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/memos/files/compose.yaml b/apps/memos/files/compose.yaml index 2124d8f..8fa3fb4 100644 --- a/apps/memos/files/compose.yaml +++ b/apps/memos/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>:/var/opt/memos + - << appdata_dir >>/<< service_name >>:/var/opt/memos restart: unless-stopped diff --git a/apps/memos/template.json b/apps/memos/template.json index 570d3e1..9724dee 100644 --- a/apps/memos/template.json +++ b/apps/memos/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/metabase/files/compose.yaml b/apps/metabase/files/compose.yaml index 96f33c6..c9cfb38 100644 --- a/apps/metabase/files/compose.yaml +++ b/apps/metabase/files/compose.yaml @@ -8,5 +8,5 @@ services: - TZ=<< timezone >> - MB_DB_FILE=/metabase-data/metabase.db volumes: - - << data_dir >>/<< service_name >>:/metabase-data + - << appdata_dir >>/<< service_name >>:/metabase-data restart: unless-stopped diff --git a/apps/metabase/template.json b/apps/metabase/template.json index b89f7bf..1be7d4d 100644 --- a/apps/metabase/template.json +++ b/apps/metabase/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/mosquitto/files/compose.yaml b/apps/mosquitto/files/compose.yaml index 5b3c6d9..f99216d 100644 --- a/apps/mosquitto/files/compose.yaml +++ b/apps/mosquitto/files/compose.yaml @@ -8,7 +8,7 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/mosquitto/config - - << data_dir >>/<< service_name >>/data:/mosquitto/data - - << data_dir >>/<< service_name >>/log:/mosquitto/log + - << appdata_dir >>/<< service_name >>/config:/mosquitto/config + - << appdata_dir >>/<< service_name >>/data:/mosquitto/data + - << appdata_dir >>/<< service_name >>/log:/mosquitto/log restart: unless-stopped diff --git a/apps/mosquitto/template.json b/apps/mosquitto/template.json index 8af4263..6197c7c 100644 --- a/apps/mosquitto/template.json +++ b/apps/mosquitto/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/mylar3/files/compose.yaml b/apps/mylar3/files/compose.yaml new file mode 100644 index 0000000..947284c --- /dev/null +++ b/apps/mylar3/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/mylar3:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:8090" + restart: unless-stopped diff --git a/apps/mylar3/template.json b/apps/mylar3/template.json new file mode 100644 index 0000000..b267b6b --- /dev/null +++ b/apps/mylar3/template.json @@ -0,0 +1,88 @@ +{ + "kind": "compose", + "metadata": { + "name": "Mylar3", + "description": "Volgt stripseries en haalt nieuwe uitgaven binnen. De *arr-aanpak, maar voor comics.", + "tags": [ + "media", + "strips", + "boeken" + ], + "icon": { + "provider": "selfhst", + "id": "mylar" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "mylar3", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8115, + "required": true, + "description": "Standaard 8090; 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 instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/n8n/files/compose.yaml b/apps/n8n/files/compose.yaml index 3e9754d..6022512 100644 --- a/apps/n8n/files/compose.yaml +++ b/apps/n8n/files/compose.yaml @@ -13,5 +13,5 @@ services: - TZ=<< timezone >> - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true volumes: - - << data_dir >>/<< service_name >>/data:/home/node/.n8n + - << appdata_dir >>/<< service_name >>/data:/home/node/.n8n restart: unless-stopped diff --git a/apps/n8n/template.json b/apps/n8n/template.json index de56886..599b7fb 100644 --- a/apps/n8n/template.json +++ b/apps/n8n/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/navidrome/files/compose.yaml b/apps/navidrome/files/compose.yaml index 72dd207..b0f980d 100644 --- a/apps/navidrome/files/compose.yaml +++ b/apps/navidrome/files/compose.yaml @@ -10,5 +10,5 @@ services: - ND_LOGLEVEL=info volumes: - << music_dir >>:/music:ro - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data restart: unless-stopped diff --git a/apps/navidrome/template.json b/apps/navidrome/template.json index b3ee073..87e3c32 100644 --- a/apps/navidrome/template.json +++ b/apps/navidrome/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/neutarr/files/compose.yaml b/apps/neutarr/files/compose.yaml new file mode 100644 index 0000000..fe6b70d --- /dev/null +++ b/apps/neutarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: iampuid0/neutarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:9705" + restart: unless-stopped diff --git a/apps/neutarr/template.json b/apps/neutarr/template.json new file mode 100644 index 0000000..17b2380 --- /dev/null +++ b/apps/neutarr/template.json @@ -0,0 +1,57 @@ +{ + "kind": "compose", + "metadata": { + "name": "NeutArr", + "description": "Zoekt gericht naar ontbrekende afleveringen en naar wat beter kan. Opvolger van Huntarr, dat in februari 2026 offline ging na een reeks lekken; dit is de fork van de laatste schone versie.", + "tags": [ + "media", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "huntarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "neutarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 9705, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/nextcloud-aio/files/compose.yaml b/apps/nextcloud-aio/files/compose.yaml index b01bcad..6b28baa 100644 --- a/apps/nextcloud-aio/files/compose.yaml +++ b/apps/nextcloud-aio/files/compose.yaml @@ -8,7 +8,7 @@ services: environment: - APACHE_PORT=<< port_nextcloud >> - APACHE_IP_BINDING=0.0.0.0 - - NEXTCLOUD_DATADIR=<< data_dir >>/<< service_name >>/ncdata + - NEXTCLOUD_DATADIR=<< appdata_dir >>/<< service_name >>/ncdata - TZ=<< timezone >> volumes: - << service_name >>_config:/mnt/docker-aio-config diff --git a/apps/nextcloud-aio/template.json b/apps/nextcloud-aio/template.json index ca01dfa..ee3b24c 100644 --- a/apps/nextcloud-aio/template.json +++ b/apps/nextcloud-aio/template.json @@ -34,9 +34,9 @@ "description": "AIO beheert zelf extra containers. Naam is normaal nextcloud-aio-mastercontainer." }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Basismap voor Nextcloud-bestanden" diff --git a/apps/nginx-proxy-manager/files/compose.yaml b/apps/nginx-proxy-manager/files/compose.yaml index 0ead0ac..80288ac 100644 --- a/apps/nginx-proxy-manager/files/compose.yaml +++ b/apps/nginx-proxy-manager/files/compose.yaml @@ -7,6 +7,6 @@ services: - "<< port_https >>:443" - "<< port_admin >>:81" volumes: - - << data_dir >>/<< service_name >>/data:/data - - << data_dir >>/<< service_name >>/letsencrypt:/etc/letsencrypt + - << appdata_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/letsencrypt:/etc/letsencrypt restart: unless-stopped diff --git a/apps/nginx-proxy-manager/template.json b/apps/nginx-proxy-manager/template.json index 9b993da..adfb4b7 100644 --- a/apps/nginx-proxy-manager/template.json +++ b/apps/nginx-proxy-manager/template.json @@ -33,9 +33,9 @@ "description": "Naam van de Docker container" }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Basismap voor persistente data" diff --git a/apps/nocodb/files/compose.yaml b/apps/nocodb/files/compose.yaml index a932eed..9e3f7c4 100644 --- a/apps/nocodb/files/compose.yaml +++ b/apps/nocodb/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>:/usr/app/data + - << appdata_dir >>/<< service_name >>:/usr/app/data restart: unless-stopped diff --git a/apps/nocodb/template.json b/apps/nocodb/template.json index 1abd31d..b172736 100644 --- a/apps/nocodb/template.json +++ b/apps/nocodb/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/node-red/files/compose.yaml b/apps/node-red/files/compose.yaml index 7af8ad4..3b6d20f 100644 --- a/apps/node-red/files/compose.yaml +++ b/apps/node-red/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data restart: unless-stopped diff --git a/apps/node-red/template.json b/apps/node-red/template.json index 6104b0a..4f936a1 100644 --- a/apps/node-red/template.json +++ b/apps/node-red/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/notifiarr/files/compose.yaml b/apps/notifiarr/files/compose.yaml new file mode 100644 index 0000000..be0e227 --- /dev/null +++ b/apps/notifiarr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: golift/notifiarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - DN_API_KEY=<< notifiarr_apikey >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:5454" + restart: unless-stopped diff --git a/apps/notifiarr/template.json b/apps/notifiarr/template.json new file mode 100644 index 0000000..947a176 --- /dev/null +++ b/apps/notifiarr/template.json @@ -0,0 +1,73 @@ +{ + "kind": "compose", + "metadata": { + "name": "Notifiarr", + "description": "Stuurt meldingen van je *arr-apps naar Discord, en houdt tegelijk je server in de gaten.", + "tags": [ + "meldingen", + "monitoring", + "discord" + ], + "icon": { + "provider": "selfhst", + "id": "notifiarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "communicatie", + "monitoring" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "notifiarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 5454, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + }, + { + "title": "Toegang", + "items": [ + { + "name": "notifiarr_apikey", + "type": "str", + "title": "Notifiarr API-sleutel", + "default": "", + "required": true, + "secret": true, + "description": "Haal je op in je profiel op notifiarr.com" + } + ] + } + ] +} diff --git a/apps/ntfy/files/compose.yaml b/apps/ntfy/files/compose.yaml index 72c995f..746d4a4 100644 --- a/apps/ntfy/files/compose.yaml +++ b/apps/ntfy/files/compose.yaml @@ -13,5 +13,5 @@ services: - NTFY_AUTH_DEFAULT_ACCESS=<< auth_default >> - NTFY_CACHE_FILE=/var/lib/ntfy/cache.db volumes: - - << data_dir >>/<< service_name >>:/var/lib/ntfy + - << appdata_dir >>/<< service_name >>:/var/lib/ntfy restart: unless-stopped diff --git a/apps/ntfy/template.json b/apps/ntfy/template.json index dec4100..5e3911b 100644 --- a/apps/ntfy/template.json +++ b/apps/ntfy/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/nzbget/files/compose.yaml b/apps/nzbget/files/compose.yaml new file mode 100644 index 0000000..8c15198 --- /dev/null +++ b/apps/nzbget/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/nzbget:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:6789" + restart: unless-stopped diff --git a/apps/nzbget/template.json b/apps/nzbget/template.json new file mode 100644 index 0000000..d91169b --- /dev/null +++ b/apps/nzbget/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "NZBGet", + "description": "Zuinige usenet-downloader. Lichter dan SABnzbd en daarmee prettig op een kleine server.", + "tags": [ + "usenet", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "nzbget" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "nzbget", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 6789, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/nzbhydra2/files/compose.yaml b/apps/nzbhydra2/files/compose.yaml new file mode 100644 index 0000000..3e00b3e --- /dev/null +++ b/apps/nzbhydra2/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/nzbhydra2:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:5076" + restart: unless-stopped diff --git a/apps/nzbhydra2/template.json b/apps/nzbhydra2/template.json new file mode 100644 index 0000000..496b078 --- /dev/null +++ b/apps/nzbhydra2/template.json @@ -0,0 +1,78 @@ +{ + "kind": "compose", + "metadata": { + "name": "NZBHydra2", + "description": "Bundelt meerdere usenet-indexers tot één zoekbron, met eigen statistieken per indexer.", + "tags": [ + "usenet", + "indexers", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "nzbhydra2" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "nzbhydra2", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 5076, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/octoprint/files/compose.yaml b/apps/octoprint/files/compose.yaml index 406d9c3..efd92e5 100644 --- a/apps/octoprint/files/compose.yaml +++ b/apps/octoprint/files/compose.yaml @@ -7,7 +7,7 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>:/octoprint + - << appdata_dir >>/<< service_name >>:/octoprint devices: - << usb_device >>:/dev/ttyACM0 restart: unless-stopped diff --git a/apps/octoprint/template.json b/apps/octoprint/template.json index ff772fb..9d44bfa 100644 --- a/apps/octoprint/template.json +++ b/apps/octoprint/template.json @@ -37,9 +37,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/ollama/files/compose.yaml b/apps/ollama/files/compose.yaml index 1d7955d..feb868d 100644 --- a/apps/ollama/files/compose.yaml +++ b/apps/ollama/files/compose.yaml @@ -7,7 +7,7 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>:/root/.ollama + - << appdata_dir >>/<< service_name >>:/root/.ollama <%- if gpu %> deploy: resources: diff --git a/apps/ollama/template.json b/apps/ollama/template.json index a05205c..d046898 100644 --- a/apps/ollama/template.json +++ b/apps/ollama/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/open-webui/files/compose.yaml b/apps/open-webui/files/compose.yaml index 2a995c9..33f07dc 100644 --- a/apps/open-webui/files/compose.yaml +++ b/apps/open-webui/files/compose.yaml @@ -9,5 +9,5 @@ services: - OLLAMA_BASE_URL=<< ollama_url >> - WEBUI_SECRET_KEY=<< secret_key >> volumes: - - << data_dir >>/<< service_name >>:/app/backend/data + - << appdata_dir >>/<< service_name >>:/app/backend/data restart: unless-stopped diff --git a/apps/open-webui/template.json b/apps/open-webui/template.json index 813b696..80998b9 100644 --- a/apps/open-webui/template.json +++ b/apps/open-webui/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/overseerr/files/compose.yaml b/apps/overseerr/files/compose.yaml new file mode 100644 index 0000000..6873de7 --- /dev/null +++ b/apps/overseerr/files/compose.yaml @@ -0,0 +1,12 @@ +services: + << service_name >>: + image: sctx/overseerr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - LOG_LEVEL=info + volumes: + - << appdata_dir >>/<< service_name >>:/app/config + ports: + - "<< port >>:5055" + restart: unless-stopped diff --git a/apps/overseerr/template.json b/apps/overseerr/template.json new file mode 100644 index 0000000..672cc14 --- /dev/null +++ b/apps/overseerr/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "Overseerr", + "description": "Laat huisgenoten films en series aanvragen, gekoppeld aan Plex. Voor Jellyfin en Emby gebruik je Jellyseerr.", + "tags": [ + "media", + "verzoeken" + ], + "icon": { + "provider": "selfhst", + "id": "overseerr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "overseerr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8120, + "required": true, + "description": "Standaard 5055; hier verplaatst omdat Jellyseerr die al gebruikt" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/owntracks/files/compose.yaml b/apps/owntracks/files/compose.yaml index 124fe72..5002a26 100644 --- a/apps/owntracks/files/compose.yaml +++ b/apps/owntracks/files/compose.yaml @@ -8,6 +8,6 @@ services: - TZ=<< timezone >> - OTR_PORT=0 volumes: - - << data_dir >>/<< service_name >>/store:/store - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/store:/store + - << appdata_dir >>/<< service_name >>/config:/config restart: unless-stopped diff --git a/apps/owntracks/template.json b/apps/owntracks/template.json index e7aeff7..faceaae 100644 --- a/apps/owntracks/template.json +++ b/apps/owntracks/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/paperless-ngx/files/compose.yaml b/apps/paperless-ngx/files/compose.yaml index f87b054..3517f6b 100644 --- a/apps/paperless-ngx/files/compose.yaml +++ b/apps/paperless-ngx/files/compose.yaml @@ -28,10 +28,10 @@ services: - PAPERLESS_TIME_ZONE=<< timezone >> - PAPERLESS_OCR_LANGUAGE=<< ocr_language >> volumes: - - << data_dir >>/<< service_name >>/data:/usr/src/paperless/data - - << data_dir >>/<< service_name >>/media:/usr/src/paperless/media - - << data_dir >>/<< service_name >>/export:/usr/src/paperless/export - - << data_dir >>/<< service_name >>/consume:/usr/src/paperless/consume + - << appdata_dir >>/<< service_name >>/data:/usr/src/paperless/data + - << appdata_dir >>/<< service_name >>/media:/usr/src/paperless/media + - << appdata_dir >>/<< service_name >>/export:/usr/src/paperless/export + - << appdata_dir >>/<< service_name >>/consume:/usr/src/paperless/consume depends_on: - << service_name >>-broker - << service_name >>-db diff --git a/apps/paperless-ngx/template.json b/apps/paperless-ngx/template.json index 0be770a..ef1da0c 100644 --- a/apps/paperless-ngx/template.json +++ b/apps/paperless-ngx/template.json @@ -40,9 +40,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/photoprism/files/compose.yaml b/apps/photoprism/files/compose.yaml index 75f1e2e..5965d0f 100644 --- a/apps/photoprism/files/compose.yaml +++ b/apps/photoprism/files/compose.yaml @@ -15,7 +15,7 @@ services: - PHOTOPRISM_DATABASE_PASSWORD=<< db_password >> volumes: - << photos_dir >>:/photoprism/originals - - << data_dir >>/<< service_name >>/storage:/photoprism/storage + - << appdata_dir >>/<< service_name >>/storage:/photoprism/storage depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/photoprism/template.json b/apps/photoprism/template.json index ac745eb..81ffb57 100644 --- a/apps/photoprism/template.json +++ b/apps/photoprism/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/pihole/files/compose.yaml b/apps/pihole/files/compose.yaml index c638374..f220032 100644 --- a/apps/pihole/files/compose.yaml +++ b/apps/pihole/files/compose.yaml @@ -10,6 +10,6 @@ services: - TZ=<< timezone >> - WEBPASSWORD=<< web_password >> volumes: - - << data_dir >>/<< service_name >>/etc-pihole:/etc/pihole - - << data_dir >>/<< service_name >>/etc-dnsmasq.d:/etc/dnsmasq.d + - << appdata_dir >>/<< service_name >>/etc-pihole:/etc/pihole + - << appdata_dir >>/<< service_name >>/etc-dnsmasq.d:/etc/dnsmasq.d restart: unless-stopped diff --git a/apps/pihole/template.json b/apps/pihole/template.json index 0fb48d8..48ab75e 100644 --- a/apps/pihole/template.json +++ b/apps/pihole/template.json @@ -48,9 +48,9 @@ "description": "Poort 53 is de standaard DNS-poort" }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/pinchflat/files/compose.yaml b/apps/pinchflat/files/compose.yaml index 4ad97b9..e7fdc52 100644 --- a/apps/pinchflat/files/compose.yaml +++ b/apps/pinchflat/files/compose.yaml @@ -7,6 +7,6 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - << downloads_dir >>:/downloads restart: unless-stopped diff --git a/apps/pinchflat/template.json b/apps/pinchflat/template.json index b3191db..9f4e393 100644 --- a/apps/pinchflat/template.json +++ b/apps/pinchflat/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/planka/files/compose.yaml b/apps/planka/files/compose.yaml index 8e206c4..b2a3653 100644 --- a/apps/planka/files/compose.yaml +++ b/apps/planka/files/compose.yaml @@ -14,8 +14,8 @@ services: - DEFAULT_ADMIN_NAME=Beheerder - DEFAULT_ADMIN_USERNAME=beheerder volumes: - - << data_dir >>/<< service_name >>/avatars:/app/public/user-avatars - - << data_dir >>/<< service_name >>/attachments:/app/private/attachments + - << appdata_dir >>/<< service_name >>/avatars:/app/public/user-avatars + - << appdata_dir >>/<< service_name >>/attachments:/app/private/attachments depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/planka/template.json b/apps/planka/template.json index e687c66..60b5b92 100644 --- a/apps/planka/template.json +++ b/apps/planka/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/plex/files/compose.yaml b/apps/plex/files/compose.yaml index 37afbd8..03bb18a 100644 --- a/apps/plex/files/compose.yaml +++ b/apps/plex/files/compose.yaml @@ -12,6 +12,6 @@ services: - PLEX_CLAIM=<< plex_claim >> <% endif %> volumes: - - << data_dir >>/<< service_name >>/config:/config - - << media_dir >>:/media:ro + - << appdata_dir >>/<< service_name >>/config:/config + - << data_root >>/media:/data/media:ro restart: unless-stopped diff --git a/apps/plex/template.json b/apps/plex/template.json index a88adbb..67ef617 100644 --- a/apps/plex/template.json +++ b/apps/plex/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Basismap voor Plex configuratie en metadata" @@ -80,12 +80,13 @@ "title": "Media", "items": [ { - "name": "media_dir", + "name": "data_root", "type": "str", - "title": "Media directory", - "default": "/mnt/media", + "title": "Gedeelde datamap", + "default": "/mnt/data", "required": true, - "description": "Map met je films, series en muziek (wordt read-only gemount)" + "description": "Je media staat onder /data/media en wordt alleen-lezen gekoppeld", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." } ] }, diff --git a/apps/portainer/files/compose.yaml b/apps/portainer/files/compose.yaml index e3d0719..843d884 100644 --- a/apps/portainer/files/compose.yaml +++ b/apps/portainer/files/compose.yaml @@ -6,5 +6,5 @@ services: - "<< port >>:9000" volumes: - /var/run/docker.sock:/var/run/docker.sock - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data restart: unless-stopped diff --git a/apps/portainer/template.json b/apps/portainer/template.json index 072a3e5..ea2c78f 100644 --- a/apps/portainer/template.json +++ b/apps/portainer/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/posterizarr/files/compose.yaml b/apps/posterizarr/files/compose.yaml new file mode 100644 index 0000000..075031c --- /dev/null +++ b/apps/posterizarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/fscorrupt/posterizarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - RUN_TIME=disabled + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + restart: unless-stopped diff --git a/apps/posterizarr/template.json b/apps/posterizarr/template.json new file mode 100644 index 0000000..d564a8c --- /dev/null +++ b/apps/posterizarr/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Posterizarr", + "description": "Maakt automatisch posters en titelkaarten voor je bibliotheek, in een stijl die je zelf instelt.", + "tags": [ + "media", + "artwork" + ], + "icon": { + "provider": "selfhst", + "id": "posterizarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "posterizarr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/prefetcharr/files/compose.yaml b/apps/prefetcharr/files/compose.yaml new file mode 100644 index 0000000..00dd535 --- /dev/null +++ b/apps/prefetcharr/files/compose.yaml @@ -0,0 +1,9 @@ +services: + << service_name >>: + image: phueber/prefetcharr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + restart: unless-stopped diff --git a/apps/prefetcharr/template.json b/apps/prefetcharr/template.json new file mode 100644 index 0000000..3030986 --- /dev/null +++ b/apps/prefetcharr/template.json @@ -0,0 +1,51 @@ +{ + "kind": "compose", + "metadata": { + "name": "Prefetcharr", + "description": "Laat Sonarr het volgende seizoen ophalen zodra je aan de laatste afleveringen van het huidige begint.", + "tags": [ + "media", + "series", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "sonarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "prefetcharr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/profilarr/files/compose.yaml b/apps/profilarr/files/compose.yaml new file mode 100644 index 0000000..208bcdd --- /dev/null +++ b/apps/profilarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: santiagosayshey/profilarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:6868" + restart: unless-stopped diff --git a/apps/profilarr/template.json b/apps/profilarr/template.json new file mode 100644 index 0000000..dd59135 --- /dev/null +++ b/apps/profilarr/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "Profilarr", + "description": "Beheert kwaliteitsprofielen en custom formats met versiebeheer, en deelt ze tussen instanties.", + "tags": [ + "media", + "configuratie" + ], + "icon": { + "provider": "selfhst", + "id": "profilarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "profilarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 6868, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/prometheus/files/compose.yaml b/apps/prometheus/files/compose.yaml index 0fa87ea..81ac4c7 100644 --- a/apps/prometheus/files/compose.yaml +++ b/apps/prometheus/files/compose.yaml @@ -10,7 +10,7 @@ services: - --config.file=/etc/prometheus/prometheus.yml - --storage.tsdb.retention.time=<< retention >> volumes: - - << data_dir >>/<< service_name >>/config:/etc/prometheus + - << appdata_dir >>/<< service_name >>/config:/etc/prometheus - << service_name >>_data:/prometheus restart: unless-stopped diff --git a/apps/prometheus/template.json b/apps/prometheus/template.json index f7f9edf..dba9fb8 100644 --- a/apps/prometheus/template.json +++ b/apps/prometheus/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/prowlarr/files/compose.yaml b/apps/prowlarr/files/compose.yaml new file mode 100644 index 0000000..d17e0a9 --- /dev/null +++ b/apps/prowlarr/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/prowlarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:9696" + restart: unless-stopped diff --git a/apps/prowlarr/template.json b/apps/prowlarr/template.json new file mode 100644 index 0000000..ff308f0 --- /dev/null +++ b/apps/prowlarr/template.json @@ -0,0 +1,78 @@ +{ + "kind": "compose", + "metadata": { + "name": "Prowlarr", + "description": "Beheert je indexers op één plek en duwt ze door naar Sonarr, Radarr en de rest. Scheelt overal apart instellen.", + "tags": [ + "media", + "indexers", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "prowlarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "prowlarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 9696, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/pulsarr/files/compose.yaml b/apps/pulsarr/files/compose.yaml new file mode 100644 index 0000000..ea133dd --- /dev/null +++ b/apps/pulsarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: lakker/pulsarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/data + ports: + - "<< port >>:3003" + restart: unless-stopped diff --git a/apps/pulsarr/template.json b/apps/pulsarr/template.json new file mode 100644 index 0000000..013daa6 --- /dev/null +++ b/apps/pulsarr/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "Pulsarr", + "description": "Koppelt Plex-watchlists aan Sonarr en Radarr: wat je op je lijst zet, wordt opgehaald.", + "tags": [ + "media", + "watchlist" + ], + "icon": { + "provider": "selfhst", + "id": "pulsarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "pulsarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8117, + "required": true, + "description": "Standaard 3003; 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 instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/qbittorrent/files/compose.yaml b/apps/qbittorrent/files/compose.yaml index 613aa03..603cce3 100644 --- a/apps/qbittorrent/files/compose.yaml +++ b/apps/qbittorrent/files/compose.yaml @@ -6,12 +6,15 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> - - WEBUI_PORT=<< port_ui >> + - UMASK=002 + # Vast: de interne poort hoort niet af te hangen van welke hostpoort je + # kiest, anders klopt hij niet meer zodra de container achter een VPN zit. + - WEBUI_PORT=8090 volumes: - - << data_dir >>/<< service_name >>/config:/config - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data ports: - - "<< port_ui >>:<< port_ui >>" + - "<< port_ui >>:8090" - "<< port_torrent >>:6881" - "<< port_torrent >>:6881/udp" restart: unless-stopped diff --git a/apps/qbittorrent/template.json b/apps/qbittorrent/template.json index 9f7a4b8..0c78986 100644 --- a/apps/qbittorrent/template.json +++ b/apps/qbittorrent/template.json @@ -34,9 +34,9 @@ "name": "port_ui", "type": "int", "title": "Web UI poort", - "default": 8080, + "default": 8097, "required": true, - "description": "Poort voor de webinterface" + "description": "Standaard 8080; hier verplaatst omdat zes andere apps die poort ook willen" }, { "name": "port_torrent", @@ -47,19 +47,20 @@ "description": "Poort voor torrent-verbindingen (TCP en UDP). Zet deze poort open in je firewall/router voor betere download-snelheid." }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Config directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, { - "name": "downloads_dir", + "name": "data_root", "type": "str", - "title": "Downloads directory", - "default": "/mnt/downloads", + "title": "Gedeelde datamap", + "default": "/mnt/data", "required": true, - "description": "Map waar downloads worden opgeslagen. Gebruik hetzelfde pad als in Radarr/Sonarr." + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." }, { "name": "timezone", diff --git a/apps/radarr/files/compose.yaml b/apps/radarr/files/compose.yaml new file mode 100644 index 0000000..b0c1c93 --- /dev/null +++ b/apps/radarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/radarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:7878" + restart: unless-stopped diff --git a/apps/radarr/template.json b/apps/radarr/template.json new file mode 100644 index 0000000..8e37c45 --- /dev/null +++ b/apps/radarr/template.json @@ -0,0 +1,87 @@ +{ + "kind": "compose", + "metadata": { + "name": "Radarr", + "description": "Zoekt, downloadt en hernoemt films. Dezelfde aanpak als Sonarr, maar dan voor je filmbibliotheek.", + "tags": [ + "media", + "films", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "radarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "radarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 7878, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/readarr/files/compose.yaml b/apps/readarr/files/compose.yaml new file mode 100644 index 0000000..e468266 --- /dev/null +++ b/apps/readarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/readarr:develop + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:8787" + restart: unless-stopped diff --git a/apps/readarr/template.json b/apps/readarr/template.json new file mode 100644 index 0000000..04458c5 --- /dev/null +++ b/apps/readarr/template.json @@ -0,0 +1,87 @@ +{ + "kind": "compose", + "metadata": { + "name": "Readarr", + "description": "Beheert e-boeken en luisterboeken. Let op: de ontwikkeling is stilgelegd; het draait nog wel, maar er komen geen nieuwe versies meer.", + "tags": [ + "media", + "boeken", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "readarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "readarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8787, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/recyclarr/files/compose.yaml b/apps/recyclarr/files/compose.yaml new file mode 100644 index 0000000..b7b9e17 --- /dev/null +++ b/apps/recyclarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/recyclarr/recyclarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + restart: unless-stopped diff --git a/apps/recyclarr/template.json b/apps/recyclarr/template.json new file mode 100644 index 0000000..e4c38c5 --- /dev/null +++ b/apps/recyclarr/template.json @@ -0,0 +1,71 @@ +{ + "kind": "compose", + "metadata": { + "name": "Recyclarr", + "description": "Zet de kwaliteitsprofielen uit de TRaSH-gidsen in Sonarr en Radarr, en houdt ze bij.", + "tags": [ + "media", + "configuratie" + ], + "icon": { + "provider": "selfhst", + "id": "recyclarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "recyclarr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/requestrr/files/compose.yaml b/apps/requestrr/files/compose.yaml new file mode 100644 index 0000000..5155032 --- /dev/null +++ b/apps/requestrr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: thomst08/requestrr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/root/config + ports: + - "<< port >>:4545" + restart: unless-stopped diff --git a/apps/requestrr/template.json b/apps/requestrr/template.json new file mode 100644 index 0000000..abd1681 --- /dev/null +++ b/apps/requestrr/template.json @@ -0,0 +1,59 @@ +{ + "kind": "compose", + "metadata": { + "name": "Requestrr", + "description": "Discord-bot waarmee je huisgenoten films en series kunnen aanvragen zonder een webinterface te openen.", + "tags": [ + "media", + "verzoeken", + "discord" + ], + "icon": { + "provider": "selfhst", + "id": "requestrr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "communicatie" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "requestrr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 4545, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/sabnzbd/files/compose.yaml b/apps/sabnzbd/files/compose.yaml index 34d4768..1d072da 100644 --- a/apps/sabnzbd/files/compose.yaml +++ b/apps/sabnzbd/files/compose.yaml @@ -6,9 +6,10 @@ services: - PUID=<< puid >> - PGID=<< pgid >> - TZ=<< timezone >> + - UMASK=002 volumes: - - << data_dir >>/<< service_name >>/config:/config - - << downloads_dir >>:/downloads + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data ports: - "<< port >>:8080" restart: unless-stopped diff --git a/apps/sabnzbd/template.json b/apps/sabnzbd/template.json index b5dc46e..5a48c55 100644 --- a/apps/sabnzbd/template.json +++ b/apps/sabnzbd/template.json @@ -40,19 +40,20 @@ "description": "Poort voor de webinterface" }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Config directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, { - "name": "downloads_dir", + "name": "data_root", "type": "str", - "title": "Downloads directory", - "default": "/mnt/downloads", + "title": "Gedeelde datamap", + "default": "/mnt/data", "required": true, - "description": "Map waar downloads worden opgeslagen. Gebruik hetzelfde pad als in Radarr/Sonarr." + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." }, { "name": "timezone", diff --git a/apps/scrypted/files/compose.yaml b/apps/scrypted/files/compose.yaml index 2a8abd5..418eba2 100644 --- a/apps/scrypted/files/compose.yaml +++ b/apps/scrypted/files/compose.yaml @@ -8,5 +8,5 @@ services: - TZ=<< timezone >> - SCRYPTED_SECURE_PORT=<< port >> volumes: - - << data_dir >>/<< service_name >>:/server/volume + - << appdata_dir >>/<< service_name >>:/server/volume restart: unless-stopped diff --git a/apps/scrypted/template.json b/apps/scrypted/template.json index b5f0990..8b12d82 100644 --- a/apps/scrypted/template.json +++ b/apps/scrypted/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/searxng/files/compose.yaml b/apps/searxng/files/compose.yaml index a13df3d..6c316eb 100644 --- a/apps/searxng/files/compose.yaml +++ b/apps/searxng/files/compose.yaml @@ -9,7 +9,7 @@ services: - SEARXNG_BASE_URL=<< base_url >> - SEARXNG_SECRET=<< secret_key >> volumes: - - << data_dir >>/<< service_name >>/config:/etc/searxng + - << appdata_dir >>/<< service_name >>/config:/etc/searxng cap_drop: - ALL cap_add: diff --git a/apps/searxng/template.json b/apps/searxng/template.json index ed96257..5645d46 100644 --- a/apps/searxng/template.json +++ b/apps/searxng/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/shlink/files/compose.yaml b/apps/shlink/files/compose.yaml index a79491e..d4ba1e9 100644 --- a/apps/shlink/files/compose.yaml +++ b/apps/shlink/files/compose.yaml @@ -10,5 +10,5 @@ services: - IS_HTTPS_ENABLED=false - INITIAL_API_KEY=<< api_key >> volumes: - - << data_dir >>/<< service_name >>:/etc/shlink/data + - << appdata_dir >>/<< service_name >>:/etc/shlink/data restart: unless-stopped diff --git a/apps/shlink/template.json b/apps/shlink/template.json index 9c635c4..ca09873 100644 --- a/apps/shlink/template.json +++ b/apps/shlink/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/slskd/files/compose.yaml b/apps/slskd/files/compose.yaml new file mode 100644 index 0000000..5b9e44c --- /dev/null +++ b/apps/slskd/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: slskd/slskd:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + - SLSKD_REMOTE_CONFIGURATION=true + volumes: + - << appdata_dir >>/<< service_name >>:/app + - << data_root >>:/data + ports: + - "<< port >>:5030" + - "<< port_listen >>:50300" + restart: unless-stopped diff --git a/apps/slskd/template.json b/apps/slskd/template.json new file mode 100644 index 0000000..f94dcab --- /dev/null +++ b/apps/slskd/template.json @@ -0,0 +1,74 @@ +{ + "kind": "compose", + "metadata": { + "name": "slskd", + "description": "Soulseek-client met webinterface. In combinatie met Soularr vult het gaten in je muziekbibliotheek die de gewone indexers niet hebben.", + "tags": [ + "muziek", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "slskd" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "slskd", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 5030, + "required": true + }, + { + "name": "port_listen", + "type": "int", + "title": "Luisterpoort", + "default": 50300, + "required": true, + "description": "Zet deze poort open in je router, anders kun je alleen downloaden van gebruikers die zelf bereikbaar zijn" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/sonarr/files/compose.yaml b/apps/sonarr/files/compose.yaml new file mode 100644 index 0000000..947f60a --- /dev/null +++ b/apps/sonarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/sonarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:8989" + restart: unless-stopped diff --git a/apps/sonarr/template.json b/apps/sonarr/template.json new file mode 100644 index 0000000..e865c1f --- /dev/null +++ b/apps/sonarr/template.json @@ -0,0 +1,87 @@ +{ + "kind": "compose", + "metadata": { + "name": "Sonarr", + "description": "Zoekt, downloadt en hernoemt series. Houdt bij welke afleveringen je mist en pakt ze op zodra ze verschijnen.", + "tags": [ + "media", + "series", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "sonarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "sonarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8989, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/soularr/files/compose.yaml b/apps/soularr/files/compose.yaml new file mode 100644 index 0000000..36bb1bc --- /dev/null +++ b/apps/soularr/files/compose.yaml @@ -0,0 +1,10 @@ +services: + << service_name >>: + image: mrusse08/soularr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/data + - << data_root >>:/data + restart: unless-stopped diff --git a/apps/soularr/template.json b/apps/soularr/template.json new file mode 100644 index 0000000..fa6b46a --- /dev/null +++ b/apps/soularr/template.json @@ -0,0 +1,60 @@ +{ + "kind": "compose", + "metadata": { + "name": "Soularr", + "description": "Laat Lidarr zoeken via Soulseek (slskd) voor albums die op de gewone indexers niet te vinden zijn.", + "tags": [ + "muziek", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "soulseek" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden", + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "soularr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. Eronder: media/films, media/series, torrents/ en usenet/." + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/speedtest-tracker/files/compose.yaml b/apps/speedtest-tracker/files/compose.yaml index 3f0aa8f..5a69750 100644 --- a/apps/speedtest-tracker/files/compose.yaml +++ b/apps/speedtest-tracker/files/compose.yaml @@ -11,5 +11,5 @@ services: - APP_KEY=<< app_key >> - DB_CONNECTION=sqlite volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config restart: unless-stopped diff --git a/apps/speedtest-tracker/template.json b/apps/speedtest-tracker/template.json index 35e4b58..953b145 100644 --- a/apps/speedtest-tracker/template.json +++ b/apps/speedtest-tracker/template.json @@ -40,9 +40,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/spoolman/files/compose.yaml b/apps/spoolman/files/compose.yaml index 82e9581..c7a89f5 100644 --- a/apps/spoolman/files/compose.yaml +++ b/apps/spoolman/files/compose.yaml @@ -7,5 +7,5 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/data:/home/app/.local/share/spoolman + - << appdata_dir >>/<< service_name >>/data:/home/app/.local/share/spoolman restart: unless-stopped diff --git a/apps/spoolman/template.json b/apps/spoolman/template.json index 21e7756..87e1fc7 100644 --- a/apps/spoolman/template.json +++ b/apps/spoolman/template.json @@ -37,9 +37,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/stirling-pdf/files/compose.yaml b/apps/stirling-pdf/files/compose.yaml index 69039e1..c72c65d 100644 --- a/apps/stirling-pdf/files/compose.yaml +++ b/apps/stirling-pdf/files/compose.yaml @@ -5,6 +5,6 @@ services: ports: - "<< port >>:8080" volumes: - - << data_dir >>/<< service_name >>/configs:/configs - - << data_dir >>/<< service_name >>/logs:/logs + - << appdata_dir >>/<< service_name >>/configs:/configs + - << appdata_dir >>/<< service_name >>/logs:/logs restart: unless-stopped diff --git a/apps/stirling-pdf/template.json b/apps/stirling-pdf/template.json index 36ce866..8305489 100644 --- a/apps/stirling-pdf/template.json +++ b/apps/stirling-pdf/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/suggestarr/files/compose.yaml b/apps/suggestarr/files/compose.yaml new file mode 100644 index 0000000..0775ac6 --- /dev/null +++ b/apps/suggestarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ciuse99/suggestarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/app/config + ports: + - "<< port >>:5000" + restart: unless-stopped diff --git a/apps/suggestarr/template.json b/apps/suggestarr/template.json new file mode 100644 index 0000000..5a097f5 --- /dev/null +++ b/apps/suggestarr/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "SuggestArr", + "description": "Kijkt wat er gekeken is en zet automatisch aanbevelingen klaar in Sonarr en Radarr.", + "tags": [ + "media", + "aanbevelingen" + ], + "icon": { + "provider": "selfhst", + "id": "suggestarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "suggestarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8116, + "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 instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/syncthing/files/compose.yaml b/apps/syncthing/files/compose.yaml index 58e89c2..dcf6e85 100644 --- a/apps/syncthing/files/compose.yaml +++ b/apps/syncthing/files/compose.yaml @@ -11,6 +11,6 @@ services: - PUID=<< puid >> - PGID=<< pgid >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config - << sync_dir >>:/data restart: unless-stopped diff --git a/apps/syncthing/template.json b/apps/syncthing/template.json index d9fe6dd..8add16c 100644 --- a/apps/syncthing/template.json +++ b/apps/syncthing/template.json @@ -47,9 +47,9 @@ "description": "Poort voor apparaat-tot-apparaat synchronisatie" }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Map voor Syncthing configuratie" diff --git a/apps/tandoor/files/compose.yaml b/apps/tandoor/files/compose.yaml index 3f5aee5..83db859 100644 --- a/apps/tandoor/files/compose.yaml +++ b/apps/tandoor/files/compose.yaml @@ -13,8 +13,8 @@ services: - POSTGRES_USER=tandoor - POSTGRES_PASSWORD=<< db_password >> volumes: - - << data_dir >>/<< service_name >>/staticfiles:/opt/recipes/staticfiles - - << data_dir >>/<< service_name >>/mediafiles:/opt/recipes/mediafiles + - << appdata_dir >>/<< service_name >>/staticfiles:/opt/recipes/staticfiles + - << appdata_dir >>/<< service_name >>/mediafiles:/opt/recipes/mediafiles depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/tandoor/template.json b/apps/tandoor/template.json index 89337c8..396059b 100644 --- a/apps/tandoor/template.json +++ b/apps/tandoor/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/tautulli/files/compose.yaml b/apps/tautulli/files/compose.yaml new file mode 100644 index 0000000..c203466 --- /dev/null +++ b/apps/tautulli/files/compose.yaml @@ -0,0 +1,14 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/tautulli:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + ports: + - "<< port >>:8181" + restart: unless-stopped diff --git a/apps/tautulli/template.json b/apps/tautulli/template.json new file mode 100644 index 0000000..ad050f8 --- /dev/null +++ b/apps/tautulli/template.json @@ -0,0 +1,79 @@ +{ + "kind": "compose", + "metadata": { + "name": "Tautulli", + "description": "Laat zien wie wat kijkt op je Plex-server, met grafieken en meldingen.", + "tags": [ + "media", + "statistiek", + "monitoring" + ], + "icon": { + "provider": "selfhst", + "id": "tautulli" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "monitoring" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "tautulli", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8181, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/tdarr/files/compose.yaml b/apps/tdarr/files/compose.yaml new file mode 100644 index 0000000..9a318c7 --- /dev/null +++ b/apps/tdarr/files/compose.yaml @@ -0,0 +1,21 @@ +services: + << service_name >>: + image: ghcr.io/haveagitgat/tdarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + - serverIP=0.0.0.0 + - serverPort=8266 + - webUIPort=8265 + - internalNode=true + volumes: + - << appdata_dir >>/<< service_name >>:/app/server + - << data_root >>:/data + - << appdata_dir >>/<< service_name >>-configs:/app/configs + ports: + - "<< port >>:8265" + - "<< port_server >>:8266" + restart: unless-stopped diff --git a/apps/tdarr/template.json b/apps/tdarr/template.json new file mode 100644 index 0000000..78fd59f --- /dev/null +++ b/apps/tdarr/template.json @@ -0,0 +1,94 @@ +{ + "kind": "compose", + "metadata": { + "name": "Tdarr", + "description": "Zet je bibliotheek om naar een zuiniger formaat, verdeeld over meerdere machines als je wilt.", + "tags": [ + "media", + "encoding" + ], + "icon": { + "provider": "selfhst", + "id": "tdarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "tdarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8265, + "required": true + }, + { + "name": "port_server", + "type": "int", + "title": "Serverpoort", + "default": 8266, + "required": true, + "description": "Waar de rekenknooppunten verbinding mee maken" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/technitium-dns/files/compose.yaml b/apps/technitium-dns/files/compose.yaml index 46d3a1b..9f27ff8 100644 --- a/apps/technitium-dns/files/compose.yaml +++ b/apps/technitium-dns/files/compose.yaml @@ -10,7 +10,7 @@ services: - TZ=<< timezone >> - DNS_SERVER_ADMIN_PASSWORD=<< admin_password >> volumes: - - << data_dir >>/<< service_name >>/config:/etc/dns + - << appdata_dir >>/<< service_name >>/config:/etc/dns sysctls: - net.ipv4.ip_local_port_range=1024 65000 restart: unless-stopped diff --git a/apps/technitium-dns/template.json b/apps/technitium-dns/template.json index 9f24bc0..a881e8f 100644 --- a/apps/technitium-dns/template.json +++ b/apps/technitium-dns/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/traefik/files/compose.yaml b/apps/traefik/files/compose.yaml index eb30de2..d1b8f67 100644 --- a/apps/traefik/files/compose.yaml +++ b/apps/traefik/files/compose.yaml @@ -19,5 +19,5 @@ services: - "<< dashboard_port >>:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - - << data_dir >>/<< service_name >>/letsencrypt:/letsencrypt + - << appdata_dir >>/<< service_name >>/letsencrypt:/letsencrypt restart: unless-stopped diff --git a/apps/traefik/template.json b/apps/traefik/template.json index 5598928..51e2c8d 100644 --- a/apps/traefik/template.json +++ b/apps/traefik/template.json @@ -54,9 +54,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/trailarr/files/compose.yaml b/apps/trailarr/files/compose.yaml new file mode 100644 index 0000000..6f1998b --- /dev/null +++ b/apps/trailarr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: nandyalu/trailarr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:7889" + restart: unless-stopped diff --git a/apps/trailarr/template.json b/apps/trailarr/template.json new file mode 100644 index 0000000..1852c18 --- /dev/null +++ b/apps/trailarr/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "Trailarr", + "description": "Haalt trailers op bij de films en series in Radarr en Sonarr, en zet ze naast je media.", + "tags": [ + "media", + "trailers" + ], + "icon": { + "provider": "selfhst", + "id": "trailarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "trailarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 7889, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/transmission/files/compose.yaml b/apps/transmission/files/compose.yaml new file mode 100644 index 0000000..5c713b1 --- /dev/null +++ b/apps/transmission/files/compose.yaml @@ -0,0 +1,17 @@ +services: + << service_name >>: + image: lscr.io/linuxserver/transmission:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:9091" + - "<< port_torrent >>:51413" + - "<< port_torrent >>:51413/udp" + restart: unless-stopped diff --git a/apps/transmission/template.json b/apps/transmission/template.json new file mode 100644 index 0000000..948909e --- /dev/null +++ b/apps/transmission/template.json @@ -0,0 +1,95 @@ +{ + "kind": "compose", + "metadata": { + "name": "Transmission", + "description": "Sobere, stabiele torrentclient. Weinig knoppen, doet gewoon zijn werk.", + "tags": [ + "torrents", + "downloaden" + ], + "icon": { + "provider": "selfhst", + "id": "transmission" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "transmission", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 8114, + "required": true, + "description": "Standaard 9091; hier verplaatst omdat die poort al bezet is" + }, + { + "name": "port_torrent", + "type": "int", + "title": "Inkomende poort", + "default": 6883, + "required": true, + "description": "Zet deze poort open in je router voor betere snelheden" + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/unifi-network/files/compose.yaml b/apps/unifi-network/files/compose.yaml index 174bb2a..68ec96b 100644 --- a/apps/unifi-network/files/compose.yaml +++ b/apps/unifi-network/files/compose.yaml @@ -12,7 +12,7 @@ services: - MONGO_PORT=27017 - MONGO_DBNAME=unifi volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>/config:/config ports: - "<< port_ui >>:8443" - "<< port_inform >>:8080" diff --git a/apps/unifi-network/template.json b/apps/unifi-network/template.json index fbc0fcb..f320d8f 100644 --- a/apps/unifi-network/template.json +++ b/apps/unifi-network/template.json @@ -65,9 +65,9 @@ "description": "Gebruikt om Unifi-apparaten op het lokale netwerk automatisch te ontdekken." }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true, "description": "Basismap voor configuratie en database" diff --git a/apps/unpackerr/files/compose.yaml b/apps/unpackerr/files/compose.yaml new file mode 100644 index 0000000..85cb2cb --- /dev/null +++ b/apps/unpackerr/files/compose.yaml @@ -0,0 +1,16 @@ +services: + << service_name >>: + image: ghcr.io/unpackerr/unpackerr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UN_SONARR_0_URL=<< sonarr_url >> + - UN_SONARR_0_API_KEY=<< sonarr_apikey >> + - UN_RADARR_0_URL=<< radarr_url >> + - UN_RADARR_0_API_KEY=<< radarr_apikey >> + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + restart: unless-stopped diff --git a/apps/unpackerr/template.json b/apps/unpackerr/template.json new file mode 100644 index 0000000..92df8ae --- /dev/null +++ b/apps/unpackerr/template.json @@ -0,0 +1,128 @@ +{ + "kind": "compose", + "metadata": { + "name": "Unpackerr", + "description": "Pakt gedownloade rar-archieven uit zodra ze klaar zijn, en ruimt de restanten op.", + "tags": [ + "downloaden", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "unpackerr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "downloaden" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "unpackerr", + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + }, + { + "title": "Koppelingen", + "items": [ + { + "name": "sonarr_url", + "type": "str", + "title": "Sonarr", + "default": "http://sonarr:8989", + "required": false, + "connect": { + "app": "sonarr", + "scheme": "http", + "port": 8989 + }, + "help": "Het adres waarop Unpackerr Sonarr kan bereiken. Draaien ze allebei op hetzelfde gedeelde netwerk, dan is de containernaam genoeg." + }, + { + "name": "sonarr_apikey", + "type": "str", + "title": "Sonarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Sonarr onder Settings → General" + }, + { + "name": "radarr_url", + "type": "str", + "title": "Radarr", + "default": "http://radarr:7878", + "required": false, + "connect": { + "app": "radarr", + "scheme": "http", + "port": 7878 + }, + "help": "Het adres waarop Unpackerr Radarr kan bereiken." + }, + { + "name": "radarr_apikey", + "type": "str", + "title": "Radarr API-sleutel", + "default": "", + "required": false, + "secret": true, + "description": "Te vinden in Radarr onder Settings → General" + } + ] + } + ] +} diff --git a/apps/uptime-kuma/files/compose.yaml b/apps/uptime-kuma/files/compose.yaml index e9027da..e7af659 100644 --- a/apps/uptime-kuma/files/compose.yaml +++ b/apps/uptime-kuma/files/compose.yaml @@ -5,5 +5,5 @@ services: ports: - "<< port >>:3001" volumes: - - << data_dir >>/<< service_name >>/data:/app/data + - << appdata_dir >>/<< service_name >>/data:/app/data restart: unless-stopped diff --git a/apps/uptime-kuma/template.json b/apps/uptime-kuma/template.json index e8f23c3..185eacb 100644 --- a/apps/uptime-kuma/template.json +++ b/apps/uptime-kuma/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/vaultwarden/files/compose.yaml b/apps/vaultwarden/files/compose.yaml index 53e92b2..0dfe080 100644 --- a/apps/vaultwarden/files/compose.yaml +++ b/apps/vaultwarden/files/compose.yaml @@ -11,5 +11,5 @@ services: - ADMIN_TOKEN=<< admin_token >> <% endif %> volumes: - - << data_dir >>/<< service_name >>/data:/data + - << appdata_dir >>/<< service_name >>/data:/data restart: unless-stopped diff --git a/apps/vaultwarden/template.json b/apps/vaultwarden/template.json index 7f7b21c..9339431 100644 --- a/apps/vaultwarden/template.json +++ b/apps/vaultwarden/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true } diff --git a/apps/vikunja/files/compose.yaml b/apps/vikunja/files/compose.yaml index 1690f86..c1c7bbc 100644 --- a/apps/vikunja/files/compose.yaml +++ b/apps/vikunja/files/compose.yaml @@ -24,7 +24,7 @@ services: - VIKUNJA_SERVICE_JWTSECRET=<< jwt_secret >> - VIKUNJA_SERVICE_TIMEZONE=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/files:/app/vikunja/files + - << appdata_dir >>/<< service_name >>/files:/app/vikunja/files depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/vikunja/template.json b/apps/vikunja/template.json index e0fe431..6b19ef6 100644 --- a/apps/vikunja/template.json +++ b/apps/vikunja/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/wallabag/files/compose.yaml b/apps/wallabag/files/compose.yaml index a0d33d8..a850e14 100644 --- a/apps/wallabag/files/compose.yaml +++ b/apps/wallabag/files/compose.yaml @@ -14,7 +14,7 @@ services: - SYMFONY__ENV__DATABASE_PASSWORD=<< db_password >> - SYMFONY__ENV__DOMAIN_NAME=<< app_url >> volumes: - - << data_dir >>/<< service_name >>/images:/var/www/wallabag/web/assets/images + - << appdata_dir >>/<< service_name >>/images:/var/www/wallabag/web/assets/images depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/wallabag/template.json b/apps/wallabag/template.json index b3e8849..1fa5258 100644 --- a/apps/wallabag/template.json +++ b/apps/wallabag/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/wg-easy/files/compose.yaml b/apps/wg-easy/files/compose.yaml index 6fa3f00..171119a 100644 --- a/apps/wg-easy/files/compose.yaml +++ b/apps/wg-easy/files/compose.yaml @@ -11,7 +11,7 @@ services: - PASSWORD_HASH=<< password_hash >> - WG_PORT=<< vpn_port >> volumes: - - << data_dir >>/<< service_name >>/config:/etc/wireguard + - << appdata_dir >>/<< service_name >>/config:/etc/wireguard cap_add: - NET_ADMIN - SYS_MODULE diff --git a/apps/wg-easy/template.json b/apps/wg-easy/template.json index 44c6fdf..8825eb4 100644 --- a/apps/wg-easy/template.json +++ b/apps/wg-easy/template.json @@ -39,9 +39,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/whisparr/files/compose.yaml b/apps/whisparr/files/compose.yaml new file mode 100644 index 0000000..b87a301 --- /dev/null +++ b/apps/whisparr/files/compose.yaml @@ -0,0 +1,15 @@ +services: + << service_name >>: + image: ghcr.io/hotio/whisparr:latest + container_name: << service_name >> + environment: + - PUID=<< puid >> + - PGID=<< pgid >> + - TZ=<< timezone >> + - UMASK=002 + volumes: + - << appdata_dir >>/<< service_name >>:/config + - << data_root >>:/data + ports: + - "<< port >>:6969" + restart: unless-stopped diff --git a/apps/whisparr/template.json b/apps/whisparr/template.json new file mode 100644 index 0000000..cc1de24 --- /dev/null +++ b/apps/whisparr/template.json @@ -0,0 +1,86 @@ +{ + "kind": "compose", + "metadata": { + "name": "Whisparr", + "description": "Dezelfde automatisering als Sonarr en Radarr, gericht op materiaal voor volwassenen.", + "tags": [ + "media", + "automatisering" + ], + "icon": { + "provider": "selfhst", + "id": "whisparr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "whisparr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 6969, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "data_root", + "type": "str", + "title": "Gedeelde datamap", + "default": "/mnt/data", + "required": true, + "description": "Eén map met je media én je downloads, gekoppeld als /data", + "help": "Media en downloads horen onder één map te staan, die als /data in elke container komt. Alleen dan kan een voltooide download met een hardlink naar je bibliotheek: geen kopie, geen dubbele opslag, en je torrent blijft seeden. Zet je ze op gescheiden paden, dan kopieert elke download opnieuw. 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; bepaalt de eigenaar van de bestanden" + }, + { + "name": "pgid", + "type": "int", + "title": "Groeps-ID (PGID)", + "default": 1000, + "required": true + } + ] + } + ] +} diff --git a/apps/wikijs/files/compose.yaml b/apps/wikijs/files/compose.yaml index 0a57aea..08400df 100644 --- a/apps/wikijs/files/compose.yaml +++ b/apps/wikijs/files/compose.yaml @@ -13,7 +13,7 @@ services: - DB_PASS=<< db_password >> - DB_NAME=wiki volumes: - - << data_dir >>/<< service_name >>/content:/wiki/data/content + - << appdata_dir >>/<< service_name >>/content:/wiki/data/content depends_on: - << service_name >>-db restart: unless-stopped diff --git a/apps/wikijs/template.json b/apps/wikijs/template.json index c21e152..afc93bc 100644 --- a/apps/wikijs/template.json +++ b/apps/wikijs/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/wizarr/files/compose.yaml b/apps/wizarr/files/compose.yaml new file mode 100644 index 0000000..add104b --- /dev/null +++ b/apps/wizarr/files/compose.yaml @@ -0,0 +1,11 @@ +services: + << service_name >>: + image: ghcr.io/wizarrrr/wizarr:latest + container_name: << service_name >> + environment: + - TZ=<< timezone >> + volumes: + - << appdata_dir >>/<< service_name >>:/data/database + ports: + - "<< port >>:5690" + restart: unless-stopped diff --git a/apps/wizarr/template.json b/apps/wizarr/template.json new file mode 100644 index 0000000..51ff7b1 --- /dev/null +++ b/apps/wizarr/template.json @@ -0,0 +1,58 @@ +{ + "kind": "compose", + "metadata": { + "name": "Wizarr", + "description": "Nodigt nieuwe gebruikers uit voor Plex, Jellyfin of Emby met een uitnodigingslink, inclusief uitleg voor de nieuwkomer.", + "tags": [ + "media", + "gebruikers" + ], + "icon": { + "provider": "selfhst", + "id": "wizarr" + }, + "version": { + "name": "latest" + }, + "categories": [ + "media", + "beheer" + ] + }, + "variables": [ + { + "title": "Algemeen", + "items": [ + { + "name": "service_name", + "type": "str", + "title": "Servicenaam", + "default": "wizarr", + "required": true + }, + { + "name": "port", + "type": "int", + "title": "Webinterface", + "default": 5690, + "required": true + }, + { + "name": "appdata_dir", + "type": "str", + "title": "Appdata-map", + "default": "/opt/serverup/appdata", + "required": true, + "description": "Basismap voor de instellingen van deze app" + }, + { + "name": "timezone", + "type": "str", + "title": "Tijdzone", + "default": "Europe/Amsterdam", + "required": true + } + ] + } + ] +} diff --git a/apps/zigbee2mqtt/files/compose.yaml b/apps/zigbee2mqtt/files/compose.yaml index 83848d6..1fea146 100644 --- a/apps/zigbee2mqtt/files/compose.yaml +++ b/apps/zigbee2mqtt/files/compose.yaml @@ -8,7 +8,7 @@ services: - TZ=<< timezone >> - ZIGBEE2MQTT_CONFIG_MQTT_SERVER=<< mqtt_server >> volumes: - - << data_dir >>/<< service_name >>/data:/app/data + - << appdata_dir >>/<< service_name >>/data:/app/data - /run/udev:/run/udev:ro devices: - << usb_device >>:/dev/ttyACM0 diff --git a/apps/zigbee2mqtt/template.json b/apps/zigbee2mqtt/template.json index fa8c0bb..51130ba 100644 --- a/apps/zigbee2mqtt/template.json +++ b/apps/zigbee2mqtt/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/apps/zwave-js-ui/files/compose.yaml b/apps/zwave-js-ui/files/compose.yaml index 143fa6c..2ffe225 100644 --- a/apps/zwave-js-ui/files/compose.yaml +++ b/apps/zwave-js-ui/files/compose.yaml @@ -8,7 +8,7 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/store:/usr/src/app/store + - << appdata_dir >>/<< service_name >>/store:/usr/src/app/store devices: - << usb_device >>:/dev/zwave restart: unless-stopped diff --git a/apps/zwave-js-ui/template.json b/apps/zwave-js-ui/template.json index 728fbcb..757b283 100644 --- a/apps/zwave-js-ui/template.json +++ b/apps/zwave-js-ui/template.json @@ -38,9 +38,9 @@ "required": true }, { - "name": "data_dir", + "name": "appdata_dir", "type": "str", - "title": "Data directory", + "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true }, diff --git a/docs/README.md b/docs/README.md index a95aebe..45e790f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -5,6 +5,7 @@ | [installeren.md](installeren.md) | Installeren met één regel, alle opties van het script, bijwerken en verwijderen. | | [beveiliging.md](beveiliging.md) | Accounts, rollen, reverse-proxy-SSO en TLS. **Lees dit voordat je Server Up van buiten je netwerk bereikbaar maakt** — toegang tot de interface staat gelijk aan root op de host. | | [apps-maken.md](apps-maken.md) | Eigen apps toevoegen: het volledige `template.json`-formaat, de compose-syntaxis, apps aan elkaar koppelen en onderdelen optioneel maken. | +| [arr-stack.md](arr-stack.md) | Media-automatisering: los of gebundeld installeren, waarom alles één `/data`-map deelt, downloaden via een VPN. | | [netwerken.md](netwerken.md) | Stacks een eigen IP-adres geven in je LAN met macvlan of ipvlan. Inclusief de valkuil dat de host zijn eigen macvlan-containers niet bereikt. | | [backups.md](backups.md) | Wat er wél en niet in een backup zit, terugzetten, bewaarbeleid, geplande backups, controleren, downloaden en een tweede bestemming. | | [pangolin.md](pangolin.md) | Publieke adressen voor je apps via een Pangolin-tunnel, zonder poorten open te zetten. | diff --git a/docs/apps-maken.md b/docs/apps-maken.md index 0b0381c..098f612 100644 --- a/docs/apps-maken.md +++ b/docs/apps-maken.md @@ -39,7 +39,7 @@ Zet die map in `apps/`, of in je eigen git-repo die je toevoegt bij "default": "mijn-app", "required": true}, {"name": "port", "type": "int", "title": "Web poort", "default": 8200, "required": true}, - {"name": "data_dir", "type": "str", "title": "Data directory", + {"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true}, {"name": "timezone", "type": "str", "title": "Tijdzone", "default": "Europe/Amsterdam", "required": true} @@ -61,7 +61,7 @@ services: environment: - TZ=<< timezone >> volumes: - - << data_dir >>/<< service_name >>/config:/config + - << appdata_dir >>/<< service_name >>:/config restart: unless-stopped ``` @@ -192,7 +192,7 @@ waar een veld hoort, en meestal klopt dat: | Stap | Wat er terechtkomt | |---|---| -| **Basis** | `service_name`, poortvelden (type `int` met `port` in de naam), `data_dir`, `timezone`, `puid`/`pgid` | +| **Basis** | `service_name`, poortvelden (type `int` met `port` in de naam), `appdata_dir`, `data_root`, `timezone`, `puid`/`pgid` | | **Verbinden** | velden met `connect` | | **Toegang** | alles wat als geheim geldt, plus gebruikersnamen en e-mailadressen | | **Instellingen** | de rest | @@ -302,12 +302,14 @@ Voor stacks met meerdere componenten kun je per groep een schakelaar zetten: ```json { - "title": "Bazarr — ondertitels", + "title": "Bazarr", + "section": "Ondertitels en verwerking", "toggle": "enable_bazarr", "toggle_default": true, "description": "Haalt automatisch ondertitels op", "items": [ - {"name": "port_bazarr", "type": "int", "title": "Poort", "default": 6767} + {"name": "port_bazarr", "type": "int", "title": "Poort", "default": 6767, + "advanced": true, "step": "instellingen"} ] } ``` @@ -326,8 +328,22 @@ In het compose-bestand gebruik je die schakelaar als voorwaarde: `toggle_default` bepaalt of het onderdeel standaard aan staat. Zonder die sleutel staat hij aan. -De ARR-stack (`apps/arr-stack`) gebruikt dit voor twintig onderdelen en is het -beste voorbeeld om van af te kijken. +**Vanaf twee schakelbare groepen krijgt het kiezen een eigen eerste stap.** Alle +schakelaars staan dan bij elkaar in *Onderdelen*, en `section` bepaalt onder welk +kopje ze daar terechtkomen — bij vijftig onderdelen is dat het verschil tussen +een overzicht en een lijst waar je in verdwaalt. Bij één schakelbare groep blijft +de schakelaar gewoon bij zijn eigen velden staan. + +De velden van een onderdeel zet je op `"step": "instellingen"` en meestal ook op +`"advanced": true`: de poorten kloppen al, en ze horen niet in het eerste scherm +te staan als je door vijftig onderdelen loopt. De schakelaar zélf wordt nooit +geavanceerd — dat is juist wat je eerst kiest. Wil je een héél onderdeel achter +het uitklapblok, gebruik dan `toggle_advanced`. + +De ARR-stack (`apps/arr-stack`) gebruikt dit voor negenenveertig onderdelen en is +het beste voorbeeld om van af te kijken. Let op: die wordt gegenereerd — pas +`tools/arr_sjablonen.py` aan en draai dat script, anders draait +`tests/test_arr_sjablonen.py` je wijziging terug. --- @@ -336,7 +352,15 @@ beste voorbeeld om van af te kijken. **Poorten.** Kies een standaardpoort die nog niet door een andere app gebruikt wordt. De testsuite controleert dat, en meldt welke botsen. Alternatieven voor dezelfde taak (twee reverse proxies, twee DNS-blokkers) mogen wel dezelfde poort -delen; die staan in een allowlist in `tests/test_apps.py`. +delen; die staan in een allowlist in `tests/test_apps.py`. Een onderdeel van de +ARR-stack mag dezelfde poort hebben als zijn losse sjabloon — dat is dezelfde +container, alleen anders verpakt. + +**De appdata-map heet `appdata_dir`, de gedeelde datamap `data_root`.** De eerste +is de plek waar déze app zijn instellingen bewaart (`/config`), de tweede is de +gedeelde berg met media en downloads die als `/data` in elke container komt. Zit +je app aan dezelfde bibliotheek als de *arr-apps, gebruik dan `data_root` — en +géén losse `/downloads`- of `/tv`-mount, want daarmee sneuvelen hardlinks. **`network_mode`.** Heeft een service `network_mode: host` of `network_mode: service:…`, dan kan hij niet aan het gedeelde netwerk hangen. diff --git a/docs/arr-stack.md b/docs/arr-stack.md new file mode 100644 index 0000000..4e14769 --- /dev/null +++ b/docs/arr-stack.md @@ -0,0 +1,106 @@ +# De ARR-stack + +Media-automatisering bestaat uit een stuk of tien tot vijftig losse programma's +die elkaar aanvullen: Sonarr houdt series bij, Radarr films, Prowlarr regelt de +indexers, een downloadclient haalt het binnen, Bazarr zoekt ondertitels. In de +store staat elk van die programma's als losse app, én gebundeld als **ARR-stack** +waarin je per onderdeel een schakelaar omzet. + +## Los of gebundeld? + +Het zijn dezelfde containers. De stack is één compose-project met één +instellingenscherm; los installeren geeft je per app een eigen stack die je apart +kunt bijwerken, herstarten en backuppen. + +| | Los | ARR-stack | +|---|---|---| +| Iets bijzetten | opnieuw installeren uit de store | schakelaar aan, opnieuw instellen | +| Bijwerken | per app | de hele stack in één keer | +| Backup | per app | alles samen | +| Overzicht | een tegel per app | één tegel met alle containers | + +Weet je nog niet wat je nodig hebt, begin dan met de stack: je zet er later +onderdelen bij zonder opnieuw te beginnen. Draai je er al een paar en wil je er +één bij, installeer die dan los. + +## Eén map: /data + +Alles deelt één map, die als `/data` in elke container komt: + +``` +/mnt/data/ +├── media/ +│ ├── films/ +│ ├── series/ +│ ├── muziek/ +│ └── boeken/ +├── torrents/ # blijven seeden na afloop +└── usenet/ +``` + +**Dit is geen smaakkwestie.** Staan je downloads en je bibliotheek op +verschillende mounts — `/downloads` en `/tv` bijvoorbeeld — dan ziet Sonarr twee +verschillende bestandssystemen, ook al staat het op dezelfde schijf. Er kan dan +geen hardlink gemaakt worden en elke voltooide download wordt **gekopieerd** naar +je bibliotheek. Dat is traag, en je hebt de aflevering tijdelijk twee keer op je +schijf staan. Verwijder je daarna de download, dan stopt het seeden. + +Met één gedeelde `/data`-mount is het verplaatsen een hardlink: klaar in een +oogwenk, geen extra ruimte, en je torrent blijft doordraaien. + +Alle containers draaien met `UMASK=002`, zodat wat de één aanmaakt door de ander +gelezen en geschreven kan worden. Zorg dat de map van de PUID/PGID is die je bij +het installeren opgeeft (`id -u` en `id -g` op je server). + +## Downloaden via een VPN + +Zet je **Gluetun** aan, dan gaan de downloadclients in de netwerknamespace van +die container zitten: al hun verkeer loopt door de VPN, en hun webinterfaces +bereik je via de poorten van Gluetun. Dat gebeurt automatisch zodra je de +schakelaar omzet. + +Wat er bewust *niet* gebeurt: de inkomende torrentpoort op de host publiceren. +Achter een VPN regel je dat met de port forwarding van je aanbieder — zou je hem +op de host zetten, dan komt dat verkeer langs de tunnel binnen en botsen twee +torrentclients bovendien meteen op poort 6881. + +Je hebt gegevens van je VPN-aanbieder nodig: bij WireGuard een privésleutel en +een adres, bij OpenVPN een gebruikersnaam en wachtwoord. Die vul je in bij de +stap *Toegang* en ze komen in `.env` terecht, niet in het compose-bestand. + +## Het invulmenu + +De stack heeft negenenveertig schakelbare onderdelen, dus het formulier begint +met **Onderdelen**: alle schakelaars bij elkaar, gegroepeerd per soort. Wat je +daar aanzet, bepaalt wat je in de volgende stappen te zien krijgt. + +1. **Onderdelen** — wat wil je draaien +2. **Basis** — mappen, tijdzone, PUID/PGID +3. **Verbinden** — gedeelde netwerken, en eventueel een eigen IP-adres per container +4. **Instellingen** — de poorten (staan al goed) en de VPN-instellingen +5. **Toegang** — sleutels en wachtwoorden +6. **Controleren** — het compose-bestand zoals het straks op schijf komt + +## Een eigen adres per container + +Bij *Verbinden* kun je containers een eigen IP-adres in je LAN geven in plaats +van een poort op de host. Dat gaat **per container**: geef Sonarr en Radarr elk +een adres en laat de rest op zijn hostpoort staan. Containers zonder adres houden +hun poortmapping gewoon. + +Zie [netwerken.md](netwerken.md) voor het aanmaken van zo'n netwerk en voor de +valkuil dat de host zijn eigen macvlan-containers niet kan bereiken. + +## De sjablonen worden gegenereerd + +Elk onderdeel bestaat twee keer: als losse app in `apps//` en als +schakelaar in `apps/arr-stack/`. Dat soort verdubbeling loopt uit elkaar, dus +beide komen uit één bron: + +```bash +python3 tools/arr_sjablonen.py +``` + +`tests/test_arr_sjablonen.py` draait dat opnieuw en vergelijkt het met wat er in +`apps/` staat. Pas je een sjabloon met de hand aan, dan faalt die test — bewerk +`tools/arr_sjablonen.py` en draai het script. diff --git a/docs/backups.md b/docs/backups.md index e0e3a2a..2e892a7 100644 --- a/docs/backups.md +++ b/docs/backups.md @@ -29,7 +29,7 @@ niet de inhoud ervan herstellen. Wil je dat ook, dan zijn er twee routes: 1. **Bind mounts in plaats van named volumes.** Staat je data in `/opt/serverup/appdata/` en zit die map binnen je stackmap, dan gaat hij - wél mee. De meeste templates in `apps/` gebruiken `data_dir` daarvoor. + wél mee. De meeste templates in `apps/` gebruiken `appdata_dir` daarvoor. 2. **Een aparte volume-backup** met bijvoorbeeld `restic` of `borg` naast Server Up. Voor grote datasets is dat sowieso beter dan een tar per keer. diff --git a/docs/netwerken.md b/docs/netwerken.md index 001a590..9b6b246 100644 --- a/docs/netwerken.md +++ b/docs/netwerken.md @@ -137,7 +137,8 @@ services: services: vaultwarden: vaultwarden: image: vaultwarden/server image: vaultwarden/server ports: networks: - - "8222:80" lan: + - "8222:80" default: + lan: ipv4_address: 192.168.1.240 networks: lan: @@ -145,11 +146,25 @@ services: services: ``` De poortmapping verdwijnt — die heeft geen functie meer. Vaultwarden luistert op -poort 80 en is bereikbaar op `http://192.168.1.240`. +poort 80 en is bereikbaar op `http://192.168.1.240`. Het `default`-netwerk blijft +erbij staan: zodra een container een `networks`-blok krijgt, vervalt zijn +lidmaatschap van het netwerk van de stack, en dan vindt hij zijn eigen database +niet meer. -Bestaat een stack uit meerdere containers, dan krijgt de container die poorten -publiceerde het vaste adres; de rest komt zonder vast adres in hetzelfde netwerk, -zodat ze elkaar op servicenaam blijven vinden. +### Meerdere containers, meerdere adressen + +Bestaat een stack uit meerdere containers, dan kies je bij **Adres per container** +wie er een eigen adres krijgt. Dat hoeft niet iedereen te zijn: geef Sonarr en +Radarr een adres en laat de rest op zijn hostpoort staan. + +**Een container die je geen adres geeft, houdt zijn poortmapping.** Dat is precies +het verschil met hoe dit eerder werkte: toen raakte élke container in de stack +zijn poorten kwijt zodra er één een adres kreeg, en waren de andere daarna nergens +meer te bereiken. + +Containers met `network_mode` — de downloadclients achter een VPN — slaat Server +Up over. Die delen al de namespace van een andere container, en compose weigert +`network_mode` en `networks` naast elkaar. --- diff --git a/docs/pangolin.md b/docs/pangolin.md index 7d4b924..3906d95 100644 --- a/docs/pangolin.md +++ b/docs/pangolin.md @@ -37,10 +37,16 @@ Server Up doet dan twee dingen: 1. een *resource* aanmaken — het publieke adres, standaard `.`; 2. een *target* aanmaken — waar dat adres naartoe wijst. -Het doel wordt afgeleid: heeft de stack een eigen IP-adres (macvlan), dan dat; +Het doel wordt afgeleid: heeft de container een eigen IP-adres (macvlan), dan dat; anders het adres van de host met de gepubliceerde poort. De URL wordt bij de stack bewaard en daarna in het paneel getoond. +**Bij een stack met meerdere webinterfaces publiceer je per container.** De +ARR-stack heeft er twintig; die krijgen elk hun eigen adres +(`sonarr.`, `radarr.`, …) in plaats van dat de eerste poort in +het bestand de URL opslokt. Server Up haalt de juiste poort uit de gegevens die +bij het installeren zijn bewaard. + --- ## Als het misgaat diff --git a/server-up/app.py b/server-up/app.py index 4783b31..f51b6d4 100644 --- a/server-up/app.py +++ b/server-up/app.py @@ -921,6 +921,7 @@ def api_stack_config(name): fields=_annotate_fields(boilerplates.fields(bron)), values=waarden, network=meta.get("network", ""), ip=meta.get("ip", ""), + ips=meta.get("ips") or {}, connected=bool(meta.get("connected")), app_networks=meta.get("app_networks") or [], source=meta.get("source", ""), repo_id=meta.get("repo_id", ""), @@ -947,6 +948,17 @@ def api_stack_reconfigure(name): net_name = (body.get("network") if "network" in body else meta.get("network")) or "" net_ip = (body.get("ip") if "ip" in body else meta.get("ip")) or "" + net_ips = (body.get("ips") if "ips" in body else meta.get("ips")) or {} + if not isinstance(net_ips, dict): + net_ips = {} + if net_name and net_ips: + net = _network_by_name(net_name) + if net: + al_van_ons = set((meta.get("ips") or {}).values()) | {meta.get("ip") or ""} + net_ips, fout, code = _ip_mapping(net, net_name, net_ips, al_van_ons) + if fout: + return jsonify(ok=False, msg=fout), code + net_ip = "" gedeeld_net = (cfg.load().get("SHARED_NETWORK") or "serverup").strip() if "app_networks" in body or "connect_apps" in body: app_netten = _gekozen_app_netwerken(body, gedeeld_net) @@ -997,9 +1009,20 @@ def api_stack_reconfigure(name): f"{len(env_geheim)} geheim(en) in .env bijgewerkt") except compose_transform.TransformError as e: jobs.log(qq, "warn", f"Geheimen niet verplaatst: {e}") - if net_name: + try: + poorten_meta = compose_transform.poorten_per_service( + cf.read_text(encoding="utf-8")) if cf else [] + except Exception: + poorten_meta = [] + if net_name and cf: net = _network_by_name(net_name) - if net and net_ip: + if net and net_ips: + cf.write_text(compose_transform.to_dedicated_ips( + cf.read_text(encoding="utf-8"), net_name, net_ips), + encoding="utf-8") + for svc, adres in net_ips.items(): + jobs.log(qq, "ok", f"Eigen IP-adres voor {svc}: {adres}") + elif net and net_ip: cf.write_text(compose_transform.to_dedicated_ip( cf.read_text(encoding="utf-8"), net_name, net_ip), encoding="utf-8") @@ -1028,8 +1051,9 @@ def api_stack_reconfigure(name): _stack_meta_schrijven(d, { "values": zichtbaar, "secret_fields": geheime_namen, "secret_keys": secret_keys, - "network": net_name, "ip": net_ip, + "network": net_name, "ip": net_ip, "ips": net_ips, "app_networks": app_netten, + "service_ports": poorten_meta, "connected": bool(app_netten)}) docker.compose_down(d, log_fn=lf, name=name) @@ -1310,6 +1334,36 @@ def _gekozen_app_netwerken(body: dict, standaard: str) -> list[str]: return [standaard] if verbinden else [] +def _ip_mapping(net: dict, net_naam: str, gevraagd: dict, + eigen=()) -> tuple[dict, str, int]: + """Controleer een mapping container → adres, en vul lege adressen aan. + + Een stack met twintig webinterfaces wil er niet één adres, maar een adres + per container die je van buiten wilt bereiken. `eigen` zijn de adressen die + deze stack zelf al gebruikt — bij herconfigureren mag hij die houden zonder + dat ze als "al in gebruik" gelden. Retourneert + (mapping, foutmelding, http-status). + """ + bezet = (_reserved_ips() | networks.used_ips(net_naam)) - set(eigen) + uit: dict[str, str] = {} + for service, adres in gevraagd.items(): + if not isinstance(service, str) or not service.strip(): + continue + service = service.strip() + adres = (adres or "").strip() if isinstance(adres, str) else "" + if not adres: + adres = networks.next_free_ip(net, bezet) + if not adres: + return {}, f"Geen vrij IP-adres meer voor '{service}'", 400 + if not networks.ip_in_network(adres, net): + return {}, f"{adres} ligt buiten het subnet van '{net_naam}'", 400 + if adres in bezet: + return {}, f"{adres} is al in gebruik", 409 + bezet.add(adres) + uit[service] = adres + return uit, "", 0 + + def _bezette_poorten() -> set[int]: """Alles wat een nieuwe stack in de weg kan zitten. @@ -1406,6 +1460,17 @@ def api_store_preview(): env_preview = "".join(f"{k}={v}\n" for k, v in env_geheim.items()) except Exception as e: preview_files = {"_error": f"render: {e}"} + # Welke containers levert deze keuze op? De interface heeft die namen + # nodig om per container een eigen IP-adres aan te kunnen bieden; + # afleiden uit de veldnamen gaat mis zodra een onderdeel meer dan één + # container heeft. + diensten: list[str] = [] + try: + doc = yaml.safe_load(preview_files.get("compose.yaml") + or preview_files.get("docker-compose.yml") or "") or {} + diensten = [n for n in (doc.get("services") or {})] + except Exception: + diensten = [] return jsonify( ok=True, stack=stack, @@ -1413,6 +1478,7 @@ def api_store_preview(): format="boilerplate", metadata=meta, fields=flds, + services=diensten, preview_files=preview_files, # Backwards-compat voor de oude UI: env_vars=[], images=[], ports=[], @@ -1525,18 +1591,28 @@ def api_store_install(): return jsonify(ok=False, msg="stack vereist") net = None + # Per container een eigen adres. Zonder deze mapping blijft het bij één + # adres voor de hele stack (het gewone geval: apps met één container). + net_ips: dict = {} if net_name: net = _network_by_name(net_name) if not net: return jsonify(ok=False, msg=f"Netwerk '{net_name}' is niet geconfigureerd"), 400 - if not net_ip: - net_ip = networks.next_free_ip(net, _reserved_ips()) - if not net_ip: - return jsonify(ok=False, msg="Geen vrij IP-adres beschikbaar in dit netwerk"), 400 - if not networks.ip_in_network(net_ip, net): - return jsonify(ok=False, msg=f"{net_ip} ligt buiten het subnet van '{net_name}'"), 400 - if net_ip in _reserved_ips() or net_ip in networks.used_ips(net_name): - return jsonify(ok=False, msg=f"{net_ip} is al in gebruik"), 409 + gevraagd = d.get("ips") + if isinstance(gevraagd, dict) and gevraagd: + net_ips, fout, code = _ip_mapping(net, net_name, gevraagd) + if fout: + return jsonify(ok=False, msg=fout), code + net_ip = "" + else: + if not net_ip: + net_ip = networks.next_free_ip(net, _reserved_ips()) + if not net_ip: + return jsonify(ok=False, msg="Geen vrij IP-adres beschikbaar in dit netwerk"), 400 + if not networks.ip_in_network(net_ip, net): + return jsonify(ok=False, msg=f"{net_ip} ligt buiten het subnet van '{net_name}'"), 400 + if net_ip in _reserved_ips() or net_ip in networks.used_ips(net_name): + return jsonify(ok=False, msg=f"{net_ip} is al in gebruik"), 409 # De instantienaam bepaalt de doelmap én de compose-projectnaam. Zonder # controle schrijft `"instance": "../../etc"` buiten de library. if not cfg.safe_name(inst): @@ -1588,6 +1664,7 @@ def api_store_install(): qq = jobs.get_queue(jid) secret_keys: dict = {} velden_bron: list = [] + poorten_meta: list = [] # De waarden zoals er echt mee gerenderd is, inclusief de defaults die # de client niet meestuurde. Alleen die zijn bruikbaar om het formulier # later opnieuw te openen. @@ -1717,21 +1794,39 @@ def api_store_install(): jobs.log(qq, "ok", "Image tags aangepast") # Eigen IP-adres in plaats van poorten op de host + # Onthouden op welke poort de app zelf luistert. Bij een eigen + # IP-adres verdwijnt het ports-blok, en dan is dit de enige manier + # om er later nog naartoe te kunnen wijzen (reverse proxy, tunnel). + try: + cf_poort = docker.find_compose(dest) + if cf_poort: + poorten_meta = compose_transform.poorten_per_service( + cf_poort.read_text(encoding="utf-8")) + except Exception: + poorten_meta = [] + if net: cf = docker.find_compose(dest) if not cf: jobs.log(qq, "error", "Geen compose-bestand om aan te passen") jobs.finish(jid, "error"); jobs.done(qq); return try: - nieuw = compose_transform.to_dedicated_ip( - cf.read_text(encoding="utf-8"), net_name, net_ip) + tekst = cf.read_text(encoding="utf-8") + if net_ips: + nieuw = compose_transform.to_dedicated_ips( + tekst, net_name, net_ips) + else: + nieuw = compose_transform.to_dedicated_ip( + tekst, net_name, net_ip) except compose_transform.TransformError as e: jobs.log(qq, "error", f"Netwerkomzetting mislukt: {e}") jobs.finish(jid, "error"); jobs.done(qq); return cf.write_text(nieuw, encoding="utf-8") - jobs.log(qq, "ok", f"Eigen IP-adres: {net_ip} op netwerk '{net_name}'") - jobs.log(qq, "dim", "Poortmappings verwijderd — de app draait op " - "zijn eigen poort op dit adres.") + for svc, adres in (net_ips or {"": net_ip}).items(): + jobs.log(qq, "ok", f"Eigen IP-adres{f' voor {svc}' if svc else ''}: " + f"{adres} op netwerk '{net_name}'") + jobs.log(qq, "dim", "Poortmappings van die containers verwijderd — ze " + "draaien op hun eigen poort op dat adres.") # Aan het gedeelde netwerk hangen. Zonder dit zit elke stack in # zijn eigen compose-netwerk en vindt geen enkele app een andere. @@ -1790,8 +1885,10 @@ def api_store_install(): # geen andere installatie hetzelfde IP voorgesteld. "network": net_name, "ip": net_ip if net else "", + "ips": net_ips if net else {}, "connected": bool(app_netten), "app_networks": app_netten, + "service_ports": poorten_meta, "categories": meta.get("categories") or [], "tags": meta.get("tags") or [], # Zonder de gebruikte waarden valt het installatieformulier @@ -2075,11 +2172,23 @@ def api_stack_pangolin(name): body = request.json or {} meta = _stack_meta_lezen(d) + # Welke container publiceren we? Een stack als de ARR-stack heeft er twintig + # met een eigen webinterface; zonder deze keuze kreeg altijd de eerste poort + # in het bestand de URL. + service = (body.get("service") or "").strip() # Waar wijst de URL naartoe? Een eigen IP-adres, anders de host op de # gepubliceerde poort. - ip = (body.get("ip") or meta.get("ip") or "").strip() + ip = (body.get("ip") or (meta.get("ips") or {}).get(service) + or meta.get("ip") or "").strip() poort = body.get("port") + if not poort and service: + # Heeft de container een eigen adres, dan luistert hij op zijn interne + # poort; anders is de gepubliceerde poort op de host het doel. + for p in meta.get("service_ports") or []: + if p.get("service") == service: + poort = p.get("container") if ip else (p.get("host") or p.get("container")) + break if not poort: try: poorten = compose_transform.published_ports(docker.read_compose(d)) @@ -2091,21 +2200,30 @@ def api_stack_pangolin(name): ip = (body.get("host_ip") or "").strip() or _eigen_host_ip() if not ip or not poort: return jsonify(ok=False, - msg="Kan niet bepalen waar deze stack draait; vul het " + msg="Kan niet bepalen waar " + f"{service or 'deze stack'} draait; vul het " "adres en de poort zelf in."), 400 + standaard_naam = service or name try: res = pangolin.publiceer( - naam=body.get("name") or name, - subdomein=(body.get("subdomain") or name).strip().lower(), + naam=body.get("name") or standaard_naam, + subdomein=(body.get("subdomain") or standaard_naam).strip().lower(), ip=ip, poort=int(poort), site_id=body.get("site_id"), domein_id=body.get("domain_id", "")) except pangolin.PangolinError as e: audit.log("pangolin", "publish", "error", ref=name, detail=str(e)[:200]) return jsonify(ok=False, msg=str(e)), 400 - _stack_meta_schrijven(d, {"pangolin_url": res.get("url", ""), - "pangolin_resource": res.get("resource_id")}) + # Per container onthouden, zodat Sonarr, Radarr en Prowlarr elk hun eigen + # adres kunnen hebben. Zonder `service` blijft het één URL voor de stack. + urls = dict(meta.get("pangolin_urls") or {}) + urls[service or name] = res.get("url", "") + updates = {"pangolin_urls": urls, + "pangolin_resource": res.get("resource_id")} + if not service: + updates["pangolin_url"] = res.get("url", "") + _stack_meta_schrijven(d, updates) audit.log("pangolin", "publish", "ok", ref=name, detail=res.get("url", "")[:200], ip=request.remote_addr) return jsonify(ok=True, **res) @@ -3023,10 +3141,11 @@ def api_wizard_git(): port_web = int(d.get("port_web") or 3000) port_ssh = int(d.get("port_ssh") or 2222) - data_dir = d.get("data_dir", cfg.load().get("DATA_DIR", "/opt/serverup/appdata")) + appdata_dir = d.get("appdata_dir") or d.get("data_dir") or \ + cfg.load().get("DATA_DIR", "/opt/serverup/appdata") values = { "service_name": "forgejo", - "data_dir": data_dir, + "appdata_dir": appdata_dir, "timezone": "Europe/Amsterdam", "port_web": port_web, "port_ssh": port_ssh, diff --git a/server-up/core/boilerplates.py b/server-up/core/boilerplates.py index b216f20..4f9fff2 100644 --- a/server-up/core/boilerplates.py +++ b/server-up/core/boilerplates.py @@ -83,10 +83,16 @@ def fields(d: Path) -> list[dict]: options (for enum), needs (visibility deps), placeholder, description. """ t = read_template(d) or {} + groepen = t.get("variables", []) or [] + # Vanaf twee schakelbare groepen krijgt het kiezen van onderdelen een eigen + # stap. Bij één groep zou dat een scherm met één vinkje opleveren; dan blijft + # de schakelaar staan waar zijn eigen velden staan. + eigen_stap = sum(1 for g in groepen if g.get("toggle")) >= 2 out: list[dict] = [] - for grp in t.get("variables", []) or []: + for grp in groepen: gname = grp.get("title") or grp.get("name", "") toggle = grp.get("toggle") + sectie = grp.get("section", "") if toggle: # De groepsschakelaar is zelf geen item in template.json, waardoor # hij nergens een startwaarde kreeg en dus altijd uit stond. Als @@ -95,14 +101,19 @@ def fields(d: Path) -> list[dict]: out.append({ "name": toggle, "type": "bool", "title": gname, "group": gname, "group_toggle": toggle, + "section": sectie, "default": bool(grp.get("toggle_default", True)), "required": False, "options": [], "needs": [], "placeholder": "", "description": grp.get("description", ""), "is_group_toggle": True, - # De schakelaar hoort bij de stap waar zijn eigen velden staan; - # die bepalen we pas hieronder, dus voorlopig 'instellingen'. - "step": "instellingen", "credential": "", - "secret": False, "generate": "", "advanced": bool(grp.get("advanced")), + "step": "onderdelen" if eigen_stap else _stap_van_groep(grp), + "credential": "", + "secret": False, "generate": "", + # `advanced` op de groep gaat over zijn vélden; de schakelaar + # zelf is juist het eerste wat je kiest en verdwijnt daar niet + # mee achter het uitklapblok. Wil je hem toch verbergen, dan + # zeg je dat apart met `toggle_advanced`. + "advanced": bool(grp.get("toggle_advanced")), }) groep_geavanceerd = bool(grp.get("advanced")) for item in grp.get("items", []) or []: @@ -113,6 +124,9 @@ def fields(d: Path) -> list[dict]: "title": item.get("title") or item.get("name", ""), "group": gname, "group_toggle": toggle, + # Kopje waaronder de groep in de stap Onderdelen komt te staan, + # zodat vijftig schakelaars niet één lange lijst worden. + "section": sectie, "default": item.get("default"), "required": bool(item.get("required")), "options": cfg.get("options") or [], @@ -149,12 +163,24 @@ def fields(d: Path) -> list[dict]: # ── Indeling in het invulmenu ──────────────────────────────────────────────── -# Vijf vaste stappen voor elke app. Eén stap per groep werkt niet: de mediane -# app heeft één groep en arr-stack heeft er eenentwintig. -STAPPEN = ("basis", "verbinden", "instellingen", "geheimen") +# Vaste stappen voor elke app. Eén stap per groep werkt niet: de mediane app +# heeft één groep en arr-stack heeft er vijftig. 'onderdelen' verschijnt alleen +# bij een sjabloon dat meer dan één schakelbare groep heeft. +STAPPEN = ("onderdelen", "basis", "verbinden", "instellingen", "geheimen") -_BASIS_NAMEN = ("service_name", "data_dir", "timezone", "tz", "puid", "pgid", - "downloads_dir", "media_dir", "config_dir") +_BASIS_NAMEN = ("service_name", "appdata_dir", "data_root", "timezone", "tz", + "puid", "pgid", "umask", "media_dir", "downloads_dir") + + +def _stap_van_groep(grp: dict) -> str: + """Waar hoort de schakelaar van deze groep als hij geen eigen stap krijgt? + + Bij zijn eigen velden — anders staat de schakelaar in een ander scherm dan + waar hij iets doet. Een groep zonder velden valt terug op 'instellingen'. + """ + for item in grp.get("items", []) or []: + return _stap_van(item, grp.get("toggle", "")) + return "instellingen" def _stap_van(item: dict, groep_toggle: str = "") -> str: diff --git a/server-up/core/compose_transform.py b/server-up/core/compose_transform.py index 9780165..7796a69 100644 --- a/server-up/core/compose_transform.py +++ b/server-up/core/compose_transform.py @@ -25,22 +25,74 @@ class TransformError(Exception): pass +def to_dedicated_ips(compose_text: str, network: str, + ips: dict[str, str]) -> str: + """Geef elke genoemde service een eigen adres op `network`. + + Wie in `ips` staat verliest zijn poortmappings — die hebben geen zin meer, + de container is rechtstreeks bereikbaar. **Wie er niet in staat houdt ze.** + Dat verschil is de hele reden dat deze functie bestaat: een stack met twintig + webinterfaces waarvan er één een eigen adres krijgt, verloor voorheen de + poorten van alle andere en was daarna nergens meer te bereiken. + + Services met `network_mode` blijven ongemoeid; die delen al de namespace van + een ander (de downloadclients achter Gluetun) en verdragen geen `networks`. + """ + doc = _laad(compose_text) + services = doc.get("services") + if not isinstance(services, dict) or not services: + raise TransformError("compose bevat geen services") + + onbekend = sorted(set(ips) - set(services)) + if onbekend: + raise TransformError( + f"service{'s' if len(onbekend) > 1 else ''} " + f"{', '.join(repr(n) for n in onbekend)} " + f"{'bestaan' if len(onbekend) > 1 else 'bestaat'} niet in dit compose-bestand") + + toegekend = False + for naam, svc in services.items(): + if not isinstance(svc, dict) or svc.get("network_mode"): + continue + ip = ips.get(naam) + if not ip: + continue + svc.pop("ports", None) + huidig = svc.get("networks") + if isinstance(huidig, dict): + netten = dict(huidig) + elif isinstance(huidig, list): + netten = {n: None for n in huidig} + else: + # Zodra een service een `networks`-blok krijgt, vervalt zijn + # lidmaatschap van het impliciete default-netwerk van de stack. Zonder + # dit zou een container met een eigen adres de rest van zijn eigen + # stack niet meer op naam kunnen vinden. + netten = {"default": None} + netten[network] = {"ipv4_address": ip} + svc["networks"] = netten + toegekend = True + + if toegekend: + # Het netwerk wordt door Server Up beheerd, niet door deze compose-stack. + netwerken = doc.get("networks") + if not isinstance(netwerken, dict): + netwerken = {} + netwerken[network] = {"external": True} + doc["networks"] = netwerken + + return yaml.safe_dump(doc, sort_keys=False, default_flow_style=False, + allow_unicode=True, width=120) + + def to_dedicated_ip(compose_text: str, network: str, ip: str, only_service: str | None = None) -> str: - """Geef het compose-bestand terug met poortmappings vervangen door een IP. + """Eén adres voor één service — de gewone situatie bij een app met één container. - Het IP wordt toegekend aan één service: `only_service` als die is opgegeven, - anders de eerste service die poorten publiceert (en anders de eerste service - überhaupt). Overige services komen zonder vast adres in hetzelfde netwerk, - zodat ze elkaar op servicenaam kunnen blijven vinden. + `only_service` bepaalt wie het adres krijgt; zonder opgave is dat de eerste + service die poorten publiceert, en anders de eerste service überhaupt. """ - try: - doc = yaml.safe_load(compose_text) - except yaml.YAMLError as e: - raise TransformError(f"compose is geen geldige YAML: {e}") from e - if not isinstance(doc, dict): - raise TransformError("compose bevat geen mapping op het hoogste niveau") - + doc = _laad(compose_text) services = doc.get("services") if not isinstance(services, dict) or not services: raise TransformError("compose bevat geen services") @@ -51,25 +103,17 @@ def to_dedicated_ip(compose_text: str, network: str, ip: str, if isinstance(svc, dict) and svc.get("ports")), None) if doel is None: doel = next(iter(services)) - if doel not in services: - raise TransformError(f"service '{doel}' bestaat niet in dit compose-bestand") + return to_dedicated_ips(compose_text, network, {doel: ip}) - for naam, svc in services.items(): - if not isinstance(svc, dict): - continue - # Poorten publiceren heeft geen zin meer — de container is direct - # bereikbaar op zijn eigen adres. - svc.pop("ports", None) - if naam == doel: - svc["networks"] = {network: {"ipv4_address": ip}} - else: - svc["networks"] = [network] - # Het netwerk wordt door Server Up beheerd, niet door deze compose-stack. - doc["networks"] = {network: {"external": True}} - - return yaml.safe_dump(doc, sort_keys=False, default_flow_style=False, - allow_unicode=True, width=120) +def _laad(compose_text: str) -> dict: + try: + doc = yaml.safe_load(compose_text) + except yaml.YAMLError as e: + raise TransformError(f"compose is geen geldige YAML: {e}") from e + if not isinstance(doc, dict): + raise TransformError("compose bevat geen mapping op het hoogste niveau") + return doc def add_shared_network(compose_text: str, network) -> str: @@ -292,6 +336,39 @@ def env_samenvoegen(bestaand: str, nieuw: dict[str, str]) -> str: return "\n".join(uit).strip("\n") + "\n" +def poorten_per_service(compose_text: str) -> list[dict]: + """Welke poort luistert er binnen elke container, en waarop publiceert hij? + + Nodig omdat `to_dedicated_ip()` het `ports`-blok weghaalt: een container met + een eigen IP-adres publiceert niets meer op de host. Wil je daar later + naartoe wijzen — een reverse proxy, een tunnel — dan moet je nog wél weten + op welke poort de app zelf luistert. + """ + try: + doc = yaml.safe_load(compose_text) or {} + except yaml.YAMLError: + return [] + uit = [] + for snaam, svc in (doc.get("services") or {}).items(): + if not isinstance(svc, dict): + continue + for p in svc.get("ports") or []: + s = str(p).strip('"') + proto = "udp" if s.endswith("/udp") else "tcp" + s = s.replace("/udp", "").replace("/tcp", "") + delen = s.split(":") + try: + if len(delen) == 1: # alleen "8080" + host, container = 0, int(delen[0]) + else: + host, container = int(delen[-2]), int(delen[-1]) + except ValueError: + continue # bereik of variabele + uit.append({"service": snaam, "host": host, + "container": container, "proto": proto}) + return uit + + def published_ports(compose_text: str) -> list[str]: """Alle host-poorten die dit compose-bestand publiceert (voor de UI).""" try: diff --git a/server-up/templates/index.html b/server-up/templates/index.html index ba38d8a..eb3bfb7 100644 --- a/server-up/templates/index.html +++ b/server-up/templates/index.html @@ -320,7 +320,15 @@ tailwind.config = { Laden… -