Docker is eenvoudig te demonstreren en verrassend lastig goed uit te leggen.

Je kunt een docker run-commando kopiëren, een poort openen en binnen een minuut een webpagina zien. Dat voelt als vooruitgang. Daarna komen de logische vragen: waar komen de bestanden vandaan? Waarom staan er twee getallen in 8080:80? Wat blijft bestaan als je de container verwijdert? Wanneer zet je een commando om naar Compose? En is deze configuratie veilig genoeg om met internet te verbinden?

Die vragen zijn geen bijzaken. Ze zijn Docker.

Daarom begint OnlinePilots met één compleet interactief leerpad: Bouw je eerste Docker-webserver. In plaats van losse commando's te presenteren, laat de module je één klein systeem bouwen, bekijken, kapotmaken, herstellen en uiteindelijk deployen. Iedere stap verandert hetzelfde live model van je container.

Het doel is niet om Docker-syntax uit je hoofd te leren. Het doel is leren denken in containers.

Start de interactieve Docker-module →

Waarom een webserver het juiste eerste project is

Een eenvoudige webserver is klein genoeg om te overzien, maar compleet genoeg om de belangrijkste grenzen van Docker zichtbaar te maken.

Er is een image, een actief proces, een containerbestandssysteem en een interne netwerkpoort. Je hebt een route nodig van je computer naar de container. De server wordt nuttiger zodra websitebestanden buiten de tijdelijke containerlaag staan. Je kunt de configuratie vastleggen in Compose en zodra je de dienst verder dan localhost ontsluit, heb je verstandige beveiligingsmaatregelen nodig.

Niets hiervan is een kunstmatig lesvoorbeeld. Het model dat je leert gebruik je later ook voor een persoonlijke website, intern dashboard, homelab-dienst of kleine productieapplicatie.

Het mentale model: image, container en host

Drie objecten doen het meeste denkwerk.

Een image is het verpakte startpunt. Docker omschrijft een image als een gestandaardiseerd pakket met de bestanden, binaries, libraries en configuratie die nodig zijn om een container te draaien. Images zijn onveranderlijk en opgebouwd uit lagen. Met nginx:1.28-alpine kies je dus zowel een applicatie als een specifieke verpakte omgeving.

Een container is een uitvoerbaar exemplaar van die image: een geïsoleerd proces met een eigen bestandssysteem, netwerk en procesboom. Het is geen kleine virtuele machine. Containers delen de kernel van de host en kunnen daardoor lichtgewicht zijn.

De host is de machine waarop Docker draait. De host bezit de gepubliceerde poort, bewaart persistente gegevens en bepaalt welke resources en rechten de container krijgt.

De interactieve module houdt deze objecten gelijktijdig zichtbaar. Als je een poort wijzigt of opslag koppelt, verandert het infrastructuurdiagram mee. Juist de verbinding tussen een configuratiekeuze en het zichtbare gevolg zorgt voor begrip.

Het leerpad in elf stappen

1. Selecteer een image

Het pad begint met nginx, omdat je daarmee een echte webserver hebt zonder eerst applicatiecode te schrijven. Je vergelijkt verplaatsbare tags zoals nginx:alpine met een versiegebonden tag zoals nginx:1.28-alpine.

Een verplaatsbare tag is handig om te experimenteren. Een versiegebonden verwijzing maakt deployments beter reproduceerbaar, omdat een update een bewuste keuze wordt. Voor strikte reproduceerbaarheid kunnen productieteams nog een stap verder gaan en een image-digest vastzetten.

2. Geef de container een naam

Docker kan zelf een naam verzinnen, maar een doelbewuste naam maakt commando's, logs en monitoring beter leesbaar. my-webserver vertelt wat de container doet.

Hier wordt ook een belangrijk onderscheid duidelijk: de image is het sjabloon; de container met een naam is één actief exemplaar dat uit dat sjabloon is gemaakt.

3. Koppel een poort

De notatie 8080:80 wordt eenvoudiger als je die van buiten naar binnen leest:

browser → localhost:8080 → container:80 → nginx

Poort 80 hoort bij nginx in de container. Poort 8080 hoort bij je Docker-host. Door de poort te publiceren ontstaat een route tussen beide. Docker waarschuwt dat gepubliceerde poorten standaard ook buiten de host bereikbaar kunnen zijn. Bindingen en firewallregels zijn dus belangrijk wanneer je van laptop naar server gaat.

4. Start de container in de simulator

Het eerste volledige commando heeft nu betekenis:

docker run -d --name my-webserver -p 8080:80 nginx:1.28-alpine

De simulator past het commando toe zonder een echte Docker-daemon te gebruiken. Je ziet de container actief worden en de netwerkroute oplichten. Dit is een veilige plaats om fouten te maken: een ongeldige naam of poort geeft feedback voordat je iets deployt.

5. Bekijk de virtuele docker ps

Starten is niet hetzelfde als controleren. De module toont een realistische docker ps-weergave waarin je image, status, poortkoppeling en naam controleert.

Die gewoonte schaalt mee. Op een echte host bekijk je ook de healthstatus, logs en HTTP-respons. Een deployment is pas afgerond als de dienst zich gedraagt zoals bedoeld.

6. Verwijder de container

Vervolgens verwijder je het actieve exemplaar. De image blijft beschikbaar, maar de container en zijn schrijfbare laag zijn weg. Zo verdwijnt bewust het idee dat een container een permanent klein servertje is.

Containers horen vervangbaar te zijn. Configuratie en belangrijke gegevens hebben een levensduur nodig buiten één containerinstantie.

7. Ontdek wat verdwenen is

Bestanden die alleen in de schrijfbare containerlaag stonden, verdwijnen wanneer die container wordt vernietigd. Dat is geen fout in Docker, maar de verwachte lifecycle.

De les maakt dit verlies eerst zichtbaar en introduceert daarna pas de oplossing. Als je het probleem begrijpt, verandert een volume van mysterieuze syntax in een logische architectuurkeuze.

8. Voeg een volume toe

De websitemap wordt aan nginx gekoppeld:

-v ./site:/usr/share/nginx/html:ro

De lokale map ./site hoort bij de host. nginx ziet deze op /usr/share/nginx/html. Het achtervoegsel :ro maakt de mount in de container alleen-lezen, wat passend is voor statische websitebestanden.

Volgens de Docker-documentatie bestaat de inhoud van een volume buiten de lifecycle van een afzonderlijke container. Bind mounts en door Docker beheerde volumes lossen verwante maar verschillende problemen op: een bind mount is handig als je hostbestanden rechtstreeks wilt benaderen; een named volume is vaak een sterke standaard voor persistente gegevens die een applicatie zelf genereert.

9. Zet de configuratie om naar Compose

Een lang shellcommando werkt, maar is makkelijk te vergeten en lastig te beoordelen. Compose legt de gewenste toestand vast in YAML:

services:
  web:
    image: nginx:1.28-alpine
    container_name: my-webserver
    ports:
      - "8080:80"
    volumes:
      - ./site:/usr/share/nginx/html:ro
    restart: unless-stopped

De interactieve editor legt de geselecteerde regel meteen uit. Poorten, opslag en herstartbeleid zijn niet langer verborgen flags in je terminalgeschiedenis, maar een leesbaar deploymentmodel dat je kunt controleren, versioneren en herhalen.

10. Voer een security- en configuratiecheck uit

Containers bieden isolatie, maar isolatie betekent niet automatisch dat iets veilig is. De module controleert een praktische basis:

  • gebruik een versiegebonden image;
  • mount gepubliceerde websitebestanden alleen-lezen;
  • maak waar mogelijk het containerbestandssysteem alleen-lezen;
  • voorkom privilege-escalatie;
  • verwijder onnodige Linux-capabilities;
  • stel CPU- en geheugenlimieten in.

De score is begeleiding, geen certificering. Echte beveiliging hangt ook af van de herkomst en actualiteit van images, secretbeheer, de Docker-host, netwerkblootstelling, logging en back-ups. Docker documenteert daarnaast rootless mode, waarbij daemon en containers zonder rootrechten kunnen draaien als extra maatregel op hostniveau.

11. Deploy hetzelfde model op je eigen host

Pas nu verlaat je de simulator. De laatste stap vertaalt het model naar een korte operationele routine:

docker compose config
docker compose up -d
docker compose ps
docker compose logs --tail=100 web
curl -I http://localhost:8080

Valideer eerst het Compose-model. Start het daarna, controleer de status, lees de logs en test het echte HTTP-endpoint. Staat er een reverse proxy of Cloudflare Tunnel voor, controleer die laag dan afzonderlijk en stel de originpoort niet ruimer bloot dan nodig.

De vier interactieve functies achter de module

Het leerpad combineert vier hulpmiddelen, omdat ieder een andere vraag beantwoordt.

1. Docker-commandosimulator

Wat gaat dit commando doen? De simulator zet opties om in zichtbare status zonder dat je een lokale omgeving nodig hebt. Je krijgt directe feedback terwijl de vorm van het echte commando behouden blijft.

2. Compose-editor met directe uitleg

Wat regelt deze regel? Door een regel te selecteren verbind je YAML-structuur aan runtimegedrag. Dat helpt vooral omdat inspringing en nesting betekenis hebben in Compose.

3. Visuele netwerk- en volumeweergave

Waar gaan verkeer en gegevens heen? Het diagram scheidt browser, host, container en opslag. Het verandert zodra je een poort publiceert, container start of volume koppelt.

4. Automatische security- en configuratiecheck

Wat zie ik over het hoofd? De check vertaalt abstract advies naar concrete, controleerbare configuratie. Ook wordt duidelijk dat een werkende en een verantwoord ingerichte deployment twee verschillende mijlpalen zijn.

Wat je aan het einde moet begrijpen

Na de module kun je het volgende uitleggen in plaats van alleen herhalen:

  • een image is een verpakt, onveranderlijk startpunt;
  • een container is een vervangbaar runtime-exemplaar;
  • een poortkoppeling verbindt een hostpoort met een containerpoort;
  • gegevens in de containerlaag zijn tijdelijk;
  • volumes of bind mounts bewaren belangrijke gegevens buiten die lifecycle;
  • Compose legt het gewenste applicatiemodel vast;
  • controle omvat status, logs en een respons op applicatieniveau;
  • beveiliging ontstaat uit bewuste lagen en niet alleen door Docker te gebruiken.

Die basis is belangrijker dan twaalf commando's uit je hoofd kennen. Zodra het model helder is, worden nieuwe diensten varianten van dezelfde vragen: wat draait er, wat is bereikbaar, wat blijft bestaan, wat vertrouw je en hoe bewijs je dat het werkt?

Begin in de simulator, eindig op je eigen host

OnlinePilots bouwt aan een plek waar mensen leren denken in containers. Een echte cloudterminal en tijdelijke Docker-omgevingen kunnen later waardevol zijn. De eerste versie begint bewust kleiner: een commandosimulator, uitlegbare Compose-editor, visueel infrastructuurmodel en gerichte securitycheck.

Dat is genoeg om de belangrijkste sprong te maken: van een commando kopiëren naar een deployment begrijpen.

Bouw je eerste Docker-webserver →

Primaire bronnen