Zelf ntfy server hosten met Docker Compose
Host uw eigen ntfy server achter TLS met Docker Compose. Beveilig topics met ACLs en stuur direct pushmeldingen vanuit cron jobs of systemd OnFailure units naar uw telefoon.
Wat een zelfgehoste ntfy server doet
Een zelfgehoste ntfy server zet een HTTP POST om in een pushbericht op uw telefoon. U publiceert met curl, en het bericht komt aan in de Android-app, de iOS-app, een browsertabblad of elk ander medium dat een HTTP-verbinding open kan houden. Er hoeft geen clientbibliotheek te worden geïnstalleerd en er hoeft geen message broker te worden uitgevoerd.
ntfy adresseert berichten op basis van een topic. Een topic is een naam in het URL-pad, zoals https://ntfy.example.com/alerts, en deze bestaat op het moment dat iemand ernaar publiceert. Bij een standaardinstallatie kan iedereen die die naam kent het topic lezen en ernaar schrijven; daarom vergelijkt de documentatie van het project een topicnaam met een wachtwoord. Dat model is prima voor de publieke ntfy.sh dienst. Het is echter niet geschikt voor een server die meldingen over uw back-upfouten verwerkt, dus deze handleiding schakelt authenticatie in voordat het eerste bericht wordt verzonden.
Vereisten voordat u begint
U heeft een VPS nodig met Ubuntu 24.04 of Debian 13, inclusief Docker Engine en de Compose-plugin, een domeinnaam en zeer weinig RAM. Maak een DNS (domain name system) A-record aan dat ntfy.example.com naar het publieke IP-adres van de server wijst en controleer of dit correct wordt omgezet voordat u verdere stappen onderneemt.
dig +short ntfy.example.com
sudo ufw allow 80,443/tcp
sudo ufw statusdig moet het IP-adres van uw server tonen. De uitgifte van het certificaat mislukt als dit niets retourneert, omdat de certificaatautoriteit de naam van buitenaf controleert. Poort 80 moet open blijven omdat ACME (automatic certificate management environment), het protocol achter Let's Encrypt, deze gebruikt voor de HTTP-challenge. De ntfy-container zelf krijgt nooit een publieke poort.
Schrijf het ntfy-configuratiebestand
De Docker-image bevat geen configuratiebestand, dus u moet er zelf een aanmaken. Elke opdracht verderop in deze handleiding leest vanuit dit bestand. Bepaal eerst de user ID en group ID waaronder de container zal draaien.
id -u
id -g
sudo install -d -o "$(id -u)" -g "$(id -g)" /etc/ntfy /var/cache/ntfy /var/lib/ntfy
sudo nano /etc/ntfy/server.ymlbase-url: "https://ntfy.example.com"
listen-http: ":2586"
behind-proxy: true
cache-file: "/var/cache/ntfy/cache.db"
cache-duration: "12h"
auth-file: "/var/lib/ntfy/user.db"
auth-default-access: "deny-all"
enable-login: true
enable-signup: falseVier van deze regels zijn cruciaal. base-url moet het exacte publieke HTTPS-adres zijn, omdat ntfy hiermee bijlagelinks en verzoeken van de web-app zelf opbouwt; een onjuiste waarde zorgt ervoor dat de web-app wel laadt, maar elke actie faalt. listen-http: ":2586" bindt aan alle interfaces binnen de container, wat onzorgvuldig lijkt maar correct is: de container heeft zijn eigen netwerk-namespace, dus binden aan 127.0.0.1 zou de poort onbereikbaar maken vanaf de host en de gepubliceerde poort van Docker zou nooit verbinding maken. auth-default-access: "deny-all" vormt de volledige beveiligingsstrategie, omdat het lees- en schrijftoegang weigert aan iedereen zonder expliciete toestemming. behind-proxy: true instrueert ntfy om het clientadres uit de X-Forwarded-For-header te halen, zodat rate limits de werkelijke bezoekers tellen in plaats van de reverse proxy als één zeer actieve client te zien.
enable-login: true stelt de web-app en de telefoon-apps in staat om in te loggen met een wachtwoord. enable-signup blijft false, aangezien zelfbediening voor accountcreatie op een privéserver een open deur met extra stappen is.
sudo chown "$(id -u):$(id -g)" /etc/ntfy/server.yml
sudo chmod 600 /etc/ntfy/server.ymlntfy uitvoeren met Docker Compose
Plaats dit in /opt/ntfy/compose.yaml en vervang 1000:1000 door de twee getallen id -u en id -g die hierboven staan.
services:
ntfy:
image: binwiederhier/ntfy:v2.27.0
container_name: ntfy
command: serve
user: "1000:1000"
environment:
- TZ=UTC
volumes:
- /etc/ntfy:/etc/ntfy
- /var/cache/ntfy:/var/cache/ntfy
- /var/lib/ntfy:/var/lib/ntfy
ports:
- "127.0.0.1:2586:2586"
restart: unless-stoppedcd /opt/ntfy
sudo docker compose up -d
sudo docker compose logs ntfy
curl -s http://127.0.0.1:2586/v1/healthEen gezonde server antwoordt met {"healthy":true}. Twee details in dat compose-bestand zijn bewust gekozen. De image is vastgezet op v2.27.0, de huidige release van augustus 2026, in plaats van latest. Met latest wijzigt de volgende docker compose pull namelijk uw serverversie en komt u daar pas achteraf via de changelog achter. De poort is gepubliceerd als 127.0.0.1:2586:2586, waardoor de container alleen bereikbaar is vanaf het loopback-adres van de host. Schrijf in plaats daarvan 2586:2586 en Docker voegt zijn eigen firewallregels toe vóór die van u; dit betekent dat de poort reageert vanaf het internet, ook al zegt ufw status dat de poort gesloten is.
Als curl Connection refused afdrukt, lees dan het containerlogboek. Een permissiefout op /var/lib/ntfy/user.db betekent dat de user:-regel niet overeenkomt met de eigenaar van die mappen, waardoor het proces zijn eigen database niet kan aanmaken en afsluit. De basisgids voor Docker Compose op een VPS behandelt volume-eigenaarschap en herstartbeleid in meer detail.
TLS implementeren met Caddy
Caddy vraagt zelfstandig certificaten aan en vernieuwt deze, wat de snelste weg is naar werkende TLS (transport layer security).
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddyVervang de inhoud van /etc/caddy/Caddyfile door drie regels.
ntfy.example.com {
reverse_proxy 127.0.0.1:2586
}sudo systemctl reload caddy
curl -s https://ntfy.example.com/v1/healthDezelfde {"healthy":true} via HTTPS betekent dat het volledige pad correct functioneert. Een 502 van Caddy betekent dat ntfy niet luistert: controleer dit met sudo ss -lntp | grep 2586. Een certificaatfout duidt meestal op een onjuist DNS-record of een geblokkeerde poort 80, en sudo journalctl -u caddy -n 50 geeft aan welke van de twee het probleem veroorzaakt.
Als u al nginx gebruikt, kopieer dan de proxy-instellingen die in de ntfy-documentatie staan: proxy_http_version 1.1, proxy_buffering off, proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for, en stel de read- en send-timeouts in op minimaal drie minuten. Een subscriber houdt één HTTP-verbinding open zolang deze luistert, en nginx sluit een inactieve upstream-verbinding standaard na 60 seconden. Hierdoor maken subscribers in een lus opnieuw verbinding en gaan berichten die tijdens de onderbreking worden verzonden verloren.
Gebruikers aanmaken en onderwerpen beveiligen
Authenticatie is ingeschakeld en niemand heeft nog ergens toegang toe; dat is precies de bedoeling. Maak één beheerdersaccount voor uzelf aan en één machine-account voor scripts. Deze commando's lezen /etc/ntfy/server.yml vanuit de container, daarom is het configuratiebestand een volume-mount.
sudo docker compose exec ntfy ntfy user add --role=admin admin
sudo docker compose exec ntfy ntfy user add robot
sudo docker compose exec ntfy ntfy user listBij elk commando wordt om een wachtwoord gevraagd. Een beheerder negeert de toegangslijst en kan elk onderwerp lezen en beschrijven, dus houd dat account voor uzelf en de telefoon-app. robot is een gewone gebruiker zonder enige toegang totdat u deze verleent.
sudo docker compose exec ntfy ntfy access robot alerts write
sudo docker compose exec ntfy ntfy access robot "alerts_*" write
sudo docker compose exec ntfy ntfy accessEen ACL-item (access control list) bestaat uit een gebruiker, een onderwerp en een permissie. Het onderwerp is een letterlijke naam of een patroon waarbij * alles matcht; zo dekt alerts_* zowel alerts_backup als alerts_db zonder dat u per host een commando hoeft uit te voeren. De permissie write betekent alleen publiceren, zodat een token dat uit een cron-job wordt gestolen niet kan subscriben om terug te lezen wat er is verzonden. De speciale gebruikersnaam everyone bepaalt wat een niet-geauthenticeerde bezoeker mag doen; gebruik deze alleen om iets bewust openbaar te maken, zoals ntfy access everyone status read.
Scripts moeten een token gebruiken, niet uw wachtwoord.
sudo docker compose exec ntfy ntfy token add robotHet commando toont een token dat begint met tk_. Een token erft exact de toegangsrechten van de gebruiker waartoe het behoort, dus dit token kan alleen publiceren naar de alerts-onderwerpen en verder niets. ntfy token list toont wat er bestaat en ntfy token remove trekt een token in zonder het wachtwoord van de gebruiker te wijzigen.
Verstuur uw eerste bericht en controleer of de vergrendeling werkt
Begin met te controleren of de deur gesloten is.
curl -s -o /dev/null -w '%{http_code}\n' -d "hello" https://ntfy.example.com/alertsDit voert 403 uit, en 403 is het juiste antwoord: auth-default-access: "deny-all" weigert een anonieme publicatie. Verstuur nu een echt bericht.
curl -H "Authorization: Bearer tk_REPLACE_WITH_YOUR_TOKEN" \
-H "Title: Nightly backup finished" \
-H "Priority: default" \
-H "Tags: white_check_mark" \
-d "42 GB copied in 11 minutes" \
https://ntfy.example.com/alertsDe server antwoordt met het opgeslagen bericht in JSON-formaat; zo weet u dat het bericht is geaccepteerd in plaats van genegeerd. Title is de vetgedrukte eerste regel. Priority loopt van 1 tot 5, of op naam van min tot urgent, en bepaalt of de telefoon een geluid maakt. Tags worden emoji's in de notificatie wanneer de naam overeenkomt met een bekende emoji-shortcode, en blijven platte tekst wanneer dit niet het geval is.
Om een onderwerp vanuit een terminal te monitoren, streamt u het als volgt:
curl -s -u admin https://ntfy.example.com/alerts/rawcurl vraagt om het wachtwoord. Elk bericht komt binnen als één regel, en de lege regels die af en toe verschijnen zijn keepalives. Door https://ntfy.example.com in een browser te openen en in te loggen met hetzelfde account, krijgt u de web-app-versie van dezelfde stream.
Stel rate limits in zodat één script de server niet kan overbelasten
Standaard krijgt elke bezoeker een bucket van 60 verzoeken, die wordt aangevuld met één verzoek per 5 seconden. Dit is ruim voor een privéserver, en een script dat vastzit in een retry-loop zal dit volledig verbruiken. Voeg limieten toe aan server.yml.
visitor-request-limit-burst: 30
visitor-request-limit-replenish: "10s"
visitor-message-daily-limit: 500sudo docker compose restart ntfyEen bezoeker die de limiet overschrijdt, krijgt HTTP 429 in plaats van een afgeleverd bericht. De limiet wordt geteld per bezoekersadres; dit is de reden waarom behind-proxy: true zo belangrijk is: zonder deze instelling ziet ntfy alleen het adres van Caddy. Elke client telt dan als dezelfde bezoeker, waardoor één luidruchtig script de bucket uitput die uw telefoon en uw andere servers delen.
Waarschuwing bij een falende cron job
Houd het token buiten de command line. ps aux toont de volledige command line van elk draaiend proces aan elke gebruiker op de server, waardoor een token dat wordt meegegeven met -H leesbaar is voor elk lokaal account zolang curl draait. Een curl-configuratiebestand voorkomt dit.
sudo install -d -m 700 /etc/ntfy-alert
printf 'header = "Authorization: Bearer tk_REPLACE_WITH_YOUR_TOKEN"\n' | sudo tee /etc/ntfy-alert/curlrc
sudo chmod 600 /etc/ntfy-alert/curlrcVerpak nu de taak. Sla dit op als /usr/local/bin/backup-with-alert.sh en maak het chmod 750.
#!/bin/bash
out=$(/usr/local/bin/backup.sh 2>&1)
code=$?
if [ "$code" -ne 0 ]; then
printf '%s' "$out" | tail -c 1000 | curl -K /etc/ntfy-alert/curlrc \
-H "Title: backup.sh failed with exit $code" \
-H "Priority: high" \
-H "Tags: warning" \
--data-binary @- \
https://ntfy.example.com/alerts
fi
exit "$code"17 3 * * * /usr/local/bin/backup-with-alert.sh >> /var/log/backup-alert.log 2>&1$? wordt direct na het commando opgevangen, omdat het volgende uitgevoerde commando het anders zou overschrijven. De output gaat door tail -c 1000 omdat ntfy een maximale berichtgrootte afdwingt en een notificatie geen logviewer is. De afsluitende exit "$code" behoudt de oorspronkelijke status, zodat andere processen die deze taak monitoren nog steeds een foutmelding zien. Test het geheel door het script voor één run naar /bin/false te laten wijzen.
Een foutafhandeling die nooit wordt uitgevoerd is slechter dan geen waarschuwing, omdat het lijkt alsof stilte succes betekent. Cron geeft uw taak een vrijwel lege omgeving en een veel kortere PATH dan uw login-shell, waardoor een script dat handmatig werkt kan crashen voordat het de curl-regel bereikt. De handleiding over waarom een cron job niet draait behandelt deze omgevingsvalkuilen. Gebruik overal absolute paden en lees het logbestand na de eerste geplande run in plaats van er zomaar vanuit te gaan dat het werkt.
Waarschuwing bij het falen van een systemd unit
Cron is geschikt voor geplande taken. Voor langlopende services is OnFailure= nodig, dat systemd uitvoert zodra een unit de status failed bereikt. Maak één template-unit aan en hergebruik deze voor elke service op de server. Sla dit op als /etc/systemd/system/ntfy-unit-failed@.service.
[Unit]
Description=Send an ntfy alert because %i failed
[Service]
Type=oneshot
ExecStart=/usr/local/bin/ntfy-unit-failed %iVoer daarna /usr/local/bin/ntfy-unit-failed uit, met modus 750:
#!/bin/bash
unit="$1"
journalctl -u "$unit" -n 15 --no-pager -o cat | tail -c 1000 | curl -K /etc/ntfy-alert/curlrc \
-H "Title: $unit failed on $(hostname -s)" \
-H "Priority: urgent" \
-H "Tags: rotating_light" \
--data-binary @- \
https://ntfy.example.com/alertsKoppel dit aan een service met een drop-in, zodat een pakket-upgrade uw wijziging niet overschrijft.
sudo systemctl edit myapp.service[Unit]
OnFailure=ntfy-unit-failed@%n.service%n wordt uitgebreid naar de volledige unit-naam, waardoor de instantie ntfy-unit-failed@myapp.service wordt, en %i in de template geeft myapp.service door aan het script als eerste argument. Hierdoor kan één template voor elke unit dienen. Controleer of het werkt met een unit die opzettelijk faalt, opgeslagen als /etc/systemd/system/ntfy-selftest.service.
[Unit]
Description=Deliberately failing unit
OnFailure=ntfy-unit-failed@%n.service
[Service]
Type=oneshot
ExecStart=/bin/falsesudo systemctl daemon-reload
sudo systemctl start ntfy-selftest.serviceHet startcommando sluit af met een non-zero status en print Job for ntfy-selftest.service failed because the control process exited with error code, waarna de telefoon ongeveer een seconde later zou moeten trillen. Verwijder de test-unit daarna.
Eén valkuil verdient aandacht. OnFailure= wordt alleen uitgevoerd wanneer een unit de status failed bereikt, en een service met Restart=always bereikt deze status mogelijk nooit, omdat systemd de service blijft herstarten. De unit faalt pas zodra het aantal herstarts StartLimitBurst overschrijdt binnen StartLimitIntervalSec. Stel deze twee waarden in op elke service waarover u bericht wilt ontvangen, anders blijft een crash-loop dagenlang onopgemerkt op de achtergrond draaien. Timers zijn het schonere alternatief voor het bovenstaande cron-patroon, aangezien de service-unit van een timer standaard OnFailure= krijgt, en de handleiding voor systemd services en timers op een VPS legt uit hoe u deze kunt omzetten.
Koppel een uptime-monitor aan hetzelfde topic
Uptime Kuma, de self-hosted statusmonitor, wordt geleverd met een ntfy-notificatietype. Open Settings, ga naar Notifications, kies Setup Notification, selecteer Ntfy, stel de server-URL in op https://ntfy.example.com en het topic op alerts, kies een prioriteit en plak het robot access token. Verstuur een testnotificatie voordat u de instellingen opslaat, omdat een onjuiste topicnaam stilzwijgend faalt bij een write-toegang die het topic niet dekt.
De beperking van deze opzet is: een monitor die op dezelfde VPS draait, kan niet melden dat de VPS zelf offline is, en ntfy kan geen melding sturen als ntfy zelf onbereikbaar is. Draai de monitor op een andere machine en voeg een tweede notificatiekanaal toe, zoals e-mail, voor de monitor die ntfy zelf controleert. Het Push-monitortype van Uptime Kuma dekt de andere blinde vlek: uw cron job roept een push-URL aan na een succesvolle uitvoering, en Kuma stuurt een waarschuwing wanneer deze aanroepen uitblijven. Een foutmelding wordt alleen verstuurd wanneer de taak daadwerkelijk draait; dit zegt dus niets over een taak die nooit is gestart.
Werkt zelf-gehoste ntfy op Android en iPhone?
Op Android werkt dit zonder beperkingen. Installeer de app via Google Play of F-Droid, open de instellingen, stel de standaardserver in op https://ntfy.example.com, voeg uw account toe in het gebruikersbeheerscherm en abonneer u vervolgens op alerts. Instant delivery houdt een foreground service actief zodat berichten aankomen, zelfs wanneer de telefoon in de doze-modus staat. De permanente notificatie die hierbij hoort, is een vereiste van Android voor foreground services en geen bug. De F-Droid-build bevat geen Firebase-code, waardoor elk abonnement gebruikmaakt van instant delivery. ntfy kan ook fungeren als een UnifiedPush-distributeur, een open vervanger voor de push-dienst van Google, zodat andere apps die UnifiedPush ondersteunen ook via uw server kunnen bezorgen.
Op iOS werkt het met één afhankelijkheid die u niet kunt verwijderen. Apple wekt een app op de achtergrond alleen via APNs (Apple push notification service). Alleen de partij die de ondertekeningsgegevens van de app bezit, mag berichten naar de app sturen; uw server heeft dus geen manier om de app rechtstreeks te bereiken. ntfy lost dit op met een relay: uw server stuurt een poll_request met de bericht-ID naar ntfy.sh, die het doorstuurt via Firebase en APNs om de app te wekken. De app haalt vervolgens de berichtinhoud op van uw server.
upstream-base-url: "https://ntfy.sh"Wees u bewust van de kosten hiervan. De berichtinhoud blijft op uw eigen server, maar het feit dat er een bericht is binnengekomen, inclusief de ID, gaat via infrastructuur die u niet zelf beheert. Zonder deze instelling komen notificaties op een iPhone vanaf een zelf-gehoste server vertraagd of helemaal niet aan, omdat er niets is dat de app wekt. De enige manier om de relay te verwijderen is door de iOS-app zelf te bouwen en te distribueren met uw eigen Apple-ontwikkelaarsaccount en uw eigen APNs-sleutels. Dit brengt jaarlijkse kosten met zich mee en vereist een nieuwe build bij elke update. Als de relay onacceptabel is voor uw gebruik, gebruik dan de alarmering op Android of de desktop-webapp.
Backups, upgrades en het vastzetten van de image
Twee paden kunnen niet opnieuw worden gegenereerd: /etc/ntfy/server.yml en /var/lib/ntfy/user.db. Het tweede pad bevat alle gebruikers, wachtwoordhashes, ACL-vermeldingen en tokens; behandel dit bestand daarom als een private key.
sudo tar czf ntfy-backup.tgz -C / etc/ntfy var/lib/ntfy
sudo chmod 600 ntfy-backup.tgzKopieer dat bestand van de server af. cache.db bevat alleen recente berichten, met de bovenstaande cache-duration gaat het om 12 uur aan data; het verlies hiervan is niet kritiek. Upgraden betekent de tag in het compose-bestand aanpassen en een pull uitvoeren.
sudo docker compose pull
sudo docker compose up -d
curl -s https://ntfy.example.com/v1/healthLees eerst de release notes. De SQLite-databases migreren bij het opstarten; terugkeren naar een oudere tag na een schemawijziging is daarom niet veilig. Bewaar de zojuist gemaakte backup totdat de nieuwe versie een dag stabiel heeft gedraaid.
Gotify en Apprise
Gotify is de compactere optie: één binary met een web-UI en een Android-app, zonder ondersteuning voor topic-wildcards en zonder officiële iOS-client. Dit is geschikt voor een privéserver waarbij Android het enige doelplatform is. Apprise is eerder een Python-library en command-line tool dan een server; het verstuurt één bericht naar meer dan honderd diensten, waaronder ntfy. Dit is geschikt voor scripts die meerdere bestemmingen tegelijk moeten bereiken. ntfy biedt een server, een HTTP API en apps voor beide mobiele platformen, wat de reden is dat dit doorgaans de standaardoplossing is voor notificaties vanaf een gehuurde server.
FAQ
Waarom krijg ik een 403-foutmelding bij het publiceren naar mijn ntfy-server?
Met auth-default-access: "deny-all" in server.yml wordt anoniem publiceren geweigerd; dit is het beoogde gedrag. Stuur inloggegevens mee met -u user:pass of -H "Authorization: Bearer tk_...". Als u al een token meestuurt en toch 403 ontvangt, heeft de gebruiker achter dat token geen overeenkomende ACL-regel voor het onderwerp. Voer ntfy access uit om de volledige lijst weer te geven. Houd er rekening mee dat een write-toegang geen recht geeft om te abonneren; een account dat succesvol kan publiceren, wordt dus alsnog geweigerd wanneer het probeert hetzelfde onderwerp te lezen.
Werken notificaties op een iPhone met een zelfgehoste ntfy-server?
Ze werken via een relay die onvermijdelijk is. Apple wekt apps alleen via APNs (Apple push notification service) en alleen de uitgever van de app kan hiernaar verzenden. Daarom stuurt ntfy een poll_request met de bericht-ID door naar ntfy.sh, die het vervolgens doorstuurt naar het apparaat. Stel upstream-base-url: "https://ntfy.sh" in server.yml in en herstart de container. De inhoud van het bericht zelf wordt nog steeds opgehaald van uw eigen server. Zonder deze instelling worden iOS-notificaties vertraagd of verschijnen ze helemaal niet.
Waarom kwam mijn ntfy-waarschuwing via een cron job nooit aan?
Voer de curl-regel eerst handmatig uit om te controleren of het token en het onderwerp correct zijn. Als het handmatig werkt maar niet via cron, ligt het probleem vóór de waarschuwing: cron voert taken uit met een minimale omgeving en een kort PATH-pad, waardoor een script dat een commando bij de naam alleen aanroept, kan falen voordat de curl-regel wordt bereikt. Gebruik absolute paden, stuur de uitvoer van de taak door naar een logbestand en lees dat bestand na de volgende uitvoering. Een 429-respons in plaats van een aflevering betekent dat de rate limit actief is en uw script te snel opnieuw probeert te verzenden.
Moet ik ntfy blootstellen aan het openbare internet?
De mobiele apps moeten de server kunnen bereiken via mobiele netwerken. Een openbaar HTTPS-eindpunt met auth-default-access: "deny-all" en ACL's per onderwerp is de standaardconfiguratie en is veilig zolang geen enkel onderwerp leesbaar is voor everyone. Een instance die alleen via VPN bereikbaar is, is logisch wanneer elke abonnee een machine is die u beheert. Voor telefoons is dit minder geschikt, omdat de app alleen berichten ontvangt zolang de tunnel actief is; waarschuwingen worden in de wachtrij geplaatst totdat de telefoon opnieuw verbinding maakt.