De situatie
Developers en collega's bouwen handige tools: een prototype dat werkt op hun laptop. De stap naar een omgeving waar anderen erop vertrouwen, is een ander vak. Twee voorbeelden waar ik die stap zette.
1. Een matching-tool voor datamigraties
Een tool die exports uit verschillende bronsystemen automatisch koppelt aan referentielijsten, met per regel een confidence-score, een status (matched, review, not_found) en de regel die de match veroorzaakte. Een developer had hem van Python naar TypeScript omgezet. Mijn deel was hem uitrolbaar maken.
- Privacy in het ontwerp: geüploade bestanden blijven alleen in het geheugen en vervallen na 30 minuten. Geen schijf, geen database. De echte brondata staat nooit in de repository.
- Een Dockerfile en een pipeline: bouwen met Buildah op een gepinde digest van de builder-image, publiceren naar de registry, en een deploy-job die een merge request opent met de nieuwe image-digest.
- Een registry pull-secret van een deploy token met alleen
read_registry.
Een overbrugging die zichzelf opruimt
De pipeline zat op een branch die op een review van iemand anders wachtte. Om de gebruikers niet te laten wachten, draaide acceptatie tijdelijk op een met de hand gebouwde image, gepind op digest. De deploy-job vervangt die regel automatisch zodra de pipeline de eerste echte image publiceert. Er hoeft niets teruggedraaid te worden; je controleert alleen dat de deploy echt gedraaid heeft.
Eerlijk over wat ontbreekt
De testfixtures bleken nooit in Git te hebben gestaan: .gitignore sloot ze uit vanaf de eerste commit, en de oorspronkelijke repository bestond niet meer. De testjob staat daarom tijdelijk op allow_failure, met de reden in de commit en als open punt in de overdracht. Een rode test die je negeert is erger dan een gele test met uitleg.
2. Een registratie-app voor support
Een React/Node-applicatie voor gespreksregistratie en rapportage, met PostgreSQL en aparte objectopslag. Wat ik eraan toevoegde om hem productieklaar te maken:
- Lokaal zonder backend: de frontend kan volledig in de browser draaien, met localStorage. Een nieuwe ontwikkelaar heeft dan geen database, geen secrets en geen toegang tot acceptatie nodig.
- Een productieachtige integratietest met Docker Compose, met poorten alleen op
127.0.0.1en herkenbare lokale testwaarden als default. - Healthchecks voor
liveenready, zodat Kubernetes het verschil weet tussen "draait" en "kan verkeer aan". - Veilige migraties: genummerde SQL-migraties, elk in één transactie, met een PostgreSQL advisory lock zodat meerdere pods niet tegelijk migreren. De migrator voert nooit
DROP TABLEofTRUNCATEuit, en oude tabellen blijven bewaard voor controle en rollback. - Documentversleuteling met sleutel-ID's: meerdere sleutels met een actieve ID, zodat roteren kan zonder oude documenten onleesbaar te maken.
- Secrets als Kubernetes Secret, met hetzelfde patroon als de andere interne applicaties.
Wat ik meeneem
Productieklaar betekent niet "het draait in een container". Het betekent: veilig migreren, eerlijke healthchecks, geen geheimen in Git, een ontwikkelaar die zonder productietoegang kan werken, en een pipeline die de weg naar productie is.