Waarom je niet rechtstreeks op productie ontwikkelt
Het klinkt logisch: je wilt een wijziging doorvoeren, dus je past de code aan op de live server. De klant ziet het resultaat meteen, je hoeft niets te deployen en het is snel geregeld. Wat kan er misgaan?
Alles. Alles kan er misgaan.
Een typfout in een query en je database is corrupt. Een vergeten puntkomma en je applicatie geeft een witte pagina. Een nieuwe feature die half werkt en je klanten krijgen foutmeldingen. En het ergste: je hebt geen manier om terug te gaan naar de vorige situatie, want die bestaat niet meer.
De OTAP-straat voorkomt dat. Het is een gestructureerde manier om software te ontwikkelen, testen en op te leveren — zodat je gebruikers alleen gevalideerde, werkende software te zien krijgen.
De vier omgevingen
O — Ontwikkeling (Development)
Dit is waar de code wordt geschreven. De lokale machine van de developer, met een eigen database, eigen configuratie en eigen testdata. Hier mag alles kapotgaan — dat is het hele punt. Je experimenteert, bouwt, breekt en fixt. Niemand heeft er last van behalve de developer zelf.
Kenmerken van de ontwikkelomgeving:
- Draait lokaal op de machine van de developer
- Eigen database met testdata (nooit productiedata)
- Debug-modus aan, uitgebreide foutmeldingen
- Externe diensten worden gemockt of draaien in sandbox-modus
- Snelle feedbackloop: wijziging opslaan, browser verversen, resultaat zien
T — Test (Testing / Staging)
Zodra een feature af is en lokaal werkt, gaat het naar de testomgeving. Dit is een server die productie zo veel mogelijk nabootst, maar met testdata. Hier draaien de geautomatiseerde tests: unit tests, feature tests, integration tests. En hier test de developer of alles samenhangt.
Kenmerken van de testomgeving:
- Draait op een server (niet lokaal)
- Configuratie die productie nabootst (dezelfde PHP-versie, dezelfde database-engine, vergelijkbare server-specs)
- Testdata die representatief is voor de echte situatie
- Automatische deployments via CI/CD pipeline
- Niet toegankelijk voor eindgebruikers
A — Acceptatie (Acceptance / UAT)
Dit is de omgeving waar de opdrachtgever of eindgebruiker de nieuwe functionaliteit test en goedkeurt. De acceptatieomgeving draait de meest recente goedgekeurde code en biedt de klant de mogelijkheid om te valideren: doet het wat ik heb gevraagd? Werkt het zoals verwacht? Klopt de flow?
Kenmerken van de acceptatieomgeving:
- Toegankelijk voor de opdrachtgever en stakeholders
- Representatieve data (anoniem gemaakte productiedata of realistische testdata)
- Geen debug-modus, geen technische foutmeldingen
- De plek waar de klant "akkoord" geeft voordat het naar productie gaat
- Soms gecombineerd met de testomgeving bij kleinere projecten
Waarom is die aparte acceptatieomgeving zo belangrijk? Omdat de persoon die hier test niet de developer is, maar de opdrachtgever of eindgebruiker — iemand die het werkproces kent. Die test niet met technische testcases, maar met scenario's uit de dagelijkse praktijk. "Ik maak een offerte aan voor klant X, wijzig de hoeveelheid, en stuur hem door naar mijn collega." Dat soort flows. Geautomatiseerde tests vangen technische fouten op, maar een flow die technisch werkt en toch niet klopt met het bedrijfsproces — dat zie je alleen hier.
In de praktijk draait een acceptatieomgeving op een apart subdomein, zoals acceptatie.jouwapp.nl, met een eigen database gevuld met geanonimiseerde of representatieve data. De toegang is beperkt via VPN of IP-whitelist zodat alleen geautoriseerde mensen erbij kunnen. Bij Coding Agency combineer ik staging en acceptatie vaak voor kleinere projecten, maar bij meerdere stakeholders of compliance-eisen splits ik ze. Zodra de opdrachtgever akkoord geeft in de acceptatieomgeving, gaat de code pas naar productie.
P — Productie (Production)
De live omgeving. Hier werken de echte gebruikers met echte data. Alleen code die door alle voorgaande stappen heen is gekomen, bereikt productie. Geen experimentele features, geen half werkende functionaliteit, geen ongeteste wijzigingen.
Kenmerken van de productieomgeving:
- De live applicatie die eindgebruikers bedienen
- Echte data, echte gebruikers, echte gevolgen
- Uitgebreide monitoring en logging
- Automatische backups
- Beveiligd en verhard (geen debug-modus, geen overbodige poorten, geen testaccounts)
- Zero-downtime deployments
De flow: van links naar rechts
Code stroomt altijd in één richting: van O naar T naar A naar P. Nooit andersom. Nooit een stap overslaan. Dit is de discipline die ervoor zorgt dat productie stabiel blijft.
- Developer schrijft code en test lokaal (O)
- Code wordt gepusht en automatische tests draaien (T)
- Bij succes wordt de code op de acceptatieomgeving gezet voor review (A)
- Opdrachtgever test en geeft akkoord
- Code wordt naar productie gedeployed (P)
Bij urgente hotfixes — een kritieke bug in productie — mag je de route versnellen, maar nooit stappen overslaan. Zelfs een hotfix gaat door tests en wordt gevalideerd voordat het live gaat.
De OTAP-straat is geen bureaucratie. Het is de reden dat je klanten nooit een half werkende feature te zien krijgen.
Hoe ik het inricht
Bij Coding Agency werk ik standaard met minimaal drie omgevingen: lokale development, staging/acceptatie (gecombineerd) en productie. Bij grotere projecten of projecten met meerdere stakeholders splits ik staging en acceptatie.
Praktisch voorbeeld
Voor een typisch Laravel-project ziet dat er zo uit:
- Lokaal — Laravel Valet of Herd op mijn machine. Eigen database, eigen .env-configuratie.
- Staging — Een aparte omgeving op dezelfde infrastructuur als productie. Bereikbaar via staging.jouwapp.nl. Automatische deployment bij elke merge naar de develop branch.
- Productie — De live applicatie op jouwapp.nl. Deployment bij merge naar de main branch, na goedkeuring op staging.
Bij serverless projecten via Laravel Vapor is dit nog eenvoudiger: Vapor ondersteunt meerdere omgevingen out-of-the-box, elk met eigen configuratie, database en domein.
Veelgemaakte fouten
- Geen staging-omgeving — Rechtstreeks van development naar productie. "We testen het wel live." Tot het fout gaat en je klanten het als eerste merken.
- Staging die niet op productie lijkt — Staging draait op een andere PHP-versie, een andere database of met andere configuratie. Alles werkt op staging, maar breekt op productie. Het hele punt van staging is dat het productie nabootst.
- Productiedata op staging — Een kopie van de productiedatabase op staging, compleet met echte klantgegevens. Dat is een AVG-overtreding en een beveiligingsrisico. Gebruik anoniem gemaakte data of synthetische testdata.
- Stappen overslaan bij haast — "Het is maar een kleine wijziging, ik zet het even direct op productie." Beroemde laatste woorden. Kleine wijzigingen veroorzaken de meeste productie-incidenten.
- Handmatige configuratieverschillen — Environment-specifieke configuratie die handmatig op de server wordt ingesteld in plaats van in code. Na een herinstallatie weet niemand meer welke instellingen nodig zijn.
OTAP voor kleinere projecten
Niet elk project heeft vier volwaardige omgevingen nodig. Voor kleinere projecten is een pragmatische variant:
- Minimaal — Lokaal + Productie. Beter dan niets, maar je mist de veiligheidslaag van staging.
- Standaard — Lokaal + Staging + Productie. Mijn standaard voor de meeste projecten. Staging dient als test- én acceptatieomgeving.
- Volledig — Lokaal + Test + Acceptatie + Productie. Voor projecten met meerdere stakeholders, compliance-eisen of complexe release-processen.
Het minimale is altijd: ontwikkel nooit op productie. Er moet minimaal één omgeving tussen development en productie zitten.
De kosten
Een staging-omgeving kost geld: een extra server of een extra Vapor-environment. Reken op € 20 tot € 100 per maand, afhankelijk van de infrastructuur. Dat is een fractie van de kosten van een productie-incident dat je had kunnen voorkomen.
Bij Laravel Vapor zijn extra omgevingen bijzonder goedkoop: je betaalt alleen voor daadwerkelijk gebruik. Een staging-omgeving die alleen actief is tijdens development kost vaak minder dan € 10 per maand.
OTAP en CI/CD: hoe ze samenhangen
OTAP beschrijft welke omgevingen er zijn. CI/CD beschrijft hoe code automatisch door die omgevingen heen stroomt. Ze zijn complementair: OTAP zonder CI/CD betekent handmatig deployen naar elke omgeving. CI/CD zonder OTAP betekent dat je automatisch naar productie deployt zonder tussenliggende controle.
In de praktijk ziet een moderne OTAP-straat met CI/CD er als volgt uit:
- Developer pusht code naar een feature-branch → CI draait automatisch linters en tests
- Pull request wordt gemerged naar de develop-branch → CD deployt automatisch naar staging
- Opdrachtgever test op staging en geeft akkoord
- Merge naar main → CD deployt automatisch naar productie via zero-downtime deployment
De combinatie van OTAP-omgevingen met geautomatiseerde pipelines is de standaard in professionele softwareontwikkeling. Handmatige deployments via FTP of SSH zijn achterhaald — ze zijn foutgevoelig, niet reproduceerbaar en laten geen audit trail achter (bron: Atlassian: CI vs CD vs CD).
OTAP in de cloud
Cloud-platformen maken het opzetten van meerdere omgevingen eenvoudiger en goedkoper dan ooit. Bij Laravel Vapor (serverless op AWS) is een nieuwe omgeving letterlijk één commando: vapor env staging. Je betaalt alleen voor daadwerkelijk gebruik, waardoor een staging-omgeving die alleen tijdens development actief is vrijwel niets kost.
Vergelijkbare mogelijkheden bieden platformen als AWS Elastic Beanstalk, Google Cloud Run en Azure App Service (bron: The Twelve-Factor App: Dev/prod parity). Het principe is steeds hetzelfde: omgevingen moeten zo identiek mogelijk zijn om "works on staging, breaks on production" te voorkomen.
Wat als het tóch misgaat: productie-incidenten beperken
Zelfs met een goed ingerichte OTAP-straat gaat het soms mis. Een externe API verandert onverwachts, een edge case die niemand had voorzien, of een configuratieverschil tussen staging en productie. Het verschil zit in hoe snel je het merkt en hoe snel je terugdraait.
Bij een goed ingericht deployment-proces heb je altijd een rollback-mogelijkheid: de vorige versie staat klaar om terug te zetten. Met monitoring en alerting merk je fouten binnen minuten in plaats van uren. En met zero-downtime deployments heeft een rollback geen impact op actieve gebruikers.
De OTAP-straat elimineert niet alle risico's — dat kan geen enkele methodiek. Maar het reduceert de kans op incidenten drastisch en maakt het herstellen van de incidenten die wél optreden voorspelbaar en snel.
OTAP en security: waarom scheiding ook een beveiligingsmaatregel is
Gescheiden omgevingen zijn niet alleen handig voor kwaliteitsbewaking — ze zijn ook een beveiligingsmaatregel. Op staging werk je met testdata of geanonimiseerde data, niet met echte klantgegevens. Dat beperkt de impact als een developer per ongeluk een kwetsbaarheid introduceert. Bovendien hoeven developers geen toegang te hebben tot de productiedatabase, wat het risico op onbedoelde of ongeautoriseerde wijzigingen verkleint.
Dit is ook relevant voor NIS2-compliance: de richtlijn verlangt dat organisaties hun softwareontwikkelproces beveiligen, inclusief gescheiden omgevingen en gecontroleerde deployment-processen. Een werkende OTAP-straat is daarmee niet alleen een best practice, maar ook een compliancemaatregel. Hetzelfde geldt voor ISO 27001, waar change management en gescheiden omgevingen expliciet worden benoemd.
Tot slot
De OTAP-straat is geen theoretisch model uit een handboek. Het is een praktische manier om ervoor te zorgen dat je software betrouwbaar is, dat wijzigingen gecontroleerd worden doorgevoerd en dat je gebruikers nooit last hebben van ongeteste code.
Bij elk project dat ik oplever, is een werkende OTAP-straat (of een pragmatische variant daarvan) onderdeel van de oplevering. Omdat software bouwen niet alleen gaat over code schrijven — het gaat over die code veilig bij je gebruikers krijgen. Wil je weten wat een goed testproces inhoudt naast de OTAP-straat? Lees dan het artikel over teststrategieën voor maatwerk en SaaS.