Een bekend fenomeen onder software ontwikkelaars is de wel bekende “maar het werkt wel op mijn laptop” reactie, als de door hun geschreven software op een andere plek moet werken, maar dit niet doet. Als je geluk hebt, is dit tijdens het delen van software met een andere ontwikkelaar, en als je pech hebt, live in productie.

Ik heb verschillende oorzaken hiervan voorbij zien komen. Configuratie fouten, onjuiste data (schema) migraties en het verkeerd combineren van werk van verschillende ontwikkelaars komen allen vaak voor. Een oorzaak die ook regelmatig voorkomt, maar vaker onder het vloerkleed wordt geschoven, is een mismatch op de executieomgeving van de software. Een mismatch in de fundatie van de software sky-scraper.

Een mismatch op de executieomgeving? Ja! Daarmee bedoel ik alle primaire tooling, gebruikte software libraries en de toevallig geinstalleerde software op het besturingssysteem. Waarom is dit een probleem? Mijns inziens moet je software bouwen zien als het koken van een maaltijd. De analogie klopt niet helemaal, want wij mensen vinden het niet erg als de ene maaltijd niet 100% hetzelfde is als de andere. Ik zou het zelfs saai vinden als dit zo zijn. Maar waar het saai zijn een negatieve eigenschap is van een maaltijd, is het juist een positieve eigenschap voor de fundatie van software projecten. Met een goede fundatie spendeer je minder tijd aan het onboarden van nieuwe ontwikkelaars, het debuggen van “het werkt wel op mijn laptop, maar niet op die van jou”, en last but not least, het vermogen om snel software uit te kunnen rollen.

Ook voor mij als freelancer die de ambitie heeft om mijn klanten te helpen een prototype te bouwen, en daarna te assisteren bij het bouwen van een team, heeft dit duidelijk voordelen voor mij en mijn klanten.

Goed, hopelijk heb ik je overtuigd dat een gelijke executieomgeving een doel is wat je na zou moeten streven. Hoe krijg je dit dan voor elkaar in de praktijk? Ik noemde eerder drie bronnen van mismatches. Wat zijn deze, en hoe kunnen wij deze temmen?

Met primaire tooling bedoel ik de gebruikte compilers en interpreters die het dagelijks gereedschap van ontwikkelaars vormen. Daar zijn enkele oplossingen voor, die vaak gericht zijn op slechts één ecosysteem. De positieve uitzondering hiervan is asdf, maar het gebruik hiervan is vrij pijnlijk in mijn ervaring.

Voor software libraries zijn er tegenwoordig goede oplossingen. Dit doormiddel van een package manager voor de gebruikte programmeertaal, die een lock-file maakt met alle (transitieve) afhankelijkheden van de gebruikte libraries. Dit werkt over het algemeen goed, maar loopt soms spaak, omdat een bibliotheek bijvoorbeeld een afhankelijkheid heeft op een database driver die op het besturingssysteem geinstalleerd moet worden. Deze driver kan dan bijvoorbeeld een nét andere versie zijn op het productiesysteem dan jouw laptop. Ik spreek uit ervaring, dat dit vervelende bugs zijn om op te lossen.

Slechts een enkeling maakt zich uberhaupt zorgen om de software die geinstalleerd is op het besturingssysteem. Het gebrek in interesse hierin verbaasd mij altijd, aangezien dit dus ook een barst in de fundatie van je sky-scraper kan zijn.

Sinds jaar en dag ben ik gecharmeerd door Nix, een ecosysteem van tooling dat het bouwen (en dus ook het schrijven) van software betrouwbaarder belooft te maken, door heel erg precies te zijn over wat het nu precies beschikbaar maakt in de executieomgeving. Alleen de noodzakelijke dingen (die je zelf aangeeft) zijn beschikbaar. Hierdoor is het triviaal om te ontdekken dat je nog iets hebt gemist, wat je bij alternatieve systemen over het hoofd kunt zien. Mijn mede IT’ers denken nu wellicht direct aan Docker, wat vergelijkbare beloften doet. In deze braindump ga ik niet verder in op wat Nix precies is, en wat de verschillen tussen Nix en Docker zijn. Ik gebruik Docker ook regelmatig, maar om het kort te houden, is Docker lastiger in gebruik tijdens het ontwikkelen van software, omdat het niet hetzelfde bestandssysteem deelt als jouw computer.

Nix heeft een scherpe leercurve, en is meer gericht op het packagen van software dan een intuitieve ontwikkel expierience. Het devenv.sh project bouwt verder op Nix.

Mijn favoriete features van devenv zijn:

  • Consistentie in welke primaire tooling er beschikbaar is, niet enkel en alleen voor slechts een, maar voor alle programmeertalen.
  • Consistentie in welke besturingssysteem packages er beschijkbaar zijn.
  • Het eenvoudig kunnen opstarten van supporting services d.mv. devenv up, welke een vergelijkbare ervaring is als met docker compose.
  • Het eenvoudig kunnen configureren van pre-commit hooks, welke forceren dat de code (of documentatie) die je wilt committen altijd aan eisen voldoet, zoals consistente code formatting en werkende unit tests.

Geinteresseerd in devenv? Leer meer op https://devenv.sh/, of wacht op een volgende braindump waar ik hier in detail op in ga.