feat(apps): voeg elf ARM64-geschikte apps toe
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 8m14s
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 8m14s
This commit is contained in:
parent
75eb24741f
commit
9008e39fe4
27 changed files with 733 additions and 1 deletions
25
CHANGELOG.md
25
CHANGELOG.md
|
|
@ -1,3 +1,28 @@
|
|||
# v0.8.17-beta — Elf nieuwe apps voor beheer, automatisering en monitoring
|
||||
|
||||
De app-store bevatte nog weinig lichte infrastructuurapps die zowel op een
|
||||
reguliere x86-server als op een 64-bits Raspberry Pi werken. Daarom zijn elf
|
||||
nieuwe templates toegevoegd met expliciete AMD64- en ARM64-ondersteuning.
|
||||
|
||||
- **Remote beheer:** RustDesk Server, MeshCentral en Apache Guacamole. Guacamole
|
||||
genereert bij de eerste start automatisch het officiële PostgreSQL-schema.
|
||||
- **Identiteit en discovery:** LLDAP en Consul bieden respectievelijk een lichte
|
||||
LDAP-directory en service discovery met DNS en healthchecks.
|
||||
- **Monitoring:** VictoriaMetrics en OpenObserve voegen efficiënte opslag toe
|
||||
voor metrics en voor logs, metrics en traces.
|
||||
- **Automatisering:** Activepieces en Windmill bieden visuele workflows,
|
||||
scripts en interne apps. De Windmill-worker krijgt standaard geen toegang tot
|
||||
de Docker-socket.
|
||||
- **Bestandsoverdracht:** PairDrop maakt lokale bestandsoverdracht vanuit de
|
||||
browser mogelijk.
|
||||
- **Nomad als veilig control-plane:** de Nomad-container draait alleen als
|
||||
server met webinterface. Workload-clients horen rechtstreeks op de hosts te
|
||||
worden geïnstalleerd, omdat HashiCorp Nomad-clients in Docker niet officieel
|
||||
ondersteunt.
|
||||
- **Cataloguscontrole:** gerichte tests bewaken dat alle elf apps beschikbaar
|
||||
blijven voor AMD64 en ARM64, dat Nomad geen containerized client wordt en dat
|
||||
Guacamole zijn database vóór de webapp initialiseert.
|
||||
|
||||
# v0.8.16-beta — De startwizard blijft gesloten
|
||||
|
||||
**De knop Sluiten verborg de optionele startwizard alleen tijdelijk.** De
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.8.16-beta
|
||||
0.8.17-beta
|
||||
|
|
|
|||
13
apps/activepieces/files/compose.yaml
Normal file
13
apps/activepieces/files/compose.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: activepieces/activepieces:latest
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port >>:80"
|
||||
environment:
|
||||
- AP_REDIS_TYPE=MEMORY
|
||||
- AP_DB_TYPE=PGLITE
|
||||
- AP_FRONTEND_URL=<< frontend_url >>
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/root/.activepieces
|
||||
restart: unless-stopped
|
||||
24
apps/activepieces/template.json
Normal file
24
apps/activepieces/template.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "Activepieces",
|
||||
"description": "Visuele workflow-automatisering als toegankelijk alternatief voor n8n. Deze lichte één-containeropzet gebruikt PGLite en een geheugenqueue en is bedoeld voor persoonlijk gebruik op één server.",
|
||||
"tags": ["automatisering", "workflows", "integraties", "no-code"],
|
||||
"icon": {"provider": "selfhst", "id": "activepieces"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["productiviteit", "ontwikkeling"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële Activepieces-image ondersteunt AMD64 en ARM64."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "activepieces", "required": true},
|
||||
{"name": "port", "type": "int", "title": "Webinterface", "default": 14003, "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true},
|
||||
{"name": "frontend_url", "type": "str", "title": "Publiek adres", "default": "http://localhost:14003", "required": true, "description": "Gebruik voor webhooks het HTTPS-adres van je reverse proxy."}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
33
apps/consul/files/compose.yaml
Normal file
33
apps/consul/files/compose.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: hashicorp/consul:latest
|
||||
container_name: << service_name >>
|
||||
command:
|
||||
- agent
|
||||
- -server
|
||||
- -bootstrap-expect=1
|
||||
- -ui
|
||||
- -client=0.0.0.0
|
||||
- -advertise=<< advertise_ip >>
|
||||
- -http-port=<< port_http >>
|
||||
- -server-port=<< port_server >>
|
||||
- -serf-lan-port=<< port_lan >>
|
||||
- -serf-wan-port=<< port_wan >>
|
||||
- -dns-port=<< port_dns >>
|
||||
- -node=<< service_name >>
|
||||
environment:
|
||||
- CONSUL_BIND_INTERFACE=eth0
|
||||
ports:
|
||||
- "<< port_http >>:<< port_http >>"
|
||||
- "<< port_server >>:<< port_server >>"
|
||||
- "<< port_lan >>:<< port_lan >>/tcp"
|
||||
- "<< port_lan >>:<< port_lan >>/udp"
|
||||
- "<< port_wan >>:<< port_wan >>/tcp"
|
||||
- "<< port_wan >>:<< port_wan >>/udp"
|
||||
- "<< port_dns >>:<< port_dns >>/tcp"
|
||||
- "<< port_dns >>:<< port_dns >>/udp"
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/consul/data
|
||||
cap_add:
|
||||
- IPC_LOCK
|
||||
restart: unless-stopped
|
||||
33
apps/consul/template.json
Normal file
33
apps/consul/template.json
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "Consul",
|
||||
"description": "Service discovery, DNS en healthchecks met een webinterface. Deze eenvoudige single-serveropzet is geschikt voor een thuislab; gebruik voor productie een oneven cluster van meerdere servers.",
|
||||
"tags": ["service discovery", "dns", "healthchecks", "hashicorp"],
|
||||
"icon": {"provider": "selfhst", "id": "consul"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["netwerk", "beheer", "ontwikkeling"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "HashiCorp publiceert officiële Consul-images voor AMD64 en ARM64."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "consul", "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true},
|
||||
{"name": "advertise_ip", "type": "str", "title": "LAN-IP van deze server", "default": "", "required": true, "description": "Het bereikbare hostadres dat Consul aan agents doorgeeft, bijvoorbeeld 192.168.1.10."}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Poorten",
|
||||
"items": [
|
||||
{"name": "port_http", "type": "int", "title": "HTTP API en webinterface", "default": 8500, "required": true},
|
||||
{"name": "port_server", "type": "int", "title": "Server-RPC", "default": 8300, "required": true},
|
||||
{"name": "port_lan", "type": "int", "title": "LAN-gossip", "default": 8301, "required": true},
|
||||
{"name": "port_wan", "type": "int", "title": "WAN-gossip", "default": 8302, "required": true},
|
||||
{"name": "port_dns", "type": "int", "title": "DNS", "default": 8600, "required": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
58
apps/guacamole/files/compose.yaml
Normal file
58
apps/guacamole/files/compose.yaml
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
services:
|
||||
<< service_name >>-init:
|
||||
image: guacamole/guacamole:1.6.0
|
||||
container_name: << service_name >>-init
|
||||
user: "0:0"
|
||||
entrypoint: ["/bin/sh", "-c"]
|
||||
command:
|
||||
- if [ ! -s /init/001-initdb.sql ]; then /opt/guacamole/bin/initdb.sh --postgresql > /init/001-initdb.sql; fi
|
||||
volumes:
|
||||
- guacamole-init:/init
|
||||
restart: "no"
|
||||
|
||||
<< service_name >>-db:
|
||||
image: postgres:16-alpine
|
||||
container_name: << service_name >>-db
|
||||
environment:
|
||||
- POSTGRES_DB=guacamole
|
||||
- POSTGRES_USER=guacamole
|
||||
- POSTGRES_PASSWORD=<< db_password >>
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>/db:/var/lib/postgresql/data
|
||||
- guacamole-init:/docker-entrypoint-initdb.d:ro
|
||||
depends_on:
|
||||
<< service_name >>-init:
|
||||
condition: service_completed_successfully
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U guacamole -d guacamole"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
restart: unless-stopped
|
||||
|
||||
<< service_name >>-guacd:
|
||||
image: guacamole/guacd:1.6.0
|
||||
container_name: << service_name >>-guacd
|
||||
restart: unless-stopped
|
||||
|
||||
<< service_name >>:
|
||||
image: guacamole/guacamole:1.6.0
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port >>:8080"
|
||||
environment:
|
||||
- WEBAPP_CONTEXT=ROOT
|
||||
- GUACD_HOSTNAME=<< service_name >>-guacd
|
||||
- POSTGRESQL_HOSTNAME=<< service_name >>-db
|
||||
- POSTGRESQL_DATABASE=guacamole
|
||||
- POSTGRESQL_USERNAME=guacamole
|
||||
- POSTGRESQL_PASSWORD=<< db_password >>
|
||||
depends_on:
|
||||
<< service_name >>-db:
|
||||
condition: service_healthy
|
||||
<< service_name >>-guacd:
|
||||
condition: service_started
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
guacamole-init:
|
||||
29
apps/guacamole/template.json
Normal file
29
apps/guacamole/template.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "Apache Guacamole",
|
||||
"description": "Clientloze webgateway voor RDP, VNC en SSH. De PostgreSQL-database wordt bij de eerste start automatisch met het officiële Guacamole-schema ingericht.",
|
||||
"tags": ["remote desktop", "rdp", "vnc", "ssh"],
|
||||
"icon": {"provider": "selfhst", "id": "apache-guacamole"},
|
||||
"version": {"name": "1.6.0"},
|
||||
"categories": ["beheer", "netwerk"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële Guacamole-, guacd- en PostgreSQL-images ondersteunen AMD64 en ARM64."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "guacamole", "required": true},
|
||||
{"name": "port", "type": "int", "title": "Webinterface", "default": 14005, "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Database",
|
||||
"items": [
|
||||
{"name": "db_password", "type": "str", "title": "Databasewachtwoord", "default": "", "required": true, "secret": true, "generate": "auto"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
apps/lldap/files/compose.yaml
Normal file
19
apps/lldap/files/compose.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: lldap/lldap:stable
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port_web >>:17170"
|
||||
- "<< port_ldap >>:3890"
|
||||
environment:
|
||||
- UID=<< puid >>
|
||||
- GID=<< pgid >>
|
||||
- TZ=<< timezone >>
|
||||
- LLDAP_JWT_SECRET=<< jwt_secret >>
|
||||
- LLDAP_KEY_SEED=<< key_seed >>
|
||||
- LLDAP_LDAP_BASE_DN=<< base_dn >>
|
||||
- LLDAP_LDAP_USER_PASS=<< ldap_user_pass >>
|
||||
- LLDAP_HTTP_URL=<< http_url >>
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/data
|
||||
restart: unless-stopped
|
||||
42
apps/lldap/template.json
Normal file
42
apps/lldap/template.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "LLDAP",
|
||||
"description": "Lichtgewicht centrale gebruikersmap met LDAP en een eenvoudige webinterface. Bedoeld als accountbron voor onder meer Authelia, Authentik, Keycloak en Nextcloud. Stel LDAP niet rechtstreeks bloot aan internet.",
|
||||
"tags": ["ldap", "accounts", "sso", "identiteit"],
|
||||
"icon": {"provider": "selfhst", "id": "lldap"},
|
||||
"version": {"name": "stable"},
|
||||
"categories": ["beveiliging", "beheer"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële image ondersteunt AMD64, ARM64 en ARM/v7."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "lldap", "required": true},
|
||||
{"name": "port_web", "type": "int", "title": "Webinterface", "default": 17170, "required": true},
|
||||
{"name": "port_ldap", "type": "int", "title": "LDAP-poort", "default": 3890, "required": true, "description": "Alleen op het vertrouwde LAN gebruiken; voor internet is LDAPS of een VPN nodig."},
|
||||
{"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},
|
||||
{"name": "puid", "type": "int", "title": "PUID", "default": 1000, "required": true},
|
||||
{"name": "pgid", "type": "int", "title": "PGID", "default": 1000, "required": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Directory",
|
||||
"items": [
|
||||
{"name": "base_dn", "type": "str", "title": "Basis-DN", "default": "dc=example,dc=com", "required": true, "description": "Pas example.com aan je eigen interne domein aan."},
|
||||
{"name": "http_url", "type": "str", "title": "Publiek webadres", "default": "http://localhost:17170", "required": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Geheimen",
|
||||
"items": [
|
||||
{"name": "ldap_user_pass", "type": "str", "title": "Adminwachtwoord", "default": "", "required": true, "secret": true, "generate": true, "credential": "password", "description": "Inloggen gaat met gebruiker admin en dit wachtwoord."},
|
||||
{"name": "jwt_secret", "type": "str", "title": "JWT-sleutel", "default": "", "required": true, "secret": true, "generate": "auto", "secret_bytes": 32},
|
||||
{"name": "key_seed", "type": "str", "title": "Versleutelingsseed", "default": "", "required": true, "secret": true, "generate": "auto", "secret_bytes": 32}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
13
apps/meshcentral/files/compose.yaml
Normal file
13
apps/meshcentral/files/compose.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: ghcr.io/ylianst/meshcentral:latest
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port >>:443"
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>/data:/opt/meshcentral/meshcentral-data
|
||||
- ./config.json:/opt/meshcentral/meshcentral-data/config.json:ro
|
||||
- << appdata_dir >>/<< service_name >>/files:/opt/meshcentral/meshcentral-files
|
||||
- << appdata_dir >>/<< service_name >>/backups:/opt/meshcentral/meshcentral-backups
|
||||
- << appdata_dir >>/<< service_name >>/web:/opt/meshcentral/meshcentral-web
|
||||
restart: unless-stopped
|
||||
14
apps/meshcentral/files/config.json
Normal file
14
apps/meshcentral/files/config.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"$schema": "https://raw.githubusercontent.com/Ylianst/MeshCentral/master/meshcentral-config-schema.json",
|
||||
"settings": {
|
||||
"cert": "<< hostname >>",
|
||||
"port": 443,
|
||||
"WANonly": true
|
||||
},
|
||||
"domains": {
|
||||
"": {
|
||||
"title": "MeshCentral",
|
||||
"newAccounts": true
|
||||
}
|
||||
}
|
||||
}
|
||||
24
apps/meshcentral/template.json
Normal file
24
apps/meshcentral/template.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "MeshCentral",
|
||||
"description": "Beheer computers op afstand via de browser: bureaublad, terminal, bestanden en inventaris. Gebruikt ingebouwde opslag en een zelfondertekend certificaat. Het eerste account wordt beheerder; schakel daarna nieuwe registraties uit in config.json.",
|
||||
"tags": ["remote beheer", "support", "inventaris", "desktop"],
|
||||
"icon": {"provider": "selfhst", "id": "meshcentral"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["beheer", "netwerk"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële image publiceert manifests voor AMD64 en ARM64."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "meshcentral", "required": true},
|
||||
{"name": "port", "type": "int", "title": "HTTPS-webinterface", "default": 14001, "required": true},
|
||||
{"name": "hostname", "type": "str", "title": "Hostnaam of LAN-IP", "default": "", "required": true, "description": "De naam of het adres waarmee apparaten deze server bereiken, bijvoorbeeld mesh.example.nl of 192.168.1.10."},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
18
apps/nomad-server/files/compose.yaml
Normal file
18
apps/nomad-server/files/compose.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: hashicorp/nomad:latest
|
||||
container_name: << service_name >>
|
||||
command:
|
||||
- agent
|
||||
- -config=/nomad/config/server.hcl
|
||||
ports:
|
||||
- "<< port_http >>:<< port_http >>"
|
||||
- "<< port_rpc >>:<< port_rpc >>"
|
||||
- "<< port_gossip >>:<< port_gossip >>/tcp"
|
||||
- "<< port_gossip >>:<< port_gossip >>/udp"
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/nomad/data
|
||||
- ./server.hcl:/nomad/config/server.hcl:ro
|
||||
cap_add:
|
||||
- IPC_LOCK
|
||||
restart: unless-stopped
|
||||
28
apps/nomad-server/files/server.hcl
Normal file
28
apps/nomad-server/files/server.hcl
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
data_dir = "/nomad/data"
|
||||
bind_addr = "0.0.0.0"
|
||||
|
||||
addresses {
|
||||
http = "0.0.0.0"
|
||||
rpc = "0.0.0.0"
|
||||
serf = "0.0.0.0"
|
||||
}
|
||||
|
||||
ports {
|
||||
http = << port_http >>
|
||||
rpc = << port_rpc >>
|
||||
serf = << port_gossip >>
|
||||
}
|
||||
|
||||
advertise {
|
||||
http = "<< advertise_ip >>:<< port_http >>"
|
||||
rpc = "<< advertise_ip >>:<< port_rpc >>"
|
||||
serf = "<< advertise_ip >>:<< port_gossip >>"
|
||||
}
|
||||
|
||||
server {
|
||||
enabled = true
|
||||
bootstrap_expect = 1
|
||||
}
|
||||
|
||||
client {
|
||||
enabled = false
|
||||
31
apps/nomad-server/template.json
Normal file
31
apps/nomad-server/template.json
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "Nomad Server",
|
||||
"description": "Nomad control-plane met webinterface voor een klein lab. Deze container draait bewust alleen als server; installeer Nomad-clients rechtstreeks op de hosts om workloads betrouwbaar te starten.",
|
||||
"tags": ["orchestratie", "scheduler", "cluster", "hashicorp"],
|
||||
"icon": {"provider": "selfhst", "id": "nomad"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["beheer", "ontwikkeling"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "HashiCorp publiceert officiële Nomad-images voor AMD64 en ARM64. Een Nomad-client in Docker wordt niet officieel ondersteund."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "nomad", "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true},
|
||||
{"name": "advertise_ip", "type": "str", "title": "LAN-IP van deze server", "default": "", "required": true, "description": "Het bereikbare hostadres dat Nomad aan clients doorgeeft, bijvoorbeeld 192.168.1.10."}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Poorten",
|
||||
"items": [
|
||||
{"name": "port_http", "type": "int", "title": "HTTP API en webinterface", "default": 4646, "required": true},
|
||||
{"name": "port_rpc", "type": "int", "title": "Server-RPC", "default": 4647, "required": true},
|
||||
{"name": "port_gossip", "type": "int", "title": "Serf-gossip", "default": 4648, "required": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
15
apps/openobserve/files/compose.yaml
Normal file
15
apps/openobserve/files/compose.yaml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: public.ecr.aws/zinclabs/openobserve:latest
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port >>:5080"
|
||||
environment:
|
||||
- ZO_DATA_DIR=/data
|
||||
- ZO_LOCAL_MODE=true
|
||||
- ZO_LOCAL_MODE_STORAGE=disk
|
||||
- ZO_ROOT_USER_EMAIL=<< root_email >>
|
||||
- ZO_ROOT_USER_PASSWORD=<< root_password >>
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/data
|
||||
restart: unless-stopped
|
||||
30
apps/openobserve/template.json
Normal file
30
apps/openobserve/template.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "OpenObserve",
|
||||
"description": "Eén interface voor logs, metrics en traces met zoeken, dashboards en waarschuwingen. Deze template gebruikt de open-source single-nodeopzet met lokale schijfopslag.",
|
||||
"tags": ["logs", "metrics", "traces", "opentelemetry"],
|
||||
"icon": {"provider": "selfhst", "id": "openobserve"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["monitoring", "analytics"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële OpenObserve OSS-image publiceert AMD64- en ARM64-manifests."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "openobserve", "required": true},
|
||||
{"name": "port", "type": "int", "title": "Web- en API-poort", "default": 14006, "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Beheerder",
|
||||
"items": [
|
||||
{"name": "root_email", "type": "str", "title": "Beheerder e-mail", "default": "admin@example.com", "required": true, "credential": "username"},
|
||||
{"name": "root_password", "type": "str", "title": "Beheerderwachtwoord", "default": "", "required": true, "secret": true, "generate": true, "credential": "password"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
apps/pairdrop/files/compose.yaml
Normal file
14
apps/pairdrop/files/compose.yaml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: lscr.io/linuxserver/pairdrop:latest
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port >>:3000"
|
||||
environment:
|
||||
- PUID=<< puid >>
|
||||
- PGID=<< pgid >>
|
||||
- TZ=<< timezone >>
|
||||
- RATE_LIMIT=true
|
||||
- WS_FALLBACK=<< ws_fallback >>
|
||||
- DEBUG_MODE=false
|
||||
restart: unless-stopped
|
||||
26
apps/pairdrop/template.json
Normal file
26
apps/pairdrop/template.json
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "PairDrop",
|
||||
"description": "Stuur bestanden en tekst rechtstreeks tussen browsers op ieder platform, zonder account. WebRTC versleutelt de overdracht; zet voor publiek gebruik HTTPS via een reverse proxy aan.",
|
||||
"tags": ["bestanden", "delen", "airdrop", "webrtc"],
|
||||
"icon": {"provider": "selfhst", "id": "pairdrop"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["productiviteit", "opslag"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De LinuxServer-image ondersteunt AMD64 en ARM64."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "pairdrop", "required": true},
|
||||
{"name": "port", "type": "int", "title": "Webinterface", "default": 14007, "required": true},
|
||||
{"name": "timezone", "type": "str", "title": "Tijdzone", "default": "Europe/Amsterdam", "required": true},
|
||||
{"name": "puid", "type": "int", "title": "PUID", "default": 1000, "required": true},
|
||||
{"name": "pgid", "type": "int", "title": "PGID", "default": 1000, "required": true},
|
||||
{"name": "ws_fallback", "type": "bool", "title": "WebSocket-fallback", "default": false, "required": false, "description": "Routeert bestanden via de server als WebRTC niet werkt; de server kan die gegevens dan verwerken."}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
19
apps/rustdesk-server/files/compose.yaml
Normal file
19
apps/rustdesk-server/files/compose.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
services:
|
||||
<< service_name >>-hbbs:
|
||||
image: rustdesk/rustdesk-server:latest
|
||||
container_name: << service_name >>-hbbs
|
||||
command: hbbs
|
||||
network_mode: host
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/root
|
||||
depends_on:
|
||||
- << service_name >>-hbbr
|
||||
restart: unless-stopped
|
||||
<< service_name >>-hbbr:
|
||||
image: rustdesk/rustdesk-server:latest
|
||||
container_name: << service_name >>-hbbr
|
||||
command: hbbr
|
||||
network_mode: host
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/root
|
||||
restart: unless-stopped
|
||||
22
apps/rustdesk-server/template.json
Normal file
22
apps/rustdesk-server/template.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "RustDesk Server",
|
||||
"description": "Eigen rendezvous- en relayserver voor RustDesk. Werkt ook op een Raspberry Pi. Gebruikt hostnetwerk en de TCP-poorten 21115-21119 plus UDP 21116; maak die alleen bereikbaar waar nodig.",
|
||||
"tags": ["remote desktop", "beheer", "support", "rustdesk"],
|
||||
"icon": {"provider": "selfhst", "id": "rustdesk"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["beheer", "netwerk"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële image ondersteunt AMD64 en ARM64, waaronder een 64-bits Raspberry Pi."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "rustdesk", "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
12
apps/victoriametrics/files/compose.yaml
Normal file
12
apps/victoriametrics/files/compose.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: victoriametrics/victoria-metrics:latest
|
||||
container_name: << service_name >>
|
||||
command:
|
||||
- -storageDataPath=/storage
|
||||
- -retentionPeriod=<< retention_months >>
|
||||
ports:
|
||||
- "<< port >>:8428"
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>:/storage
|
||||
restart: unless-stopped
|
||||
24
apps/victoriametrics/template.json
Normal file
24
apps/victoriametrics/template.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "VictoriaMetrics",
|
||||
"description": "Snelle en zuinige tijdreeksdatabase voor Prometheus-metrics. Kan Prometheus remote_write ontvangen en Grafana als databron bedienen; geschikt voor een enkele server of Raspberry Pi.",
|
||||
"tags": ["metrics", "prometheus", "tijdreeksen", "grafana"],
|
||||
"icon": {"provider": "selfhst", "id": "victoriametrics"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["monitoring", "analytics"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "VictoriaMetrics publiceert officiële AMD64- en ARM64-images en documenteert Raspberry Pi-ondersteuning."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "victoriametrics", "required": true},
|
||||
{"name": "port", "type": "int", "title": "Web- en API-poort", "default": 8428, "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true},
|
||||
{"name": "retention_months", "type": "int", "title": "Bewaartermijn in maanden", "default": 12, "required": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
46
apps/windmill/files/compose.yaml
Normal file
46
apps/windmill/files/compose.yaml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
services:
|
||||
<< service_name >>:
|
||||
image: ghcr.io/windmill-labs/windmill:main
|
||||
container_name: << service_name >>
|
||||
ports:
|
||||
- "<< port >>:8000"
|
||||
environment:
|
||||
- MODE=server
|
||||
- DATABASE_URL=postgres://postgres:<< db_password >>@<< service_name >>-db/windmill?sslmode=disable
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>/logs:/tmp/windmill/logs
|
||||
depends_on:
|
||||
<< service_name >>-db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
<< service_name >>-worker:
|
||||
image: ghcr.io/windmill-labs/windmill:main
|
||||
container_name: << service_name >>-worker
|
||||
environment:
|
||||
- MODE=worker
|
||||
- WORKER_GROUP=default
|
||||
- DATABASE_URL=postgres://postgres:<< db_password >>@<< service_name >>-db/windmill?sslmode=disable
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>/worker-cache:/tmp/windmill/cache
|
||||
- << appdata_dir >>/<< service_name >>/logs:/tmp/windmill/logs
|
||||
depends_on:
|
||||
<< service_name >>-db:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
|
||||
<< service_name >>-db:
|
||||
image: postgres:16-alpine
|
||||
container_name: << service_name >>-db
|
||||
environment:
|
||||
- POSTGRES_DB=windmill
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=<< db_password >>
|
||||
volumes:
|
||||
- << appdata_dir >>/<< service_name >>/db:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -d windmill"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
restart: unless-stopped
|
||||
29
apps/windmill/template.json
Normal file
29
apps/windmill/template.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "Windmill",
|
||||
"description": "Open-source platform voor scripts, interne apps en workflows. De template start een server, een worker en PostgreSQL zonder toegang tot de Docker-socket.",
|
||||
"tags": ["automatisering", "workflows", "scripts", "low-code"],
|
||||
"icon": {"provider": "selfhst", "id": "windmill"},
|
||||
"version": {"name": "latest"},
|
||||
"categories": ["ontwikkeling", "productiviteit"],
|
||||
"architectures": ["amd64", "arm64"],
|
||||
"architecture_note": "De officiële Windmill- en PostgreSQL-images ondersteunen AMD64 en ARM64."
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"title": "Algemeen",
|
||||
"items": [
|
||||
{"name": "service_name", "type": "str", "title": "Servicenaam", "default": "windmill", "required": true},
|
||||
{"name": "port", "type": "int", "title": "Webinterface", "default": 14004, "required": true},
|
||||
{"name": "appdata_dir", "type": "str", "title": "Appdata-map", "default": "/opt/serverup/appdata", "required": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Database",
|
||||
"items": [
|
||||
{"name": "db_password", "type": "str", "title": "Databasewachtwoord", "default": "", "required": true, "secret": true, "generate": "auto"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
91
tests/test_catalogus_nuttige_apps.py
Normal file
91
tests/test_catalogus_nuttige_apps.py
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
"""Regressietests voor de infrastructuur- en beheerapps uit v0.8.17."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
WORTEL = Path(__file__).resolve().parent.parent
|
||||
APPS = WORTEL / "apps"
|
||||
|
||||
NIEUWE_APPS = {
|
||||
"activepieces",
|
||||
"consul",
|
||||
"guacamole",
|
||||
"lldap",
|
||||
"meshcentral",
|
||||
"nomad-server",
|
||||
"openobserve",
|
||||
"pairdrop",
|
||||
"rustdesk-server",
|
||||
"victoriametrics",
|
||||
"windmill",
|
||||
}
|
||||
|
||||
|
||||
def _template(app: str) -> dict:
|
||||
return json.loads((APPS / app / "template.json").read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def test_alle_geselecteerde_apps_staan_in_de_catalogus():
|
||||
aanwezig = {pad.name for pad in APPS.iterdir() if pad.is_dir()}
|
||||
assert NIEUWE_APPS <= aanwezig
|
||||
|
||||
|
||||
@pytest.mark.parametrize("app", sorted(NIEUWE_APPS))
|
||||
def test_nieuwe_apps_ondersteunen_pi_en_x86(app):
|
||||
architecturen = set(_template(app)["metadata"]["architectures"])
|
||||
assert {"amd64", "arm64"} <= architecturen
|
||||
|
||||
|
||||
def test_nomad_container_is_alleen_control_plane():
|
||||
compose = (APPS / "nomad-server" / "files" / "compose.yaml").read_text()
|
||||
config = (APPS / "nomad-server" / "files" / "server.hcl").read_text()
|
||||
assert "-config=/nomad/config/server.hcl" in compose
|
||||
assert "enabled = false" in config
|
||||
assert "enabled = true" in config
|
||||
regels = {" ".join(regel.split()) for regel in config.splitlines()}
|
||||
for adres in ("http", "rpc", "serf"):
|
||||
assert any(regel.startswith(f'{adres} = "<< advertise_ip >>:') for regel in regels)
|
||||
assert "/var/run/docker.sock" not in compose
|
||||
assert "privileged:" not in compose
|
||||
|
||||
|
||||
def test_clusterapps_adverteren_het_bereikbare_hostadres():
|
||||
for app in ("nomad-server", "consul"):
|
||||
velden = {
|
||||
item["name"]: item
|
||||
for groep in _template(app)["variables"]
|
||||
for item in groep["items"]
|
||||
}
|
||||
assert velden["advertise_ip"]["required"] is True
|
||||
assert velden["advertise_ip"]["default"] == ""
|
||||
if app == "nomad-server":
|
||||
bron = (APPS / app / "files" / "server.hcl").read_text()
|
||||
else:
|
||||
bron = (APPS / app / "files" / "compose.yaml").read_text()
|
||||
assert "<< advertise_ip >>" in bron
|
||||
|
||||
|
||||
def test_interne_databasewachtwoorden_worden_automatisch_gemaakt():
|
||||
for app in ("guacamole", "windmill"):
|
||||
velden = [item for groep in _template(app)["variables"] for item in groep["items"]]
|
||||
assert next(item for item in velden if item["name"] == "db_password")["generate"] == "auto"
|
||||
|
||||
|
||||
def test_guacamole_initialiseert_database_voor_de_webapp_start():
|
||||
compose = (APPS / "guacamole" / "files" / "compose.yaml").read_text()
|
||||
assert "initdb.sh --postgresql" in compose
|
||||
assert "condition: service_completed_successfully" in compose
|
||||
assert "condition: service_healthy" in compose
|
||||
|
||||
|
||||
def test_meshcentral_krijgt_een_bereikbare_https_configuratie():
|
||||
config = (APPS / "meshcentral" / "files" / "config.json").read_text()
|
||||
config = json.loads(config.replace("<< hostname >>", "mesh.example.nl"))
|
||||
assert config["settings"]["cert"] == "mesh.example.nl"
|
||||
assert config["settings"]["port"] == 443
|
||||
assert config["domains"][""]["newAccounts"] is True
|
||||
|
||||
compose = (APPS / "meshcentral" / "files" / "compose.yaml").read_text()
|
||||
assert '"<< port >>:443"' in compose
|
||||
Loading…
Reference in a new issue