Direct naar de inhoud

Cookie-instellingen

Kies per soort welke cookies je toestaat. Je kunt je keuze altijd wijzigen via Cookie-instellingen onderaan elke pagina. Privacyverklaring

Noodzakelijk

Altijd aan

Nodig om in te loggen, je winkelwagen te bewaren en je keuzes te onthouden. Deze staan altijd aan.

Welke cookies?
  • weboke_sessie, weboke_klant, weboke_remember: je sessie en ingelogd blijven
  • weboke_basket: je winkelwagen
  • wkBtwIncl: prijzen met of zonder btw tonen
  • wok_cookies: je cookiekeuze, 12 maanden

Meet welke advertentie tot een bezoek of bestelling leidt, zodat we niet betalen voor advertenties die niets doen.

Welke cookies?
  • Google Ads via Google Tag Manager (_gcl_au, _gcl_aw), tot 90 dagen
  • OpenAI Ads, advertenties in ChatGPT
  • wok_aff: via welke partner je bij ons kwam (affiliateprogramma), 60 dagen

4,6

Land en taal

Elk land heeft zijn eigen site, met prijzen en btw van dat land.

Bekijken

Recepten: Uptime Kuma en Vaultwarden

Module 9: Docker en docker compose · Leestijd: 13 minuten

Leerdoel: Na deze les kun je Uptime Kuma en Vaultwarden met docker compose achter Caddy draaien, met https, dichte registratie, back-up van de volumes en een vaste manier van bijwerken.

Kernbegrippen: reverse proxy-container, Caddyfile, automatische https, Uptime Kuma, Vaultwarden, DOMAIN, SIGNUPS_ALLOWED, ADMIN_TOKEN, Argon2, .env, websockets, volumes back-uppen, docker compose pull, eigen header

Wat we bouwen

Twee handige diensten op je eigen server, elk op een eigen subdomein:

  • Uptime Kuma op status.example.com: een bewakingsprogramma met een webinterface dat je websites, poorten en certificaten in de gaten houdt en je een melding stuurt als er iets uitvalt (les 8.3). Let op: een bewaking die op dezelfde server draait als wat hij bewaakt, ziet niet dat die hele server uitvalt. Gebruik hem dus voor je andere sites en diensten, of zet hem op een tweede server.
  • Vaultwarden op kluis.example.com: een lichte, onafhankelijke serverversie die werkt met de apps en browserextensies van Bitwarden. Een wachtwoordkluis is gevoelige software: alleen doen als je bereid bent hem goed bij te houden en te back-uppen. Het is ook prima om gewoon een wachtwoordmanager van een aanbieder te gebruiken.

Ervoor zetten we Caddy in een container: die neemt poort 80 en 443 aan, regelt zelf de certificaten van Let's Encrypt (les 7.3 en 7.4) en stuurt het verkeer door naar de juiste container. Uptime Kuma en Vaultwarden publiceren zelf geen poorten (les 9.3).

internet ──443──> caddy ──> uptime-kuma:3001
                        └─> vaultwarden:80

Vooraf

  1. Docker Engine met de compose-plug-in (les 9.2).
  2. Twee DNS-records die naar je server wijzen, A en AAAA (les 7.1): status.example.com en kluis.example.com.
  3. Poort 80 en 443 vrij op de server. Draait er al een nginx of Caddy van het systeem op die poorten, dan kan de Caddy-container ze niet gebruiken. Kies dan: of je stopt de systeemwebserver, of je laat die het proxywerk doen en publiceert de containers op 127.0.0.1 (les 9.3). In dit recept doet de Caddy-container het.
  4. In ufw 80/tcp, 443/tcp en voor HTTP/3 ook 443/udp open (les 5.2). Strikt genomen gaat Docker langs ufw heen, maar zo klopt je firewalloverzicht met de werkelijkheid.

De bestanden

Alles komt in één map, /srv/diensten/:

/srv/diensten/
├── compose.yaml
├── Caddyfile
└── .env

compose.yaml

services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config

  uptime-kuma:
    image: louislam/uptime-kuma:2
    restart: unless-stopped
    volumes:
      - uptime-kuma:/app/data

  vaultwarden:
    image: vaultwarden/server:1.37.5
    restart: unless-stopped
    environment:
      DOMAIN: "https://kluis.example.com"
      SIGNUPS_ALLOWED: "true"
      ADMIN_TOKEN: ${VW_ADMIN_TOKEN}
    volumes:
      - ./vw-data:/data

volumes:
  caddy-data:
  caddy-config:
  uptime-kuma:

Kijk vóór je begint welke versie van Vaultwarden de nieuwste is (de releases op GitHub) en zet die in de tag. Alleen Caddy publiceert poorten; die moeten publiek zijn. De volumes caddy-data (certificaten), uptime-kuma en de map vw-data bevatten alles wat je moet bewaren.

Caddyfile

{
	email beheer@example.com
}

status.example.com {
	reverse_proxy uptime-kuma:3001
	header {
		X-Weboke-Cursus "jouw-code-uit-de-opdracht"
		defer
	}
}

kluis.example.com {
	reverse_proxy vaultwarden:80
}

Caddy haalt voor beide namen vanzelf een certificaat en stuurt http door naar https. uptime-kuma en vaultwarden zijn de servicenamen uit het compose-bestand: Caddy vindt ze op het interne netwerk. Het header-blok zet een extra kopregel in elk antwoord van status.example.com; die gebruik je in de opdracht als bewijs dat jouw proxy-container draait. Met defer wordt de header gezet nadat de achterliggende dienst zijn antwoord heeft gegeven. Wil je ook HSTS en de andere beveiligingsheaders uit les 7.4, zet ze dan in hetzelfde blok.

Vaultwarden veilig instellen

Vier dingen maken het verschil tussen een veilige en een gevaarlijke kluis.

Eén: alleen via https. De webkluis van Bitwarden gebruikt de cryptografie van de browser, en browsers geven die alleen vrij op https-pagina's. Zonder https werkt het dus niet goed, en dat is maar goed ook. De Vaultwarden-documentatie raadt een reverse proxy aan voor https, zoals Caddy hier. Zet DOMAIN op het volledige https-adres.

Twee: registratie dicht. Met SIGNUPS_ALLOWED: "true" kan iedereen die de pagina vindt een account maken op jouw server. Start dus, maak meteen je eigen account(s), zet de waarde op "false" en voer docker compose up -d opnieuw uit. Wil je later iemand toevoegen, gebruik dan de uitnodigingsfunctie in het beheerscherm.

Drie: een gehasht beheertoken. Het beheerscherm (/admin) is afgeschermd met ADMIN_TOKEN. Zet daar geen leesbaar wachtwoord in, maar een Argon2-hash. Die maak je met Vaultwarden zelf:

anna@web1:/srv/diensten$ sudo docker compose exec vaultwarden /vaultwarden hash
Password:
Confirm Password:

ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$...'

Zet die regel in .env (dus VW_ADMIN_TOKEN='$argon2id$...', met enkele aanhalingstekens) en maak het bestand alleen voor root leesbaar: sudo chmod 600 .env. In een .env-bestand hoef je de $-tekens niet te verdubbelen; zet je de hash direct onder environment: in het compose-bestand, dan wel (elke $ wordt $$), anders probeert Compose ze als variabelen in te vullen. Inloggen op /admin doe je met het wachtwoord dat je typte, niet met de hash. Let op: instellingen die je in het beheerscherm opslaat, komen in vw-data/config.json en gaan dan vóór de omgevingsvariabelen.

Vier: back-up en herstel. Alles staat in vw-data: de database, bijlagen en sleutels. Neem die map mee in je restic-back-up (les 8.2), en volg voor de database de back-upaanwijzingen in de Vaultwarden-wiki, zodat je geen half geschreven bestand kopieert. Test het terugzetten (opdracht O8.2): een kluis zonder werkende back-up is een risico voor al je wachtwoorden.

Meldingen tussen apparaten (websockets) werken bij recente versies van Vaultwarden over dezelfde poort; Caddy geeft ze zonder extra instelling door.

Uptime Kuma instellen

Na docker compose up -d open je https://status.example.com. Bij het eerste bezoek vraagt Uptime Kuma je een beheerdersaccount aan te maken. Doe dat meteen: zolang dat account er niet is, kan iedereen die de pagina vindt het aanmaken. Wil je dat risico helemaal niet, laat het status-blok dan eerst weg uit de Caddyfile, maak het account via een SSH-tunnel (les 2.3) en zet het blok daarna terug.

Daarna voeg je monitors toe: een HTTP-monitor voor je website, een TCP-monitor voor een poort, een certificaatwaarschuwing, en een meldkanaal (mail, een chatprogramma of een pushdienst). Zet ook tweestapsverificatie aan in de instellingen van Uptime Kuma.

Starten en controleren

anna@web1:/srv/diensten$ sudo docker compose up -d
anna@web1:/srv/diensten$ sudo docker compose ps
NAME                     SERVICE       STATUS          PORTS
diensten-caddy-1         caddy         Up 2 minutes    0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, ...
diensten-uptime-kuma-1   uptime-kuma   Up 2 minutes (healthy)
diensten-vaultwarden-1   vaultwarden   Up 2 minutes (healthy)
anna@web1:/srv/diensten$ sudo docker compose logs caddy | grep -i "certificate obtained"
anna@web1:~$ curl -sI https://status.example.com | grep -i x-weboke
x-weboke-cursus: jouw-code-uit-de-opdracht

Alleen Caddy heeft poorten. Lukt het certificaat niet, dan staat in de logs van Caddy waarom: meestal wijst de DNS nog niet naar de server, of is poort 80 niet bereikbaar (les 7.3).

Bijwerken

Een container wordt niet door unattended-upgrades bijgewerkt (les 4.2). Maak er een vast moment van, bijvoorbeeld elke twee weken:

anna@web1:/srv/diensten$ sudo docker compose pull
anna@web1:/srv/diensten$ sudo docker compose up -d
anna@web1:/srv/diensten$ sudo docker image prune

pull haalt de nieuwste images binnen de tag die je gekozen hebt (dus caddy:2 blijft binnen versie 2). Voor Vaultwarden met een versienummer pas je eerst de tag aan na het lezen van de release notes. Lees bij een nieuwe hoofdversie altijd de release notes: soms moet er iets aan je instellingen veranderen. Maak vóór een grote update een back-up van de volumes.

Volg ook de beveiligingsmeldingen van de makers. Een kwetsbaarheid in Vaultwarden of Caddy wordt alleen opgelost als jij de nieuwe versie ophaalt.

In de praktijk

Dit recept werkt op elke VPS met Docker, bij WebOké of bij een andere aanbieder. Het is zelfhulp: de aanbieder van je VPS beheert niets binnen je containers. Maak een snapshot voordat je het voor het eerst opzet, dan kun je met een gerust hart experimenteren.

Samenvatting

  • Eén compose-bestand met Caddy als reverse proxy-container; alleen Caddy publiceert poort 80 en 443, de diensten niets.
  • Caddy regelt certificaten en https automatisch en kan met header eigen kopregels zetten.
  • Vaultwarden: https verplicht, DOMAIN op het https-adres, registratie dicht na je eigen account, ADMIN_TOKEN als Argon2-hash in een .env met rechten 600.
  • Uptime Kuma: meteen het beheerdersaccount aanmaken en tweestapsverificatie aanzetten; bewaak er vooral andere servers en sites mee.
  • Back-up de volumes en de map vw-data, en werk bij met docker compose pull en up -d op een vast moment.

Quiz

1. Waarom publiceren Uptime Kuma en Vaultwarden in dit recept zelf geen poorten?



2. Waarom werkt de webkluis van Vaultwarden niet goed via gewoon http?



3. Je hebt je eigen Vaultwarden-account aangemaakt. Wat is de volgende stap?



4. Je zet de Argon2-hash van het beheertoken direct onder environment: in compose.yaml en krijgt waarschuwingen over onbekende variabelen. Waarom?



5. Hoe werk je deze diensten bij?



Opdracht

Opdracht Z9.4: Bewijs dat je container draait. Haal in de opdracht je persoonlijke code op en zet die in de Caddyfile van je Caddy-container als header X-Weboke-Cursus voor een subdomein van jou (zoals status.<jouwdomein>). Herlaad Caddy en vul de hostnaam in. Het programma haalt https://<hostnaam>/ op en controleert dat het certificaat geldig is en dat de header precies jouw code bevat. Plak daarnaast de uitvoer van docker compose ps en beantwoord welke dienst als enige poorten publiceert.

Opdracht Z9.4: Bewijs dat je container draait

Klik op "Toon mijn code" en zet de kopregel X-Weboke-Cursus met die code in je Caddyfile, bijvoorbeeld: header { X-Weboke-Cursus "<code>" }. Van buiten is niet te zien of iets in een container draait; daarom plak je ook de uitvoer van docker compose ps (die bewaren we niet).




Wat je invult en wat we vinden, slaan we niet op. Je browser onthoudt je antwoorden en of je de opdracht hebt gehaald. Ben je aangemeld, dan bewaren we alleen dat je de opdracht (bijna) goed had in Mijn cursussen; daar kun je het ook verwijderen.

Verder lezen

Even geduld…

Stel je domeinen in

Regel per domein de nameservers, de koppeling aan je hosting en wie de eigenaar wordt.

Je domeinen laden…