PR Peter ReckersInnovatiepartner
← Alle projecten
atze · 5 juni 2026 · 4 min

Stagiair, Claude Code en een portfolio live in 5 minuten

Atze is stagiair bij 42 Workspace, mijn geliefde coworking space in Rotterdam, en moest een portfolio-site maken voor zijn opleiding. Bij de AI Playground die ik daar namens 42 host, zag hij hoe je tegenwoordig sites bouwt: ontwerpen met Claude, bouwen met Claude Code. Ik heb het hem geleerd, en hij leverde een nette single-page site af. Aan mij de laatste meters: de pipeline van mijn eigen GitLab naar Dokploy. Van een los HTML-bestand in zijn Downloads-map naar een echt adres met een groen slotje: 5 minuten werk. De rest was wachten op DNS.

Het staat live op atzedezwart.nl. Hieronder hoe het daar kwam.

De opzet: één bestand, geen framework

De site is bewust simpel. Eén index.html, alles erin: styling, content, een beetje JavaScript. Geen build-stap, geen npm, geen 200 dependencies die over een jaar omvallen. Voor een schoolportfolio is dat precies goed.

De pagina doet alsof het meerdere pagina's zijn: een hoofdsite met secties (Over mij, CV, Talentontwikkeling, Stage, Reflectie) en wat detailpagina's die je opent en weer dichtklapt. Allemaal met een paar regels JavaScript die secties tonen en verbergen. Voor een stagiair die net met Claude Code begint: knap werk.

De bug die elk menu naar dezelfde plek stuurde

Eerste echte vraag van de avond: "kan jij die reflectie-sectie vinden op home." En daarna: "waarom liet de html dat niet zien en fix het."

De Reflectie-sectie zát er gewoon in. Het probleem zat in de navigatie. Wie op een menu-item klikte, maakte niet uit welk, belandde steevast bij Talentontwikkeling. Niet bij waar je op klikte.

De oorzaak was klein en logisch. De functie die de hoofdsite terugzet, kreeg geen idee mee van waar je naartoe wilde. Hij viel terug op een standaardwaarde, en die standaard was nu eenmaal Talentontwikkeling. Dus elke klik = zelfde bestemming.

De fix: de functie een doel-sectie meegeven en daar netjes naartoe scrollen.


function showMain(sectionId) {
  document.getElementById("detail-page").style.display = "none";
  document.getElementById("main-site").style.display = "block";
  if (sectionId) {
    setTimeout(() => {
      const el = document.getElementById(sectionId);
      if (el) el.scrollIntoView({ behavior: "smooth" });
    }, 50);
  }
}

Even een lokale server starten, in de browser klikken, ververst. Reflectie doet wat het hoort te doen. Dit is het soort bug waar je als beginner een uur op staart en die met een tweede paar ogen in twee minuten klaar is.

Van Downloads-map naar echte server

Tweede sessie, andere dag, scherpere opdracht: "haal website atze uit men downloads en plaats op werkplaats dokploy container."

In zijn Downloads stond niet één bestand maar een rij iteraties. atze-portfolio_21.html was de nieuwste. Die werd index.html in een schone repo op mijn eigen GitLab. De serving is zo dom mogelijk gehouden: een nginx die precies één bestand uitserveert.


FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html

Daaromheen Dokploy op mijn werkplaats: app aangemaakt, repo gekoppeld, build-type op Dockerfile. Push naar main en hij deployt vanzelf. Atze hoeft straks alleen index.html aan te passen en te pushen; de rest gebeurt zonder mij. Dat is het hele punt. Ik wil geen vaste hand op de knop zijn.

Het domein-gedoe (er is altijd domein-gedoe)

Ik had het keurig opgezet onder atze.peterreckers.nl. Toen kwam de correctie: het moest atzedezwart.nl zijn, een vers geregistreerd domein op een ander account, dat hij zelf al had ingesteld. Prima. Domeinen in Dokploy omgezet naar de apex en www.

En toen wachten. Het .nl-domein was diezelfde dag geregistreerd, dus de zone was nog niet gepubliceerd. Geen DNS, geen Let's Encrypt-certificaat. Niks te forceren; SIDN moet eerst zijn werk doen.

In plaats van elke vijf minuten te refreshen heb ik een achtergrondtaak het laten bewaken: wachten op DNS-propagatie, Traefik herstarten, certificaat checken. Toen de zone live ging, sloeg dat aan en gaf de melding: apex en www allebei 200, geldig certificaat, ook vanaf de server zelf getest.

Laatste verrassing kwam van mijn eigen Mac. Die had het "dit domein bestaat niet" nog in de cache van toen het écht niet bestond, en bleef koppig nee zeggen. De site was allang live; mijn laptop liep achter. Eén DNS-cache flushen en ook hier groen.


sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

Wat ik hieruit meeneem

De les zit niet in de techniek. Een statische site achter nginx is geen kunst. De les is de verhouding.

Een stagiair kan met Claude in een paar avonden een verzorgde portfolio-site ontwerpen en bouwen. Waar hij vastloopt is niet het bouwen, maar de meters eromheen: een navigatie-bug die hij niet kan plaatsen, een repo, een container, DNS, certificaten, een domein op het juiste account. Precies het stuk tussen "het werkt op mijn laptop" en "het staat live."

Dáár zit mijn rol. Niet het werk overnemen, maar de brug leggen van frontier-tools naar iets wat gewoon draait en blijft draaien. Snel, en zonder dat hij voor elke wijziging bij mij hoeft aan te kloppen. Vijf minuten werk, en een stagiair die nu zelf kan pushen.