Die Zukunft des Build Managements

Nicht nur sogenannte Hochsprachen, die den Quelltext in Maschinencode überführen müssen, damit dieser ausführbar ist, benötigen sogenannte Build Werkzeuge. Auch für moderne Scriptsprachen wie Python, Ruby oder PHP sind diese Werkzeuge mittlerweile verfügbar, da deren Verantwortungsbereich stetig wächst. Blickt man in die Anfänge dieser Werkzeugkategorie, stößt man unweigerlich auf make, der erste offizielle Vertreter von dem, was man heute als Build Werkzeug bezeichnet. Die Hauptaufgabe von make war das Erstellen von Maschinencode und das Paketieren der Dateien zu einer Bibliothek oder ausführbaren Datei. Man kann also sagen, das Buildwerkzeuge unter die Kategorie der Automatisierungswerkzeuge fallen. Da liegt es nahe, viele andere immer wiederkehrende Aufgaben, die im Entwickleralltag anfallen, ebenfalls zu übernehmen. So war eine der wichtigsten Innovationen, die für den Erfolg von Maven verantwortlich war, die Verwaltung von Abhängigkeiten zu anderen Programmbibliotheken.

Eine andere Klasse an Automatisierungswerkzeugen, die fast verschwunden ist, sind die sogenannten Installer. Produkte wie Inno SetUp oder Wise Installer wurden verwendet, um den Installationsprozess auf Desktopanwendungen zu automatisieren. Diese Installationsroutinen sind eine spezielle Form des Deployments. Der Deploymentprozess wiederum hängt von verschiedenen Faktoren ab. Zuallererst ist natürlich das verwendete Betriebssystem ein wichtiges Kriterium. Aber auch die Art der Anwendung hat einen erheblichen Einfluss. Handelt es sich etwa um eine Webanwendung, die eine definierte Laufzeitumgebung (Server) benötigt? Wir können hier bereits sehen, dass viele der gestellten Fragen mittlerweile im Themenbereich DevOps angesiedelt sind.

Als Entwickler genügt es nun nicht mehr, nur zu wissen, wie man Programmcode schreibt und Funktionen implementiert. Wer eine Webanwendung bauen möchte, muss zuerst den entsprechenden Server zum Laufen bekommen, auf dem die Applikation ausgeführt wird. Glücklicherweise gibt es mittlerweile viele Lösungen, die das Bereitstellen einer lauffähigen Runtime erheblich vereinfachen. Aber gerade für Anfänger ist es nicht immer so leicht, das ganze Thema zu überblicken. Ich erinnere mich noch an Fragen in einschlägigen Foren, dass man jetzt Java Enterprise heruntergeladen hat, aber nur der Applikationsserver enthalten ist.

Wo Anfang der 2000er noch Automatisierungslösungen fehlten, ist heute eher die Herausforderung, das richtige Werkzeug zu wählen. Auch hier gibt es eine Analogie aus dem Java Universum. Als das Build-Werkzeug Gradle auf dem Markt erschien, stiegen viele Projekte von Maven auf Gradle um. Das Argument war, eine höhere Flexibilität zu erhalten. Oft benötigte man die Möglichkeit, orchestrierte Builds zu definieren. Also die Reihenfolge, in der Teilprojekte erstellt werden. Anstatt sich einzugestehen, dass es sich bei dieser Anforderung um einen Architekturmangel handelt und anstatt diesen zu beheben, wurden komplizierte und kaum überschaubare Build Logiken in Gradle gebaut. Das führte wiederum dazu, dass Anpassungen nur schwer umzusetzen waren und viele Projekte zurück nach Maven migriert wurden.

Aus den DevOps Automatisierungen haben sich mittlerweile sogenannte Pipelines etabliert. Pipelines können auch als Prozess verstanden werden und diese Prozesse lassen sich wiederum standardisieren. Das beste Beispiel für einen standardisierten Prozess, ist der in Maven definierte Build Lifecycle, der auch als Default-Lifecycle bezeichnet wird. In diesem Prozess werden 23 sequenzielle Schritte definiert, die im Groben zusammengefasst folgende Aufgaben abarbeiten:

  • Auflösen und Bereitstellen von Abhängigkeiten
  • Kompilieren der Quelltexte
  • Kompilieren und Ausführen von Komponententests
  • Paketieren der Dateien zu einer Bibliothek oder Anwendung
  • Lokales Bereitstellen des Artefaktes zur Verwendung in anderen lokalen Entwicklungsprojekten
  • Ausführen von Integrationstests
  • Deployen der Artefakte auf einem Remote Repository Server.

Dieser Prozess hat sich über Jahre in unzähligen Javaprojekten bestens bewährt. Führt man diesen Prozess allerdings auf einem CI Server wie Jenkins als Pipeline aus, bekommt man wenig zu sehen. Die einzelnen Schritte des Build Lifecycles bauen aufeinander auf und können nicht einzeln angesteuert werden. Es ist nur möglich, den Lifecycle vorzeitig zu verlassen. Man kann also nach dem Paketieren die nachfolgenden Schritte des lokalen Deployments und das Ausführen der Integrationstests auslassen.

Eine Schwäche des hier beschriebenen Build Prozesses kommt bei der Erstellung von Webapplikationen zutage. Web Frontends enthalten meist CSS und JavaScript Code, der ebenfalls automatisiert optimiert wird. Um in SCSS definierte Variablen in korrektes CSS zu überführen, muss ein SASS Präprozessor verwendet werden. Zudem ist es sehr nützlich, CSS Dateien und JavaScript Dateien möglichst stark zu komprimieren. Dieser Vorgang der Obfuskation optimiert die Ladezeiten von Webanwendungen. Aber auch für CSS und JavaScript gibt es bereits unzählige Bibliotheken, die mit dem Werkzeug NPM verwaltet werden können. NPM wiederum stellt sogenannte Entwicklungsbibliotheken wie Grunt bereit, mit denen wiederum CSS-Prozessierung und -Optimierung möglich sind.

Wir sehen, wie komplex der Buildprozess von modernen Anwendungen werden kann. Das Kompilieren ist nur ein kleiner Teil davon. Ein wichtiges Feature moderner Build Werkzeuge ist das Optimieren des Build Vorgangs. Eine mittlerweile etablierte Lösung dafür ist das Erstellen von inkrementellen Builds. Dies ist eine Variante des Cachings, bei der nur geänderte Dateien kompiliert beziehungsweise prozessiert werden.

Jenkins Pipelines

Was ist aber bei einem Release zu tun? Ein Prozess, der wiederum nur dann benötigt wird, wenn eine Implementierungsphase beendet ist, um das Artefakt für die Verteilung bereitzustellen. Nun könnte man alle Schritte, die ein Release enthalten, ebenfalls in den Build einbauen, was wiederum zu längeren Buildzeiten führt. Längere lokale Buildzeiten stören wiederum den Arbeitsfluss des Entwicklers, weswegen es sinnvoller ist, hierfür einen eigenen Prozess zu definieren.

Bei einem Release sollte eine wichtige Bedingung sein, dass alle verwendeten Bibliotheken ebenfalls als finale Releaseversion vorliegen. Ist dies nicht der Fall, kann nicht sichergestellt werden, dass erneut erstellte Releases dieser Version identisch sind. Aber auch alle Testfälle müssen korrekt durchlaufen werden und ein Fehlschlagen bricht den Vorgang ab. Zudem sollte ein entsprechendes Tag im Source-Control-Repository auf die Revision gesetzt werden. Die fertigen Artefakte sind zu signieren und auch eine API Dokumentation ist zu erstellen. Natürlich sind die hier beschriebenen Regeln nur eine kleine Auswahl und einige der beschriebenen Aufgaben können sogar parallelisiert werden. Nutzt man zudem noch ein raffiniertes Caching, kann das Erstellen eines Releases auch für umfangreiche Monolithen in kurzer Zeit vonstattengehen.

Für Maven wurde beispielsweise kein kompletter Releaseprozess, ähnlich dem Buildprozess, definiert. Hier wurde durch die Community ein spezielles Plug-in entwickelt, mit dem einfache Aufgaben, die während eines Releases anstehen, semiautomatisiert werden können.

Wenn wir das Thema Dokumentation und Reporting ein wenig genauer betrachten, finden wir auch hier genügend Möglichkeiten, einen vollständigen Prozess zu beschreiben. So wäre das Erstellen der API Dokumentation nur ein untergeordneter Punkt. Wesentlich spannender an einem standardisierten Reporting sind die verschiedenen Codeinspektionen, die teilweise auch parallel durchlaufen werden können.

Natürlich darf auch das Deployment nicht fehlen. Aufgrund der Vielfalt, der möglichen Zielumgebungen ist an dieser Stelle eine andere Strategie angebracht. Ein denkbarer Weg wäre eine breite Unterstützung von Konfigurationswerkzeugen wie Ansible, Chef und Puppet. Aber auch Virtualisierungstechnologien wie Docker und LXC Container gehören in Zeiten der Cloud zum Standard. Hauptaufgabe des Deployments wäre dann vor allem die Provisionierung der Zielumgebung und das Einspielen der Artefakte aus einem Repository Server. Mit einer Fülle verschiedener Deployment Templates würde dies eine erhebliche Vereinfachung darstellen.

Wenn wir die hier getroffenen Annahmen konsequent weiterdenken, kommen wir zu dem Schluss, dass es unterschiedliche Projekttypen geben kann. Das wären klassische Entwicklungsprojekte, aus denen dann Artefakte für Bibliotheken und Anwendungen entstehen, Testprojekte, die wiederum die erstellten Artefakte als Abhängigkeit enthalten, und natürlich Deploymentprojekte zur Bereitstellung der Infrastruktur. Der Bereich des automatisierten Deployments findet sich auch in der Idee Infrastructure as a Code und GitOps wieder,die man an dieser Stelle aufgreifen und weiterentwickeln kann.

Wir sehen, dass bei weitem noch nicht alle Innovationen für sogenannte Build Werkzeuge ausgeschöpft sind. Viele der hier besprochenen Ideen sind bereits existierende Konzepte und erfordern lediglich eine Standardisierung. Durch die formalen Beschreibungen eines Prozesses und die flexible Konfiguration einzelner Komponenten in den Prozessschritten wird eine individuelle Anpassung ermöglicht.


Clean Desk – mehr als nur Sicherheit

Als Kind antwortete ich gern meiner Mutter, dass nur ein Genie das Chaos beherrscht, wenn sie mich anhielt, mein Zimmer aufzuräumen. Eine sehr willkommene Ausrede, mich vor meinen Pflichten zu drücken. Als ich nach dem Schulabschluss eine Lehre im Handwerk begonnen habe, war das Erste, worauf mein Lehrmeister achtete: Ordnung halten. Das Werkzeug hatte nach Benutzung zurück in die Werkzeugtasche gelegt zu werden, angefangene Kartons mit gleichen Arbeitsmaterialien wurden wieder aufgefüllt und natürlich galt es auch, mehrmals am Tag den Dreck aufzukehren. Ich kann gleich vorwegnehmen, dass ich diese Dinge nie als Schikane empfunden habe, auch wenn sie uns lästig erschienen sind. Denn rasch haben wir den Nutzen der Devise „Sauberkeit halten“ erfahren.

Werkzeuge, die immer zurück an ihren Platz gebracht werden, verschaffen uns zügig einen Überblick, ob etwas fehlt. Also kann man sich dann auf die Suche machen und die Wahrscheinlichkeit, dass Dinge gestohlen werden, reduziert sich drastisch. Auch bei den Arbeitsmaterialien behält man einen guten Überblick über Dinge, die verbraucht wurden und neu beschafft werden müssen. Fünf leere Kartons mit nur ein oder zwei Teilen darin verbrauchen nicht bloß Platz, sondern führen auch zu falschen Einschätzungen der verfügbaren Ressourcen. Zu guter Letzt gilt natürlich auch, dass man sich im Dreck weniger wohlfühlt und mit Sauberkeit dem Auftraggeber demonstriert, dass man fokussiert und planvoll vorgeht.

Durch diese Prägung in jungen Jahren, habe ich, als vor einigen Jahren das Thema Clean Desk als Sicherheitskonzept in Unternehmen eingeführt wurde, nicht gleich verstanden, was man von mir wollte. Schließlich ist mir das Prinzip Clean Desk bereits in Fleisch und Blut übergegangen, lange bevor ich mein Studium der Informatik abgeschlossen hatte. Aber der Reihe nach. Schauen wir uns erst einmal an, was Clean Desk eigentlich ist und wie man es umsetzt.

Wer sich tiefgehend mit dem Thema Security beschäftigt, lernt als Erstes, dass die meisten erfolgreichen Angriffe nicht über komplizierte technische Manöver durchgeführt werden. Sie verlaufen viel profaner und kommen üblicherweise nicht von außen, sondern von innen. Treu nach dem Motto: Gelegenheit macht Diebe. Kombiniert man diese Tatsache noch mit den Erkenntnissen des Social Engineerings, das vor allem durch den Hacker Kevin Mitnick geprägt wurde, ergibt sich ein neues Bild. Es müssen nicht immer gleich die eigenen Mitarbeiter unter Generalverdacht gestellt werden. In einem Gebäude gibt es externe Putzkräfte, Sicherheitspersonal oder Handwerker, die meist problemlos Zugang zu sensiblen Räumlichkeiten bekommen. Daher gilt stets die Devise: Vertrauen ist gut, Kontrolle ist besser, weswegen man eine Clean Desk Policy einführt.

Die erste Regel lautet: Wer über einen längeren Zeitraum den Arbeitsplatz verlässt, schaltet seine Geräte aus. Das gilt besonders für den Feierabend. Ansonsten ist zumindest der Desktop zu sperren. Das Konzept dahinter ist recht einfach. Von ausgeschalteten Geräten können keine Sicherheitslücken ausgenutzt werden, um sich von außen in das Firmennetzwerk zu hacken. Zudem verringert es den Stromverbrauch und verhindert Brände durch Kurzschlüsse. Damit die Geräte nicht physisch entwendet werden können, sind diese mit speziellen Schlössern am Schreibtisch fixiert. Ich habe es schon selbst erlebt, dass während der Mittagspause Geräte gestohlen wurden.

Da ich selbst sehr viel in Hotels übernachtet habe, ist die Festplatte meines Computers prinzipiell verschlüsselt. Das gilt auch für alle externen Datenträger wie USB Sticks oder externe SSDs. Wird das Gerät gestohlen, kann zumindest niemand auf die darauf befindlichen Daten zugreifen.

Es ist natürlich selbstverständlich, dass eine sichere Verschlüsselung nur mit einem starken Passwort möglich ist. Viele Unternehmen, haben spezielle Regeln, die die Passwörter der Mitarbeiter erfüllen müssen. Zudem ist es üblich, dass alle 30 bis 90 Tage ein neues Passwort vergeben werden muss, das von den letzten drei verwendeten Passwörtern abweichen muss.

Oft wird auch darauf hingewiesen, dass die Passwörter nicht auf einem Post-it stehen, der auf dem Monitor klebt. Das habe ich selbst so nie erlebt. Viel typischer ist, dass Passwörter unter der Tastatur oder dem Mauspad notiert werden.

Ein anderer Aspekt sind Aufzeichnungen, die auf Schreibtischen, Wandkalendern und Whiteboards hinterlassen werden. Auch wenn die Information noch so unbedeutend scheint, kann sie durchaus sehr wertvoll sein. Da es recht schwer ist, zu entscheiden, was wirklich schützenswert ist und was nicht, gilt die allgemeine Regel: Alle Aufzeichnungen sind zum Feierabend für Außenstehende unzugänglich zu verstauen. Das klappt natürlich nur dann, wenn auch verschließbarer Stauraum vorhanden ist. In sensiblen Bereichen wie Banken und Versicherungen geht man sogar so weit, dass auf Wandkalendern keine Urlaube der Kollegen eingetragen werden dürfen.

Natürlich ist bei diesen Überlegungen auch der eigene Papierkorb einzubeziehen. Hier ist sicherzustellen, dass die vertraulichen Dokumente in speziell gesicherten Containern entsorgt werden. Denn sonst führt es ja den ganzen Aufwand der Geheimhaltung wieder ad absurdum, wenn man diese nach Feierabend einfach aus dem Papierkorb ziehen kann.

Aber auch der virtuelle Schreibtisch ist Teil der Clean Desk Policy. Ganz besonders in Zeiten der virtuellen Videokonferenzen und Remote Arbeit können Fremde einen Blick auf den eigenen Schreibtisch erhaschen. Das erinnert mich auch an die Zeit der Vorlesungen, als ein Dozent mehrere Verknüpfungen des Papierkorbes auf seinem Desktop hatte. Wir haben immer gescherzt, dass er recycelt. Eigene Papierkörbe für Word, Excel etc. Dateien.

Die Clean Desk Policy hat allerdings auch andere Auswirkungen. Es ist durchaus mehr als nur ein Sicherheitskonzept. Denn Mitarbeiter, die diese Policy konsequent umsetzen, bringen dadurch auch mehr Ordnung in die eigenen Gedanken und können so Thema für Thema konzentriert abarbeiten, was zu einer besseren Performance führt. Meist erfolgt die persönliche Tagesplanung so, das zum Feierabend auch die begonnenen Aufgaben abgeschlossen werden können. Auch hier finden sich Analogien zum Handwerk. Denn der Handwerker versucht ebenfalls, den Auftrag möglichst bis zum Feierabend zu erledigen, um am nächsten Tag nicht noch einmal für kurze Zeit anrücken zu müssen. Denn auch hier wird einiges an Zeit für Vorbereitungen aufgewendet.

Die Umsetzung einer Clean Desk Policy erfolgt nach den drei P (Plan, Protect & Pick). Zu Beginn des Tages wird sich überlegt, welche Aufgaben erledigt werden sollen (Plan), und die entsprechenden Dokumente und benötigten Materialien werden ausgewählt, um darauf Zugriff zu haben. Am Ende des Tages werden die Dinge wieder sicher verstaut. Während der Arbeitszeit ist ebenfalls sicherzustellen, dass zum Beispiel in den Pausen keine unbefugten Personen Zugriff auf die Informationen haben. Diese tägliche, einfach umzusetzende Routine von Vorbereitung und Nachbereitung wird rasch zur Gewohnheit und die dafür aufzuwendened Zeit lässt sich auf wenige Minuten reduzieren, so dass kaum Arbeitszeit vergeudet wird.

Mit einer Clean Desk Policy verschwinden die erdrückenden Papierberge vom Schreibtisch, und durch die Überlegung, welche Aufgaben am Tag erledigt werden sollen, ist man besser auf diese fokussiert, was die Produktivität erheblich verbessert. Am Ende des Tages kann man nun mental auch einige Punkte von der eigenen Aufgabenliste streichen, was zu einer besseren Zufriedenheit führt.


Frühjahrsputz für Docker

Wer sich für diesen, eigentlich etwas spezialisierten Artikel interessiert, dem muss man nicht mehr erklären, was Docker ist und wofür das Virtualisierungswerkzeug eingesetzt wird. Daher richtet sich dieser Artikel vornehmlich an Systemadministratoren, DevOps und Cloud-Entwickler. Für alle, die bisher nicht ganz so fit mit der Technologie sind, empfehle ich unseren Docker Kurs: From Zero to Hero.

In einem Szenario, in dem wir regelmäßig neue Docker Images erstellen und verschiedene Container instanzieren, wird unsere Festplatte ordentlich gefordert. Images können je nach Komplexität durchaus problemlos einige hundert Megabyte bis Gigabyte erreichen. Damit das Erstellen neuer Images auch nicht gefühlt, wie ein Download einer drei Minuten langen MP3 mit einem 56k Modem dauert, nutzt Docker einen Build-Cache. Ist im Dockerfile wiederum ein Fehler, kann dieser Build-Cache recht lästig werden. Daher ist es eine gute Idee, den Build-Cache durchaus regelmäßig zu entleeren. Aber auch alte Containerinstanzen, die nicht mehr in Verwendung sind können zu komischen Fehlern führen. Wie hält man seine Dockerumgebung also stubenrein?

Sicher kommt man mit mit docker rm <container-nane> und docker rmi <image-id> schon recht weit. In Buildumgebungen wie Jenkins oder Serverclustern kann diese Strategie allerdings zu einer zeitintensiven und mühsamen Beschäftigung werden. Doch verschaffen wir uns zuerst einmal einen Überblick über die Gesamtsituation. Hier hilft uns der Befehl docker system df weiter.

root:/home# docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          15        9         5.07GB    2.626GB (51%)
Containers      9         7         11.05MB   5.683MB (51%)
Local Volumes   226       7         6.258GB   6.129GB (97%)
Build Cache     0         0         0B        0B

Bevor ich gleich in die Details eintauche, noch ein wichtiger Hinweis. Die vorgestellten Befehle sind sehr effizient und löschen unwiderruflich die entsprechenden Bereiche. Daher wendet diese Befehle erst auf einer Übungsumgebung an, bevor ihr damit Produktivsysteme außer Gefecht setzt. Zudem hat es sich für mich bewährt, auch die Befehle zur Instanzierung von Containern in deiner Textdatei unter Versionsverwaltung zu stellen.

Der naheliegendste Schritt bei einem Docker System Cleanup ist das Löschen der nichtbenutzten Container. Im Konkreten bedeute das, dass durch den Löschbefehl alle Instanzen der Docker Container, die nicht laufen (also nicht aktiv sind), unwiederbringlich gelöscht werden. Will man auf einem Jenkins Buildnode vor einem Deployment Tabula Rasa durchführen, kann man zuvor alle auf der Maschine laufenden Container mit einem Befehl beenden.

Abonnement / Subscription

[English] This content is only available to subscribers.

[Deutsch] Diese Inhalte sind nur für Abonnenten verfügbar.

Der Parameter -f unterdrückt die Nachfrage, ob man diese Aktion wirklich durchführen möchte. Also die ideale Option für automatisierte Skripte. Durch das Löschen der Container erhalten wir vergleichsweise wenig Festplattenplatz zurück. Die Hauptlast findet sich bei den heruntergeladenen Images. Diese lassen sich ebenfalls mit nur einem Befehl entfernen. Damit Images allerdings gelöscht werden können, muss vorher sichergestellt sein, dass diese nicht durch Container (auch inaktive) in Verwendung sind. Das Entfernen ungenutzter Container hat noch einen ganz anderen praktischen Vorteil. Denn beispielsweise durch Container blockierte Ports werden so wieder freigegeben. Schließlich lässt sich ein Port einer Hostumgebung nur exakt einmal an einen Container binden. Das kann stellenweise schnell zu Fehlermeldungen führen. Also erweitern wir unser Skript um den Eintrag, alle nicht durch Container benutzten Docker Images ebenfalls zu löschen.

Abonnement / Subscription

[English] This content is only available to subscribers.

[Deutsch] Diese Inhalte sind nur für Abonnenten verfügbar.

Eine weitere Konsequenz unserer Bemühungen umfasst die Docker Layers. Hier sollte man aus Performancegründen, besonders in CI Umgebungen Abstand nehmen. Docker Volumes hingegen sind hier weniger problematisch. Beim Entfernen der Volumes, werden nur die Referenzen in Docker entfernt. Die in die Container verlinkten Ordner und Dateien bleiben von der Löschung unberührt. Der Parameter -a löscht alle Docker Volumes.

Abonnement / Subscription

[English] This content is only available to subscribers.

[Deutsch] Diese Inhalte sind nur für Abonnenten verfügbar.

Ein weiterer Bereich, der von unseren Aufräumarbeiten betroffen ist, ist der Build-Cache. Besonders wenn man gerade ein wenig mit dem Erstellen neuer Dockerfiles experimentiert, kann es durchaus sehr nützlich sein, den Cache hin und wieder manuell zu löschen. Diese Maßnahme verhindert, dass sich falsch erstellte Layer in den Builds erhalten und es später im instanziierten Container zu ungewöhnlichen Fehlern kommt. Der entsprechende Befehl lautet:

Abonnement / Subscription

[English] This content is only available to subscribers.

[Deutsch] Diese Inhalte sind nur für Abonnenten verfügbar.

Ganz radikal ist die Möglichkeit, alle nicht genutzten Ressourcen wieder freizugeben. Hierfür gibt es ebenfalls ein explizites Kommando für die Shell.

Abonnement / Subscription

[English] This content is only available to subscribers.

[Deutsch] Diese Inhalte sind nur für Abonnenten verfügbar.

Wir können die gerade vorgestellten Befehle natürlich auch für CI Buildumgebungen wie Jenkins oder GitLab CI nutzen. Allerdings kann es sein, dass dies nicht unbedingt zum gewünschten Ziel führt. Ein bewährter Ansatz für Continuous Integration / Continuous Deployment ist das Aufsetzen einer eigenen Docker-Registry, wohin man selbst erstellte Images deployen kann. Diese Vorgehensweise, ist ein gutes Backup & Chaching System für die genutzten Docker Images. Einmal korrekt erstellte Images lassen sich so bequem über das lokale Netzwerk auf die verschiedenen Serverinstanzen deployen, ohne dass diese ständig lokal neu erstellt werden müssen. Daraus ergibt sich als bewährter Ansatz ein eigens für Docker Images / Container optimierter Buildnode, um die erstellten Images vor der Verwendung optimal zu testen. Auch auf Cloudinstanzen wie Azure und der AWS sollte man auf eine gute Performanz und ressourcenschonendes Arbeiten Wert legen. Schnell können die anfallenden Kosten explodieren und ein stabiles Projekt in massive Schieflage bringen.

In diesem Artikel konnten wir sehen, dass tiefe Kenntnisse der eingesetzten Werkzeuge einige Möglichkeiten zur Kostenersparnis erlauben. Gerade das Motto „Wir machen, weil wir es können“, ist im kommerzeillen Umfeld weniger hilfreich und kann schnell zur teuren Resourcenverschwendung ausarten.


Vibe Coding – eine neue Plage des Internets?

Als ich das erste Mal den Begriff Vibe Coding las, dachte ich erst an Kopfhörer, chillige Musik und den Übertritt in den Flow. Der absolute Zustand der Kreativität dem Programmierer hinterherjagen. Ein Rausch der Produktivität. Aber nein, es wurde mir recht schnell klar, es geht um etwas anderes.

Vibe Coding nennt man das, was man einer KI über den Prompt eingibt, um ein benutzbares Programm zu erhalten. Die Ausgabe des Large Language Models (LLM) ist dann noch nicht gleich das ausführbare Programm, sondern nur der entsprechende Quelltext in der Programmiersprache, die der Vibe Coder vorgibt. Daher braucht der Vibe Coder je nachdem, auf welcher Plattform er unterwegs ist, noch die Fähigkeit, das Ganze zum Laufen zu bringen.

Seitdem ich in der IT aktiv bin, gibt es den Traum der Verkäufer: Man bräuchte keine Programmierer mehr, um Anwendungen für den Kunden zu entwickeln. Bisher waren alle Ansätze dieser Art wenig erfolgreich, denn egal was man auch tat, es gab keine Lösung, die vollständig ohne Programmierer ausgekommen ist. Seit der allgemeinen Verfügbarkeit von KI‑Systemen hat sich einiges geändert und es ist nur eine Frage der Zeit, bis man von den LLM-Systemen wie Copilot etc. auch ausführbare Anwendungen geliefert bekommt.

Die Möglichkeiten, die sich durch Vibe Coding eröffnen, sind durchaus beachtlich, wenn man weiß, was man da tut. Gleich aus Goethes Zauberlehrling, der der Geister, die er rief, nicht mehr Herr geworden ist. Werden Programmierer nun obsolet? Auf absehbare Zeit denke ich nicht, dass der Beruf Programmierer aussterben wird. Es wird sich aber einiges verändern und die Anforderungen werden sehr hoch sein.

Ich kann definitiv sagen, dass ich der KI Unterstützung beim Programmieren offen gegenüberstehe. Allerdings haben mich meine bisherigen Erfahrungen gelehrt, sehr vorsichtig zu sein mit dem, was die LLMs so als Lösung vorschlagen. Möglicherweise liegt es daran, dass meine Fragen sehr konkret und für spezifische Fälle waren. Die Antworten waren durchaus hin und wieder ein Fingerzeig in eine mögliche Richtung, die sich als erfolgreich herausgestellt hat. Aber ohne eigenes Fachwissen und Erfahrung wären alle Antworten der KI nicht nutzbar gewesen. Auch Begründungen oder Erläuterungen sind in diesem Kontext mit Vorsicht zu genießen.

Es gibt mittlerweile diverse Angebote, die den Leuten den Umgang mit künstlicher Intelligenz beibringen wollen. Also in Klartext, wie man einen funktionierenden Prompt formuliert. Ich halte solche Offerten für unseriös, denn die LLM wurden ja dafür entwickelt, natürliche (menschliche) Sprache zu verstehen. Was soll man also lernen, vollständige und verständliche Sätze zu formulieren?

Wer eine ganze Anwendung über Vibe Coding erstellt, muss diese ausgiebig testen. Also sich durch die Funktionen klicken und schauen, ob alles so funktioniert, wie es soll. Das kann durchaus zu einer sehr nervenden Beschäftigung ausarten, die mit jedem Durchlauf lästiger wird.

Auch die Verwendung von Programmen, die durch Vibe Coding erstellt wurden, ist unproblematisch, solange diese lokal auf dem eigenen Computer laufen und nicht als kommerzieller Internetservice frei zugänglich sind. Denn genau hier lauert die Gefahr. Die durch Vibe Coding erstellten Programme sind nicht ausreichend gegen Hackerangriffe gesichert, weswegen man sie nur in geschlossenen Umgebungen betreiben sollte. Ich kann mir auch gut vorstellen, dass künftig in sicherheitskritischen Umgebungen wie Behörden oder Banken die Verwendung von Programmen, die Vibe Coded sind, zu verbieten. Sobald die ersten Cyberattacken auf Unternehmensnetzwerke durch Vibe Coding Programme bekannt werden, sind die Verbote gesetzt.

Neben der Frage zur Sicherheit von Vibe-Coding-Anwendungen werden Anpassungen und Erweiterungen nur mit großem Aufwand umzusetzen sein. Dieses Phänomen ist in der Softwareentwicklung gut bekannt und tritt bei sogenannten Legacy Anwendungen regelmäßig auf. Sobald man hört, dass ist historisch gewachsen ist, man auch schon mitten drin. Fehlende Strukturen und sogenannte technische Schulden lassen ein Projekt über die Zeit so erodieren, dass sich die Auswirkungen von Änderungen nur sehr schwer auf die restlichen Funktionen abschätzen lassen. So ist zu vermuten, dass es in Zukunft sehr viele Migrationsprojekte geben wird, die die KI erstellten Codebasen wieder in saubere Struckturen überführen. Deswegen eignet sich Vibe Coding vor allem für die Erstellung von Prototypen, um Konzepte zu testen.

Mittlerweile gibt es auch Beschwerden in Open Source Projekten, dass es hin und wieder zu Contributions kommt, die nahezu die halbe Codebasis umstellen und fehlerhafte Funktionen hinzufügen. Hier helfen natürlich zum einen der gesunde Menschenverstand und die vielen in der Softwareentwicklung etablierten Standards. Es ist ja nicht so, dass man im Open Source nicht schon früher Erfahrung mit schlechten Code Commits gesammelt hätte. Dadurch kam der Diktaturship-Workflow für Werkzeuge wie Git, das von der Codehosting Plattform GitHub in Pull Request umbenannt wurde.

Wie kann man also schnell schlechten Code erkennen? Mein derzeitiges Rezept ist die Überprüfung der Testabdeckung für hinzugefügten Code. Kein Test, kein Codemerge. Natürlich können auch Testfälle Vibe Coded sein oder es fehlen notwendige Assertions, auch das lässt sich mittlerweile gut automatisiert erkennen. In den vielen Jahren in Softwareentwicklungsprojekten habe ich genügend erlebt, dass mir kein Vibe Coder auch nur annähernd Schweißperlen auf die Stirn treiben kann.

Mein Fazit zum Thema Vibe Coding lautet: Es wird in Zukunft einen Mangel an fähigen Programmierern geben, die Unmengen an schlechtem Produktivcode gerade biegen sollen. Also auf absehbare Zeit noch kein aussterbender Beruf. Dem gegenüber werden durchaus ein paar clevere Leute für das eigene Business sich mit einfachen Informatikkenntnissen ein paar leistungsfähige Insellösungen zusammenscripten, die zu Wettbewerbsvorteilen führen werden. Während wir diese Transformation erleben, wird das Internet weiterhin zugemüllt und die Perlen, von denen Weizenbaum einst gesprochen hat, schwerer zu finden sein.


Stichwortverzeichnis & Abkürzungen

[A]

[B]

[C]

[D]

[E]

[F]

[G]

[H]

[I]

[J]

[K]

[L]

[M]

[N]

[O]

[P]

[Q]

[R]

[S]

[T]

[U]

[V]

[W]

[Y]

[Z]

[X]

Zurück zum Inhaltsverzeichniss: Apache Maven Master Class

A

B

C

D

E

F

G

H

I

J

K

L

M

N

O

P

Q

R

S

T

U

V

W

X

Y

Z

[A]

[B]

[C]

[D]

[E]

[F]

[G]

[H]

[I]

[J]

[K]

[L]

[M]

[N]

[O]

[P]

[Q]

[R]

[S]

[T]

[U]

[V]

[W]

[Y]

[Z]

[X]

Zurück zum Inhaltsverzeichniss: Apache Maven Master Class