SSD Nodes Learn
Gidsen Matt ConnorDoor Matt Connor · Bijgewerkt 2026-07-24

Uptime Kuma installeren met Docker

Monitor websites, DNS en ports met Uptime Kuma in Docker. Gebruik een aparte VPS voor statuspagina's en ontvang alerts via Telegram of e-mail bij outages.

Wat u bouwt

Eén enkele kleine container die uw andere servers en websites van buitenaf controleert. Het systeem meldt direct wanneer een service niet meer reageert via e-mail, Telegram, Discord of een webhook. Uptime Kuma is een enkel Node-proces dat gebruikmaakt van een SQLite-bestand. Hierdoor draait het probleemloos op 256-512 MB RAM. Het biedt een live dashboard, grafieken met de geschiedenis en een publieke statuspagina. De installatie bestaat uit een Compose-bestand van tien regels. De belangrijkste factoren zijn de locatie waar u het uitvoert en of de alerts tijdens een test zijn afgegaan. Een monitor waarvan u nooit heeft bewezen dat deze u bereikt, is minder waardevol dan geen monitor: het geeft een vals gevoel van veiligheid terwijl er niets wordt gecontroleerd.

Voer de monitor uit op een locatie die niet bereikbaar is tijdens een outage

Deze beslissing is cruciaal voor het succes van de implementatie. Voer Uptime Kuma niet uit op dezelfde machine als de systemen die u controleert. Als de monitor op de server draait die hij controleert, dan zorgt een fout (zoals een crash of een tekort aan geheugen) ervoor dat de monitor tegelijkertijd uitvalt. U ontvangt dan geen melding. Stilte van een defecte monitor is identiek aan de status "alles is in orde". Er is een subtielere valstoot wanneer de machine nog wel draait: een monitor die gericht is op localhost deelt de CPU met de workload. Een piek in de CPU-belasting kan ervoor zorgen dat de controle van de monitor een timeout krijgt en de status op down zet. Dit is een vals alarm, terwijl de echte gebruikers nog steeds toegang hebben.

Voer Uptime Kuma daarom uit op een andere VPS dan de servers die u controleert. Gebruik bij voorkeur een andere provider of regio. Zorg dat de monitor uw services bereikt zoals uw gebruikers dat doen: via het publieke internet, op basis van de hostname. Een goedkope instance is voldoende; één kleine monitoring VPS kan al uw servers controleren. Om te detecteren wanneer Kuma zelf uitvalt, kunt u een push heartbeat via een cronjob vanaf een andere locatie instellen.

Vereisten en dimensionering

  • Een schone Ubuntu 24.04 VPS met Docker Engine en de Compose v2 plugin. Installeer deze via de officiële Docker apt-repository en niet via het docker.io distro-pakket, omdat dit pakket achterloopt.
  • 256 MB RAM is voldoende voor enkele monitors; 512 MB tot 1 GB is aanbevolen voor tientallen monitors inclusief de reverse proxy. De CPU is nagenoeg in ruststand tussen de controles door.
  • Een domein en een DNS A-record (bijvoorbeeld status.example.com die naar de VPS wijst), alleen als u TLS en een publieke statuspagina wilt gebruiken. Een private instantie kan DNS overslaan door een VPN of SSH-tunnel te gebruiken.
  • Uitgaande netwerkverbinding naar de bestemming van de alerts: SMTP naar uw mailprovider, of HTTPS naar Telegram en Discord.

Het Compose-bestand

Plaats dit in /srv/uptime-kuma/compose.yaml.

services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "127.0.0.1:3001:3001"
    volumes:
      - kuma-data:/app/data

volumes:
  kuma-data:

Start het systeem en volg de eerste boot:

sudo mkdir -p /srv/uptime-kuma
# save the file above as /srv/uptime-kuma/compose.yaml, then:
cd /srv/uptime-kuma && sudo docker compose up -d
sudo docker compose logs -f uptime-kuma

Een correcte start logt Listening on 3001 en stopt daarna met loggen. Drie zaken in dit bestand zijn opzettelijk gekozen.

127.0.0.1:3001:3001, niet 3001:3001. Docker publiceert poorten met DNAT-regels die worden geëvalueerd voordat ufw het pakket ziet. Een enkele 3001:3001 maakt uw dashboard dus publiek toegankelijk via het internet, ongeacht uw firewall. Door te binden aan loopback blijft het privé en is alleen de reverse proxy geëxposeerd; een privé-instantie kan de proxy overslaan en 3001 bereiken via een zelfgehoste WireGuard VPN.

Een benoemde volume op /app/data. Alles wat Uptime Kuma onthoudt — de SQLite-database, uw monitors, notificatie-instellingen en statuspagina-logo's — staat daar. Als u dit verliest, begint u bij een leeg beheerderscherm; dit is het enige onderdeel dat u moet backuppen.

De image is vastgelegd op een major tag, :2. Dit is de huidige stabiele lijn; controleer Docker Hub voor de nieuwste major voordat u deze kopieert. Gebruik nooit een bewegende tag zoals latest, aangezien het project deze afkeurt. Een sprong naar een nieuwe major-versie bij deze image is een eenrichtings database-migratie; u wilt dit bewust triggeren en niet per ongeluk doen tijdens een routineuze pull.

Eén waarschuwing: /app/data moet op een bestandssysteem met POSIX file locks staan. Een lokale Docker volume is geschikt; op NFS raakt de SQLite-database beschadigd en krijgt u SQLITE_BUSY en database disk image is malformed, dus gebruik nooit een netwerkschijf.

Eerste run: maak het admin-account aan

Navigeer naar de instance via uw proxy op https://status.example.com, of via een SSH-tunnel: voer ssh -L 3001:127.0.0.1:3001 user@your-vps uit en open http://localhost:3001. De eerste pagina is een instellingenformulier voor de gebruikersnaam en het wachtwoord van de administrator; er is geen standaard login. Kies een sterk wachtwoord: dit dashboard heeft toegang tot de interne adressen en tokens van alles wat u monitort. Bent u het wachtwoord later vergeten? Reset het wachtwoord vanaf de host, niet via de browser:

sudo docker compose exec uptime-kuma npm run reset-password

Voeg eerst uw notificatiekanalen toe en test deze

Stel meldingen in voordat u monitors toevoegt. Zo kunt u direct een kanaal koppelen tijdens het aanmaken van een monitor. Ga naar Settings then Notifications then Setup Notification. Gebruik de Test-knop van elk kanaal om te bevestigen dat de melding aankomt. Een niet-geteste notificatie is de op één na meest voorkomende oorzaak van een stille fout in de configuratie.

Email (SMTP). Vul host, port, encryption, username, password, een From en een To in. De twee werkende combinaties zijn 465 met "Secure" ingesteld op TLS/SSL, of 587 met STARTTLS. Voor Gmail en de meeste providers met tweestapsverificatie moet u een app password genereren; een normaal wachtwoord resulteert in Error: Invalid login: 535-5.7.8 Username and Password not accepted.

Telegram. Stuur een bericht naar @BotFather, stuur /newbot, en kopieer de bot token. Gebruik voor uw chat ID de nieuwe bot eenmaal, open https://api.telegram.org/bot<token>/getUpdates en lees chat.id uit de JSON. Een bot waar u nog nooit een bericht naar heeft gestuurd, heeft een lege getUpdates en kan geen berichten verzenden.

Discord. Ga in het kanaal naar Edit Channel then Integrations then Webhooks then New Webhook, kopieer de URL en plak deze als een Discord notificatie.

Generic webhook. Voor andere diensten, zoals een Slack incoming webhook, een custom endpoint of een home-automation hook: het type Webhook stuurt een JSON-payload via een POST-verzoek naar de door u opgegeven URL. De ingebouwde Apprise-integratie ondersteunt de meeste van de negentig andere services op de lijst.

Voeg monitors toe, één type per keer

Klik op Add New Monitor, kies een type en stel de Friendly Name in, de Check Interval (60 seconden is een verstandelijke waarde), de Retries (het aantal opeenvolgende fouten voordat de status op "down" gaat; kies 2 of 3 zodat één verloren pakketje geen melding veroorzaakt) en de notificaties die verzonden moeten worden. De types die u zult gebruiken:

  • HTTP(s). Een volledige URL. "Up" betekent een geaccepteerde statuscode (standaard 200-299; pas dit aan onder Accepted Status Codes als 301 of 401 normaal is voor uw situatie). Dit is de standaardmethode voor websites en API's.
  • HTTP(s) - Keyword. Dezelfde aanvraag, maar "up" vereist daarnaast de aanwezigheid van een specifieke tekst in de body (tenzij Invert is uitgeschakeld). Dit detecteert situaties waarin de site 200 OK retourneert terwijl de tekst "Error establishing a database connection" wordt weergegeven. Een standaard HTTP-check zou dit als gezond beschouwen.
  • TCP Port. Een directe TCP-verbinding met een host en poort, voor diensten die geen HTTP gebruiken: SSH op 22, Postgres op 5432, een SMTP-server op 25, of een gameserver.
  • Ping. ICMP echo: een efficiënte methode voor bereikbaarheid en latency. Veel netwerken en cloud-firewalls blokkeren ICMP. Een rode ping-monitor kan dus betekenen dat de "host down" is óf dat de "provider ping blokkeert"; controleer dit met een TCP-monitor.
  • DNS. Lost een record op (A, AAAA, MX, TXT, enzovoort) via een door u opgegeven resolver. Dit kan het antwoord verifiëren, waardoor uitval van een registrar of DNS vroegtijdig wordt gedetecteerd.
  • Push. De "inside-out" monitor, die in het volgende deel wordt behandeld.

Een cron job monitoren met een push (heartbeat) monitor

Elke monitor hierboven verbindt van buitenaf met uw service. Een push-monitor werkt andersom: Uptime Kuma wacht, en uw taak roept de monitor aan om te bevestigen dat deze is uitgevoerd. Dit is de enige betrouwbare methode om een backup of cron te controleren: een HTTP-check weet alleen of een URL reageert, maar alleen de taak zelf weet of deze succesvol is voltooid.

Maak een monitor aan van het type Push. Uptime Kuma genereert een unieke URL zoals:

https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=OK&ping=

Stel het Heartbeat Interval in op de frequentie waarmee de taak wordt uitgevoerd, plus een kleine marge. Voeg vervolgens één regel toe aan het einde van het script, zodat de melding alleen bij succes wordt verzonden:

#!/usr/bin/env bash
set -euo pipefail
# ... your backup or job runs here; set -e aborts on any failure ...
curl -fsS --retry 3 "https://status.example.com/api/push/j8Xa2Kd9Qe?status=up&msg=backup+ok&ping="

Als de taak mislukt, stopt set -e voordat de curl-opdracht wordt uitgevoerd; als de server uit staat, wordt het script ook niet uitgevoerd. In beide gevallen stopt de heartbeat. Zodra de periode van het interval plus de retries is verstreken, zet Uptime Kuma de monitor op down en wordt u gewaarschuwd. Behandel deze push-token als een geheim: iedereen met deze token kan een valse succesmelding versturen.

Maak een publieke statuspagina

Een statuspagina is de weergave voor klanten: welke services actief zijn en hun recente geschiedenis, zonder uw dashboard te tonen. Ga naar Status Pages then New Status Page, geef de pagina een naam en een slug (het publieke pad, zoals /status/main), sleep de gewenste monitors naar groepen zoals "Websites" en "APIs", voeg een logo en een korte beschrijving toe, en klik op Save. U kunt de pagina ook koppelen aan een eigen domein, zodat status.example.com deze direct serveert.

Twee waarschuwingen: voeg alleen monitors toe die u publiekelijk wilt maken, aangezien een statuspagina onthult dat een service bestaat en of deze actief is; en het dashboard blijft beveiligd achter uw login, terwijl de statuspagina opzettelijk publiek is en geen authenticatie vereist.

Gebruik een reverse proxy met TLS, en let op de websockets

Plaats bij een publieke instantie een reverse proxy voor de container die aan loopback is gebonden voor TLS en een hostname. Het detail waar iedereen tegenaan loopt: De UI van Uptime Kuma is een live Socket.IO app, dus de proxy moet de WebSocket-verbinding upgraden. Als u dit vergeet, wordt de pagina geladen maar wordt er nooit verbinding gemaakt; het dashboard blijft op "Connecting..." staan, live heartbeats worden niet bijgewerkt en de browserconsole toont WebSocket connection to 'wss://.../socket.io/...' failed.

Installeer nginx en certbot, en schrijf de vhost die naar de loopback-poort proxy't. Gebruik voor nu poort 80 en laat certbot daarna TLS toevoegen; de uitdaging, de renewal timer en de foutmodi worden behandeld in issuing Let's Encrypt certificates with certbot and nginx.

sudo apt install -y nginx certbot python3-certbot-nginx

Sla dit op als /etc/nginx/sites-available/status.example.com; de twee WebSocket-regels zijn de belangrijkste:

server {
    listen 80;
    server_name status.example.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 3600s;
    }
}

Activeer de site, test de configuratie, en laat certbot de block herschrijven om te luisteren op poort 443, voeg het certificaat toe en voeg een HTTP-naar-HTTPS redirect toe:

sudo ln -s /etc/nginx/sites-available/status.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d status.example.com

De combinatie van Upgrade en Connection "upgrade" is essentieel, en proxy_read_timeout 3600s voorkomt dat nginx de langdurige socket verbreekt; certbot kopieert beide naar de gegenereerde 443-block. Als u al meerdere containers achter één proxy draait, doet routing them through Traefik with automatic TLS hetzelfde met container labels en staat standaard WebSocket upgrades toe.

Gebruik geen basic-auth voor de volledige vhost, omdat dit ook de publieke statuspagina en de /api/push endpoint blokkeert. Gebruik de ingebouwde login van Uptime Kuma, voeg fail2ban watching for repeated failed logins toe als de instantie via internet bereikbaar is, en als het dashboard nooit publiek hoeft te zijn, verwijder dan de proxy en bereik het via een VPN.

Certificate-expiry monitoring, done right

Een HTTP(s) monitor kan u waarschuwen voordat een TLS-certificaat verloopt: vink Certificate Expiry Notification aan en Uptime Kuma geeft een melding na een ingesteld aantal dagen. Twee fouten leiden tot onjuiste resultaten. Monitor op hostname, niet op IP. Een verzoek zonder SNI ontvangt het standaardcertificaat van de server, waardoor u Hostname/IP does not match certificate's altnames ziet. Vink Ignore TLS/SSL Error niet aan bij een monitor waarvoor u vervaldata wilt ontvangen: deze optie is bedoeld voor interne hosts met zelfgetekende certificaten (unable to verify the first certificate, DEPTH_ZERO_SELF_SIGNED_CERT), maar het zorgt ervoor dat Uptime Kuma het certificaat (inclusief de vervaldatum) niet meer controleert.

Backups: het is één directory

Omdat alles in /app/data staat, is een backup een kopie van dat volume. Maak deze kopie terwijl de container is gestopt. Dit zorgt ervoor dat het SQLite-bestand consistent blijft:

cd /srv/uptime-kuma
sudo docker compose stop
sudo docker run --rm \
  -v uptime-kuma_kuma-data:/data \
  -v /var/backups/kuma:/backup \
  alpine tar czf /backup/kuma-$(date -u +%Y%m%dT%H%M%SZ).tgz -C /data .
sudo docker compose start

Controleer eerst de werkelijke naam van het volume met docker volume ls | grep kuma. Compose voegt namelijk de projectdirectory toe als prefix. Kopieer het tarball-bestand vervolgens naar een andere machine. Een backup op dezelfde VPS is slechts een kopie en geen echte backup. Herstellen werkt in omgekeerde volgorde: stop de stack, extraheer de bestanden naar een leeg /app/data volume en start de stack opnieuw.

Upgrades

Upgrades bestaan uit een image pull:

cd /srv/uptime-kuma
sudo docker compose pull
sudo docker compose up -d

De nieuwe container voert bij de eerste start alle database-migraties uit; houd docker compose logs -f in de gaten. Maak de bovenstaande backup voordat u de image pull uitvoert. Blijf binnen een major tag: een overstap van :1 naar :2 is een eenrichtingsmigratie. Maak daarom eerst een backup en controleer de release notes.

Foutmodi, met de strings die u zult zien

Foutieve "down" status op een monitor gericht op localhost. De monitor wordt rood met timeout of 48000ms exceeded of connect ETIMEDOUT, terwijl de service wel reageert vanaf uw laptop. Als de monitor gericht is op dezelfde host waar Uptime Kuma draait, heeft een CPU- of geheugenpiek de controle verhinderd, niet het doelwit. Verplaats de monitor naar een aparte VPS en gebruik de publieke hostname.

connect ECONNREFUSED 127.0.0.1:443 (of een andere poort). Er werd niet geluisterd op die poort: ofwel de service is offline, ofwel u monitort localhost vanuit de container, waarbij 127.0.0.1 de container is en niet uw server. Monitor de publieke hostname, niet de loopback.

Invalid login: 535-5.7.8 Username and Password not accepted bij een e-mailtest. De SMTP-gegevens zijn onjuist, of de provider vereist een app-specifiek wachtwoord en heeft uw accountwachtwoord ontvangen. Genereer een app-wachtwoord en plak dit.

connect ETIMEDOUT of queryA ETIMEDOUT <host> bij een e-mailtest. Verkeerde poort, of de provider blokkeert uitgaande SMTP. Controleer of 465 of 587 overeenkomt met de Secure/STARTTLS-instelling, en test vanaf de host met nc -vz smtp.example.com 587. Veel providers blokkeren uitgaande 25 en sommige blokkeren submission-poorten totdat u hierom vraagt.

self signed certificate of unable to verify the first certificate bij een e-mailtest. Uw SMTP-server presenteert een certificaat dat Node niet vertrouwt; los het certificaat van de mailserver op in plaats van het probleem te maskeren.

Dashboard blijft hangen op "Connecting...", console toont WebSocket connection ... failed. De reverse proxy voert de WebSocket-upgrade niet uit. Voeg de Upgrade en Connection "upgrade" headers toe in nginx, of gebruik een proxy die deze standaard doorstuurt, zoals Traefik of Caddy. De HTML wordt geladen omdat dit een normale HTTP GET is; alleen de live socket vereist de upgrade.

Cert-expiry monitor waarschuwt nooit, of waarschuwt onjuist. Ofwel is Ignore TLS/SSL Error aangevinkt, wat de certificaatcontrole uitschakelt, of de monitor is gericht op een IP-adres en leest het verkeerde certificaat door ontbrekende SNI, wat Hostname/IP does not match certificate's altnames resulteert. Vink "ignore" uit en monitor via de hostname.

SQLITE_BUSY of database disk image is malformed in de logs. Het /app/data volume staat op een bestandssysteem zonder correcte file locking, meestal NFS; verplaats dit naar een lokale Docker volume en herstel de gegevens vanuit een backup.

FAQ

Waar moet ik mijn uptime monitor draaien?

Op een andere server dan de servers die u controleert. Ideaal is een andere provider of regio, waarbij u de servers via de hostname over het publieke internet bereikt, precies zoals uw gebruikers dat doen. Als de monitor op dezelfde machine staat als de doelservers, zorgt een serverstoring ervoor dat zowel de server als de monitor uitvalt. Een overbelaste host kan bovendien foutieve "down" meldingen geven voor services die wel functioneren. Een kleine, aparte VPS voorkomt beide problemen.

Hoe ontvang ik meldingen via Telegram of e-mail?

Voeg het kanaal toe onder Settings then Notifications en koppel het vervolgens aan elke monitor. Gebruik voor Telegram een bot met @BotFather en lees chat.id uit https://api.telegram.org/bot<token>/getUpdates. Gebruik voor e-mail 465 voor SSL of 587 voor STARTTLS met een app-wachtwoord als uw provider twee-factor authenticatie gebruikt. Klik op Test en controleer of het bericht aankomt voordat u het systeem volledig vertrouwt.

Kan Uptime Kuma een cron job of backup script monitoren?

Ja, dat is de Push monitor: Uptime Kuma geeft u een URL en u curl deze aan het einde van het script, zodat de melding alleen wordt verzonden bij succes. Als de taak mislukt of de server uitstaat, komt de heartbeat niet aan en krijgt u een melding nadat het interval is verstreken. Dit is de enige betrouwbare manier om te weten of een geplande taak daadwerkelijk is uitgevoerd, aangezien een externe controle de interne status niet kan zien.

Uptime Kuma vs Zabbix, welke moet ik gebruiken?

Uptime Kuma beantwoordt de vraag "is het systeem bereikbaar vanaf de buitenwereld en is er een melding verzonden" binnen tien minuten met minimale resources, inclusief een statuspagina. Het verzamelt geen diepgaande metrics zoals trends voor CPU, geheugen en disk, of drempelwaarden voor het gehele netwerk. Voor dat doel is een volledige Zabbix monitoring server de zwaardere, agent-gebaseerde tool; veel gebruikers draaien beide. Twijfelt u nog wat u moet draaien? ons overzicht van wat u in 2026 zelf kunt hosten plaatst monitoring in context.

#uptime-kuma#monitoring#docker#self-hosting#status-page