Connect with us

Entwicklung & Code

Docker Image Security – Teil 1: Die größten Irrtümer über Image-Scanner


Image Scanner wie Trivy oder Grype sind unverzichtbare Werkzeuge zur Erkennung von Schwachstellen in Container-Images. Während eines Scans erstellen sie eine Software Bill of Materials (SBOM) und gleichen sie mit verschiedenen Schwachstellendatenbanken ab, um potenziell angreifbare Komponenten zu identifizieren. Viele IT-Teams nutzen diese Scanner unter der Annahme, dass sie alle Schwachstellen präzise erkennen. Doch diese Scanner sind dafür anfällig, sowohl False Positives als auch False Negatives zu erzeugen, also Schwachstellen zu melden, die keine sind, oder tatsächliche zu übersehen. Dies führt zu erheblichem Mehraufwand bei der Analyse der Ergebnisse und zu Sicherheitsrisiken.


Marius Shekow

Marius Shekow

Dr. Marius Shekow war über 10 Jahre als Forscher und Softwareentwickler bei Fraunhofer tätig. Seit 2022 ist er Lead DevOps- & Cloud-Engineer bei SprintEins in Bonn. Dort baut er für Konzerne und KMUs individuelle Cloud-Umgebungen, inkl. CI/CD-Automatisierung, Observability und Security-Absicherung.

  • Docker Image Security – Teil 1: Die größten Irrtümer über Image-Scanner

Dieser Artikel beschreibt, wie die Scanner funktionieren, und liefert eine umfassende Liste möglicher False Positives und Negatives, mit konkreten Beispielen. Eine Analyse von acht der beliebtesten Docker Hub Images mit Trivy und Grype zeigt offensichtliche False Negatives bei fast allen Images, wodurch IT-Systeme angreifbar werden. Abschließend werden Lösungsansätze skizziert.

Wirft man bei Docker Hub einen genauen Blick auf beliebte Images (beispielsweise nginx), zeigt das Docker Hub UI selbst bei kürzlich gepushten Tags mehrere Schwachstellen (Vulnerabilities) an. Doch weder Docker Inc. noch die Image-Maintainer würden es dulden, dass selbst die neuesten gepushten Images bekannte Sicherheitslücken aufweisen. Woher kommen also diese vermeintlichen Schwachstellen, und sind sie wirklich ausnutzbar?

Die Images enthalten meistens eine große Anzahl von Softwarekomponenten, etwa Binärdateien und Bibliotheken. Ein PostgreSQL-Image wie postgres:17.1 enthält beispielsweise nicht nur die eine Komponente PostgreSQL, sondern über 200 Komponenten, darunter OpenSSL, die Bash-Shell und verschiedene Systempakete und -bibliotheken. Einige dieser Komponenten können für Exploits anfällig sein. Das ist aber nur dann der Fall, wenn die Komponente während der Container-Laufzeit in den RAM geladen und der angreifbare Codepfad der Komponente tatsächlich ausgeführt wird.

Das Kernproblem ist, dass die Reports von allen Docker-Image-Schwachstellenscannern wie Trivy oder Grype aus verschiedenen technischen Gründen fehleranfällig sind (Details folgen). Konsumenten eines Images würden jedoch Scanner bevorzugen, die nur „True Positives“ und „True Negatives“ erzeugen. In der Realität liefern diese Scanner jedoch auch „False Negatives“ und „False Positives“.

Begriffe wie „False Positive“ stammen aus der Statistik und der Medizin (siehe Wikipedia). „Positive“ bzw. „Negative“ bezieht sich auf die vom Scanner gemeldete Einschätzung, während „True“ bzw. „False“ angibt, ob diese Einschätzung tatsächlich stimmt. Im Kontext des Image-Scanning haben die Begriffe folgende Bedeutung:

  • True Positive: Der Scanner meldet eine angreifbare Komponente, und die Einschätzung stimmt, weil diese Komponente während der Container-Ausführung tatsächlich geladen wird und angreifbare Codepfade ausgeführt werden, die ein Angreifer ausnutzen kann. Auf solche Funde muss man reagieren, etwa durch Aktualisieren oder Entfernen der betroffenen Komponente.
  • False Positive: Der Scanner meldet eine angreifbare Komponente. Aber sie kann in diesem Image aus verschiedenen Gründen nicht ausgenutzt werden. Der Scanner liegt also falsch. Leider weiß man zu diesem Zeitpunkt noch nicht, ob ein gemeldeter „Positive“-Fund nun ein True Positive oder False Positive ist. Es muss teilweise erheblicher Aufwand investiert werden, um dies (manuell) zu ermitteln. Dies wird auch als Triage bezeichnet.
  • True Negative: Der Scanner hat eine Komponente, die Teil des Images ist, zu Recht nicht als angreifbar gemeldet.
  • False Negative: Der Scanner hat eine Image-Komponente nicht als angreifbar gemeldet, obwohl er es hätte tun sollen, weil diese Komponente tatsächlich angreifbar ist. Das ist eine gefährliche Situation, da das Image angreifbar ist, ohne dass man es weiß.

Die folgende Abbildung 1 veranschaulicht den Ablauf, wenn ein Scanner wie Trivy ein Image analysiert:


Ablauf-Diagramm für einen Image Scan

Ablauf-Diagramm für einen Image Scan

Image-Scan-Ablauf (Abb. 1)

Schritt 1: Der Scanner analysiert ein Image und erstellt dafür eine (interne) SBOM, also eine Liste aller Softwarekomponenten des Images. Die Implementierungen der Scanner unterscheiden sich, aber prinzipiell hat jeder Scanner mehrere Katalogisierer, die Softwarepakete identifizieren. Wichtige Katalogisierer sind:

  • Metadaten des Linux-Paketmanagers: Jeder Scanner identifiziert zuerst die Linux-Distribution des Images (z. B. Alpine oder Ubuntu) und analysiert dann die Metadaten des Paketmanagers. Die Metadaten beinhalten, welche Pakete via Paketmanager installiert wurden (z. B. die Datei /var/lib/dpkg/status für apt). Die konkret unterstützten Linux-Distributionen variieren je nach Scanner.
  • Metadaten von Programmiersprachen-Paketmanagern: Die meisten Scanner können die Dependency-Manifeste verschiedener Programmiersprachen (z. B. txt für Python oder yarn.lock für Yarn/npm) indizieren, um Dependencies der jeweiligen Sprache/Ökosystem zu erkennen.
  • Eingebettete SBOMs: Um es Scannern zu ermöglichen, Komponenten zu erkennen, die nicht via Paketmanager installiert wurden, unterstützen einige Scanner das Auffinden eingebetteter standardisierter SBOMs, die Teil des Dateisystems des Images sind. Dies ist hier für Trivy dokumentiert. Zudem unterstützen sowohl Trivy als auch Grype einige proprietäre eingebettete SBOM-Formate, z. B. für Bitnami-Images.
  • Metadaten in Binärdateien: Die Compiler einiger Programmiersprachen (beispielsweise Rust oder Go) können Metadaten in dessen produzierte Binärdateien einbetten. Die Metadaten enthalten Namen und Versionen der Anwendung sowie deren (transitiver) Dependencies. Scanner wie Trivy oder Grype können diese Metadaten aus einer Binärdatei extrahieren und interpretieren.
  • Binär-Scanning: Um Komponenten, die beispielsweise mit C/C++ kompiliert wurden (und nicht via Paketmanager installiert wurden), zu identifizieren, besitzt die in Grype integrierte Syft-Library einen Binär-Scanner-Katalogisierer. Dieser verwendet reguläre Ausdrücke auf Dateisystem-Pfade, und kann dadurch ausgewählte Binärdateien identifizieren. Bei Trivy hat lediglich die kommerzielle Aqua Security Edition einen solchen Katalogisierer, bei Trivys Open-Source-Variante fehlt er.

Schritt 2: Das Scanner-CLI lädt eine Schwachstellendatenbank herunter (es sei denn, es liegt bereits eine aktuelle Kopie im lokalen Cache). Die Scanner-Hersteller kompilieren diese Datenbankdatei täglich neu. Ihre Größe beträgt etwa 60 bis 70 MByte bei Trivy und Grype. Die Datei hat ein proprietäres Format und enthält Schwachstellen aus verschiedenen Schwachstellendatenbanken. Die vorkompilierten Datenbanken haben folgende Vorteile:

  • Der Scanner kann effizient in ihnen suchen (dank des proprietären Formats).
  • Der Scanner muss zur Scan-Zeit nicht jede Schwachstellendatenbank über das Internet abfragen (vielen Datenbanken fehlt ohnehin eine solche Abfrageschnittstelle).
  • Der Scanner funktioniert auch in isolierten Offline-Umgebungen.

Schritt 3: Der dritte Schritt ist das Kreuzverweisen (siehe Kasten). Der Scanner gleicht alle Komponenten der intern erstellten SBOM mit den Einträgen seiner Schwachstellendatenbank ab. Er meldet jeden Treffer als positives Ergebnis.

Der Schritt „Kreuzverweisen“ ist für die Scanner technisch anspruchsvoll, weil eine Softwarekomponente in vielen verschiedenen Repositorys unter unterschiedlichen Bezeichnern und Versionen existiert, die jeweils von unterschiedlichen Schwachstellen betroffen sind.

Ein Beispiel: Angenommen, ein Image enthält einen Python-Interpreter. Python wird auf zahlreichen Wegen verteilt. Zum einen durch Download von der python.org-Homepage, deren Binär-Builds direkt aus dem Upstream-Quellcode erstellt werden. Daneben paketieren die meisten Linux-Distributionen – darunter Red Hat Enterprise Linux, SUSE Linux, Alpine, Debian oder Ubuntu – Python, indem sie die Binärpakete selbst kompilieren und in den offiziellen Distribution-Repositorys speichern.

Welche Pakete in welcher Version aufgenommen werden, entscheidet sich jeweils beim Zusammenstellen einer neuen Linux-Distribution. Im Fall von Python ist dies beispielsweise Python 3.12.3 für Ubuntu 24.04 („Noble Numbat“). Aus Stabilitätsgründen bleibt diese Python-Version für die gesamte Lebensdauer dieser Ubuntu-Version fixiert. Da eine so alte Python-Version schnell angreifbar wird, erstellen die Linux-Distro-Maintainer jeweils Backports von Sicherheitspatches, die distributionsspezifische Suffixe wie 3.12.3-1ubuntu0.5 erhalten. Anhand eines eigenen Security-Trackers halten die Maintainer fest, welche ihrer Builds von welchen Schwachstellen/CVEs betroffen sind (siehe die Übersicht in der Trivy-Dokumentation).

Ermittelt ein Scanner wie Trivy für ein via Paketmanager installiertes Paket (wie Python) die Kreuzverweise zu den CVEs, beschränkt sich der Kreuzverweis-Algorithmus allein auf die distributionsspezifische Schwachstellendatenbank. Daher erkennt er nur Schwachstellen für Pakete, die aus den offiziellen Repositorys installiert wurden. Die Scanner-Hersteller könnten alternativ auf generische (Distro-unabhängige) Schwachstellendatenbanken wie NVD zurückgreifen, die alle (Python-)Schwachstellen enthalten – etwa über CPE-Bezeichner wie „cpe:2.3:a:python:python:3.12.3:::::::*“. Nach eigener Aussage verzichten sie jedoch darauf, weil sonst zu viele False Positives gemeldet würden.

Hinweis: Das Kreuzverweisen von Paketen, die in einer einzigen „autoritativen“ Registry gespeichert sind (z. B. Node.js-Pakete, die in npmjs.org gespeichert sind), funktioniert einwandfrei, ist also von dieser Einschränkung nicht betroffen.

Die folgende Übersicht listet Gründe auf und zeigt anhand von Beispielen, warum Scanner gewisse Schwachstellen nicht melden:

Grund 1: Der Scanner erkennt die Komponente nicht, weil sie nicht via Paketmanager installiert wurde.

Beispiel: Ein Multi-Stage Dockerfile kompiliert ein natives C/C++ Binary in der Build Stage und kopiert es in die Final Stage des Images.

Grund 2: Der Scanner erkennt die Komponente nicht, obwohl sie via Paketmanager installiert wurde, da die zugehörigen Metadaten des Paketmanagers gelöscht wurden.

Beispiel: Tools wie mint löschen solche Metadaten bei der Optimierung des Images, oder die Metadaten wurden absichtlich oder versehentlich von Menschen gelöscht (siehe Vortrag Malicious Compliance auf der KubeCon 2023 sowie diesen Folge-Vortrag auf der KubeCon 2025).

Grund 3: Der Scanner erkennt die Komponente zwar, sie ist jedoch nicht in der Schwachstellendatenbank des Scanner-Tools bekannt, die nur Pakete aus dem offiziellen Repository der Linux-Distribution abdeckt.

Beispiel: Das Paket wurde in ein Debian-basiertes Image aus einem Third-Party Debian-Repository oder mithilfe einer .deb-Datei installiert (siehe beispielsweise PostgreSQL).

Grund 4: Der Scanner erkennt die Komponente, und (prinzipiell) ist diese Komponente in der Schwachstellendatenbank des Scanners als angreifbar bekannt. Allerdings hat das Scan-Tool die Komponente mit einem anderen Identifier erkannt als dem, der in der Datenbank verwendet wird. Daher schlägt das Kreuzverweisen fehl.

Beispiel: Versucht man mit Trivy oder Grype eine SBOM zu scannen, die von einem anderen Tool (wie Bazel oder apko) erstellt wurde, werden keine Schwachstellen gefunden – konkrete Beispiele sind Googles Distroless Image SBOMs oder die von Chainguard bereitgestellten SBOMs.

Grund 5: Probleme mit der Schwachstellendatenbank des Scanners.

Beispiele: Der Scanner-Hersteller hat seine eingebettete/proprietäre Datenbank versehentlich nicht korrekt aktualisiert oder erstellt, beispielsweise könnte einer der zugrunde liegenden Datenbankanbieter (z. B. NVD) vollständig fehlen.

Das Scanner-Tool hat die lokal gecachte Datenbank seit Längerem nicht aktualisiert, etwa aufgrund von Verbindungsproblemen.

Die Schwachstelle im Code der Komponente wurde bisher nicht gemeldet, oder sie hat noch kein CVSS-Rating erhalten (siehe Bericht über den wachsenden Rückstand der NVD).

Die Ursachen, warum False Positives auftreten, also gemeldete Schwachstellen, die in Wahrheit nicht angreifbar sind, lassen sich in vier Gruppen zusammenfassen.

Grund 1 ist, der Scanner findet eine Komponente im Image, die (prinzipiell) Schwachstellen hat. Diese Komponente wird aber entweder während der gesamten Container-Laufzeit nicht geladen oder es werden nur diejenigen Teile verwendet, die nicht angreifbar sind. Zum Beispiel könnte ein Datenbankserver-Image ausgeführt werden, das auch einen angreifbaren Perl-Interpreter enthält, Perl wird aber nie verwendet.

Zweitens kann der Scanner glauben, eine Komponente gefunden zu haben, weil sie in den Metadaten des Paketmanagers aufgelistet ist. Die Dateien/Binaries dieser Komponente wurden jedoch (manuell) gelöscht, ohne die zugehörigen Metadaten korrekt zu aktualisieren. So könnten im Dockerfile Zeilen stehen wie RUN rm anstelle von RUN apt-get -y remove .

Der dritte mögliche Grund können Meinungsverschiedenheiten zwischen den Maintainern der Schwachstellendatenbank und den Maintainern der Komponente sein, ob die Komponente wirklich angreifbar ist. Die Software-Maintainer wissen prinzipiell von der Schwachstelle, haben aber aus verschiedenen Gründen nicht vor, diese in nächster Zeit zu beheben. So wird zum Beispiel CVE-2005-2541 von Security-Forschern als High-Severity-Schwachstelle angesehen, aber Debian interpretiert sie als „beabsichtigtes Verhalten“, also wie ein Feature. Oder die Software-Maintainer sehen die Schwachstelle als kleines Problem und haben ihr daher eine niedrige Priorität zugewiesen. Sie wird möglicherweise erst in einigen Monaten oder Jahren behoben.

Viertens schließlich könnte der Scanner die Security-Backports nicht richtig erkennen, die von einigen Linux-Distributionen für bestimmte Komponenten implementiert wurden. CVE-2020-8169 etwa gibt beispielsweise an, dass die curl-Versionen 7.62.0 bis 7.70.0 eine Schwachstelle aufweisen, die in Version 7.71.0 behoben ist. Das curl-Paket in Debian Buster hat allerdings einen Backport des Security-Fixes in Version 7.64.0-4+deb10u2 (siehe Debian Security-Tracker und DSA-4881-1), die der Scanner nicht erkennt (der Scanner erkennt Version 7.64.0 und meldet sie als angreifbar).



Source link

Entwicklung & Code

Warum viele Teams mit Monolithen besser fahren als mit Micro-Frontends


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Softwarearchitektur kennt Moden und Gegenbewegungen. Frontends in winzige unabhängige Teile zu zerschneiden, galt in den letzten Jahren als modern: Micro-Frontends und Microservices. Heute zeigt sich: Der Ansatz bleibt wertvoll. Aber nur dort, wo er die organisatorische Realität tatsächlich abbildet. Für viele kleine bis mittlere Teams ist ein modularer Monolith oft die robustere Startarchitektur.


Nicolai Wolko

Nicolai Wolko

Nicolai Wolko ist Softwarearchitekt, Consultant und Mitgründer der WBK Consulting AG. Er unterstützt Unternehmen bei komplexen Web- und Cloudprojekten und wirkt als Sparringspartner sowie Gutachter für CTOs. Fachbeiträge zur modernen Softwarearchitektur veröffentlicht er regelmäßig in Fachmedien und auf seinem Blog.

Die internationale Umfrage State of Frontend des Unternehmens The Software House zeigt eine klare Bewegung: 2022 gaben 75,4 Prozent der Befragten an, Micro‑Frontends zu nutzen. 2024 waren es nur noch 23,6 Prozent. Das klingt auf den ersten Blick dramatisch, ist aber kein Tod der Idee. Der Rückgang zeigt, dass viele Teams Micro-Frontends nicht mehr als Standardlösung betrachten, sondern selektiv dort einsetzen, wo organisatorische oder architektonische Gründe es rechtfertigen. Denn parallel dazu steigt die Popularität von Module Federation, und zwar nicht nur für Micro‑Frontends: 2024 berichten 51,8 Prozent die Nutzung, oft auch in monolithischen Anwendungen, um Teile unabhängig zu aktualisieren. Das stützt die These einer Konsolidierung auf weniger Deployment-Einheiten bei weiterhin modularer Struktur.

Bemerkenswert ist, dass auch KI Microservices favorisiert: Fragt man ChatGPT ohne Kontext nach Architekturmustern, empfiehlt es fast immer Microservices und oft auch Micro-Frontends. Das ist kein Indiz für universelle Richtigkeit, sondern für den Hype-Bias in den Trainingsdaten. Ohne fachliche Einordnung bleibt es eine Wahrscheinlichkeitsaussage und ersetzt nicht die Analyse eines erfahrenen Architekten oder einer erfahrenen Architektin.

Micro-Frontends entstanden als Analogie zu Microservices und erfreuen sich nicht ohne Grund großer Beliebtheit. Die Idee besteht darin, schwerfällige SPAs oder Webportale in kleine, autonome Apps aufzuteilen. Jedes Team kann sein Stück mit dem Lieblingsframework entwickeln und unabhängig deployen. Das reduziert den Koordinationsaufwand, vermeidet monolithische Rebuilds und erlaubt, Teile des Frontends asynchron zu laden.

In der Praxis führt diese Freiheit jedoch auch oft zu neuen Problemen: Mehrere Frameworks oder UI-Bibliotheken erhöhen die Downloadgröße und verlängern die Time to Interactive, globale Stores oder Shells schaffen den berüchtigten Hidden Monolith oder verteilten Monolithen, in dem Micro-Apps weiterhin denselben Zustand teilen, und zusätzliche Deployments erzeugen Overhead bei CI/CD, Feature Flags und Versionierung.

Micro‑Frontends eignen sich, wenn wirklich unabhängige Teams und heterogene Stacks aufeinandertreffen, etwa bei Tech‑Riesen wie Amazon oder Spotify. In sehr vielen Projekten erzeugt die zusätzliche Orchestrierung jedoch mehr Probleme, als sie löst und sorgt schnell für komplexe Builds und längere Ladezeiten. Gerade bei kleineren Teams und klar abgegrenzten Produkten übersteigt der Aufwand den Nutzen, und die erhoffte Entkopplung bleibt aus. Oft entsteht faktisch ein verteilter Monolith mit zahlreichen Teilprojekten, die doch nur gemeinsam leben können. Eine fatale Entwicklung, denn der verteilte Monolith vereint oft die schlechtesten Eigenschaften beider Welten in sich.

Die Debatte über Monolithen und Microservices krankt oft daran, dass Begriffe nicht klar sind. Ein Beitrag auf dem Dev-Details-Blog erläutert anschaulich, dass die Einordnung nicht von der Anzahl der Repositories, Container oder Teams abhängt:

  • Ein Monolith entsteht, wenn mehrere Teile so eng gekoppelt sind, dass sie nur gemeinsam deployt werden können.
  • Microservices wiederum zeichnen sich durch lose Kopplung und hohe Kohäsion aus. Sie können Daten und Ressourcen mit anderen Diensten teilen, solange jede Komponente ihre eigene Verantwortung behält.
  • Serverless bedeutet nur, dass die Infrastrukturverwaltung abstrahiert wird. Es ist kein Synonym für Function as a Service. Entscheidend ist, dass sich die Teams nicht um Server kümmern müssen und nur für tatsächliche Nutzung bezahlen.

Diese Perspektive hilft, Modebegriffe zu entmystifizieren. Man kann monolithische, Microservices‑basierte oder Serverless-Architekturen mischen – entscheidend ist, wie stark die Komponenten voneinander abhängen. Wenn mehrere Services stets gemeinsam deployt werden müssen, entsteht faktisch wieder ein „verteilter Monolith“.

Oft zitiert wird das Team hinter Amazon Prime Video, wie auch bereits auf heise berichtet. Es hat 2023 die Audio/Video-Monitoring-Komponente von einem Step-Functions-getriebenen verteilten Design auf ein monolithisches Prozessdesign umgestellt, was zu über 90 Prozent geringeren Kosten und höherer Skalierbarkeit für diese Komponente führte.

Das ist keine Abkehr von Microservices im gesamten Produkt, aber eine klare kontextspezifische Optimierung: weniger Netzwerk-Hops, wegfallender S3-Zwischenspeicher und weniger Orchestrierungs-Overhead.

Ein hervorragendes Beispiel dafür, dass Architektur keinem Etikett folgen sollte, sondern in diesem Fall dem Lastprofil und Coupling. Microservices und Serverless sind Werkzeuge, die bei passender Problemklasse hervorragend funktionieren; andernfalls ist ein enger gekoppelter Entwurf aber günstiger und einfacher zu betreiben.

Praktische Erfahrungen bestätigen diese Sicht: Ken Kantzer, VP Engineering bei FiscalNote und Gründer der Sicherheits- und Architekturberatung PKC Security, hat in über zwanzig Code-Audits von Start-ups wiederkehrende Muster identifiziert. Sein Befund: Die erfolgreichsten Unternehmen hielten ihre Architektur bewusst einfach. Teams, die konsequent nach dem Prinzip „Keep it simple“ arbeiteten, dominierten später ihre Märkte.

Demgegenüber verschwanden viele Firmen, die sich früh in komplexe Architekturexperimente stürzten. Kantzer hält die vorzeitige Umstellung auf Microservices, stark verteilte Systeme und Messaging-lastige Designs für eine eine selbst verschuldete Falle, die Teams in unnötige Betriebs- und Entwicklungsprobleme manövriert. In seinen Audits zeigte sich, dass solche Systeme einen Großteil der Entwicklerzeit mit Queue-Fehlern, Versionsinkompatibilitäten und Netzwerk-Latenzen blockierten, während die eigentliche Produktentwicklung ins Stocken geriet.

Die Lehre: Komplexität ist keine Investition in Zukunftsfähigkeit, wenn sie dem Kontext vorauseilt – sie ist ein Kostenfaktor, der den Markterfolg gefährden kann.

Der modulare Monolith oder auch Modulith vereint die Vorteile von Monolith und Microservices: Die Anwendung wird in klar abgegrenzte Module unterteilt, die sich intern unabhängig entwickeln, testen und versionieren lassen, aber gemeinsam deployed werden. Thoughtworks beschreibt ihn als „best of both worlds“: Es gibt weniger bewegliche Teile, einfache Deployments und geringere Infrastrukturkosten, während eine klare Aufteilung in Module dennoch möglich ist. Durch die gemeinsame Deployment-Einheit entfallen Gateways, Service Discovery und verteiltes Logging. Das verbessert die Performance, da Module über Funktionsaufrufe statt über das Netzwerk kommunizieren und das System bei Ausfall eines Moduls nicht sofort fragmentiert. Gleichzeitig lassen sich klare Teamgrenzen und Domänen definieren, sodass Entwickler ein Modul später relativ leicht ausgliedern können.

Eine praktische Entscheidungshilfe in Tabellenform stellen die Architekturexperten hinter der Toolsuite Ptidej zur Verfügung. Microservices bieten Vorteile, wenn autonome Teams mit eigenen Releasezyklen an unterschiedlichen Teilen eines großen Systems arbeiten, wenn einzelne Komponenten sehr unterschiedlich skalieren oder wenn verschiedene Technologien notwendig sind. Ein Monolith hingegen genügt, wenn das Team überschaubar ist, die Domäne klar umrissen und die Skalierungsanforderungen homogen sind. Wichtig ist, dass das System modular bleibt, damit es sich bei Bedarf später in Microservices zerlegen lässt.

Der modulare Monolith bietet somit einen pragmatischen Mittelweg: Er teilt eine Anwendung in klar abgegrenzte Module, deployt sie aber gemeinsam. Im Python/Django-Umfeld ist das Prinzip seit Jahren gelebte Praxis („Apps“ als Modulgrenzen), auch wenn es dort nicht Modulith heißt.

Thoughtworks empfiehlt, mit einem solchen Monolithen zu starten und erst nach gründlichem Verständnis der Geschäftsprozesse einzelne Module auszulagern. Die Vorteile sind klar: einfache Deployments, gute Performance, niedrigere Betriebskosten und weniger Latenz.

Moderne Monorepo‑Werkzeuge senken die Reibung größerer Codebasen: Nx etwa bietet Computation Caching (lokal und remote) und „Affected“‑Mechaniken, sodass bei Änderungen nur die betroffenen Projekte gebaut und getestet werden. Das senkt Build‑ und CI‑Zeiten drastisch und macht ein Repo mit vielen Modulen praktikabel.

Interessant ist, dass Nx explizit dokumentiert, dass Micro‑Frontends vor allem dann empfehlenswert sind, wenn unabhängiges Deployment wirklich notwendig ist. Andernfalls lassen sich dieselben Build‑Effekte zunehmend auch ohne Micro-Frontend‑Architektur erzielen (etwa Module Federation nur zur Build‑Beschleunigung).

Aus Daten, Praxisberichten und Werkzeugtrends lassen sich pragmatische Leitlinien ableiten:

  1. Für die meisten kleinen bis mittleren Teams ist ein modularer Monolith der schnellste Weg zu Features und Feedback. Er reduziert Kosten, minimiert Betriebsrisiken und bleibt evaluierbar.
  2. Wenn Komponenten immer gemeinsam deployt werden müssen, ist die Anwendung monolithisch – unabhängig davon, auf wie viele Container oder Repos sie verteilt ist. Umgekehrt sind Microservices erst dann sinnvoll, wenn Deployments wirklich unabhängig sind.
  3. Verteilte Systeme erkauft man sich mit Betriebskosten: Observability, Versionierung, Backward Compatibility, Netzwerklatenz, CAP‑Trade‑offs (Abwägungen zwischen Konsistenz, Verfügbarkeit und Partitionstoleranz). Wer diese Reife nicht hat oder nicht braucht, verliert Zeit und Fokus aufs Produkt. Genau das zeigen Code‑Audits aus der Start‑up‑Praxis.
  4. Was in einem Konzern mit Dutzenden Teams sinnvoll ist, ist für ein Team mit zehn Leuten häufig Overkill. Architektur folgt Teamschnitt und Geschäftsprozess, nicht dem Blog‑Hype. Der Artikel auf Heise hat das am Prime‑Video‑Beispiel sorgfältig eingeordnet (Stichwort Modulith).
  5. Werden einzelne Module zu Engpässen (abweichender Release‑Rhythmus, stark abweichende Last, anderes Team), lassen sie sich sauber herauslösen. Ohne vorzeitige Zersplitterung bleibt die Komplexität beherrschbar.



Source link

Weiterlesen

Entwicklung & Code

Bestie statt for-Schleife: KI entwickelt Programmiersprache im Gen-Z-Slang


Damn, das ist cringe: Der Australier Geoffrey Huntley hat die Programmier-KI Claude Code von Anthropic drei Monate in Dauerschleife laufen lassen, um eine eigene Programmiersprache im Stile der verbreiteten Umgangssprache der Generation Z zu entwerfen. Und warum? Nun, weil er es kann, wie er in einem Blogpost darlegt.


WTF

WTF

Das Internet ist voll von heißen IT-News und abgestandenem Pr0n. Dazwischen finden sich auch immer wieder Perlen, die zu schade sind für /dev/null.

Tatsächlich habe ihn einfach die Möglichkeit gereizt, dass mithilfe generativer KI der Traum vom eigenen Compiler Gestalt annehmen kann, schreibt er. Das Ganze sei dann auch ein Lernexperiment gewesen. Der KI sei es dabei selbst überlassen worden, die Sprache jeweils weiter zu verbessern. Das Ergebnis hat er sogar auf einer eigenen Website zum Download bereitgestellt. Der Name der Programmiersprache: Cursed (auf deutsch: verflucht).

Der Compiler verfügt über zwei Modi. Er kann als Interpreter oder als Compiler eingesetzt werden und Binärdateien für macOS, Linux und Windows erstellen. Zudem gebe es halbfertige Erweiterungen für die Editoren VSCode, Emacs und Vim. Wer sich den Entstehungsprozess anschauen möchte, findet dazu entsprechende Videos bei YouTube.

Sprachlich darf man sich das so vorstellen, dass an die Stelle von bekannten Begriffen wie for oder case Wörter treten, die in der GenZ gerne benutzt werden, wie etwa bestie oder mood. Eine Roadmap zur Weiterentwicklung gebe es nicht, darüber soll die Community entscheiden.

Der ursprüngliche Prompt lautete: „Hey, kannst du mir eine Programmiersprache wie Golang erstellen, bei der jedoch alle lexikalischen Schlüsselwörter ausgetauscht sind, sodass sie dem Slang der Generation Z entsprechen?“

Wer dem Beispiel von Huntley folgen möchte, sollte allerdings das nötige Kleingeld bereithalten. Der eigene Compiler koste einen etwa 5000 US-Dollar, schreibt er in einem Post auf X. Tatsächlich habe er mit 14.000 US-Dollar fast das Dreifache investieren müssen, da Cursed zunächst in C, dann in Rust und jetzt in Zig entwickelt wurde. Aber so gebe es jetzt eben auch drei Editionen des Compilers. Und am Ende sei das nur ein Vierzehntel des Gehalts eines Entwicklers in San Francisco, scherzt er.


(mki)



Source link

Weiterlesen

Entwicklung & Code

MCP Registry gestartet: Katalog für MCP-Server


close notice

This article is also available in
English.

It was translated with technical assistance and editorially reviewed before publication.

Das Entwicklungsteam hinter dem Model Context Protocol (MCP) hat die MCP Registry als Preview eingeführt – einen offenen Katalog und eine API, um öffentlich verfügbare MCP-Server ausfindig zu machen und zu verwenden. Bei MCP handelt es sich um ein offenes Protokoll für den Zugriff von Large Language Models (LLMs) auf externe Datenquellen.

Bereits vor einigen Monaten teilte das MCP-Team auf GitHub mit, an einem zentralen Register für das MCP-Ökosystem zu arbeiten. Die nun veröffentlichte, quelloffene MCP Registry soll das Verfahren standardisieren, wie MCP-Server verteilt und entdeckt werden. Sie bietet Server-Maintainern die Möglichkeit, ihre Server hinzuzufügen, und Client-Maintainern, auf Serverdaten zuzugreifen.

Um der Registry einen Server hinzuzufügen, muss dieser auf einer Package Registry wie npm, PyPI oder DockerHub veröffentlicht sein. Eine detaillierte Anleitung findet sich auf GitHub. Dort erfahren Developer, wie sie eine server.json-Datei für ihren Server erstellen, Authentifizierung mit der Registry erreichen, ihren Server veröffentlichen und die Veröffentlichung verifizieren können.

Wie das MCP-Team betont, soll das zentrale Register als hauptsächliche Source of Truth für öffentlich verfügbare MCP-Server dienen, jedoch den bereits bestehenden Registries von Community und Unternehmen nicht im Weg stehen. Diese können in der MCP Registry öffentliche oder private Sub-Registries anlegen, wie das MCP-Team auf GitHub beschreibt.

Bereits existierende Sammlungen sind etwa eine lange, gepflegte Liste auf GitHub und ein Docker-Verzeichnis für MCP-Quellen.

Da es sich bei der MCP Registry derzeit um eine Preview handelt, gibt es keine Garantie für die Beständigkeit der darin enthaltenen Daten. Auch sind Breaking Changes möglich, bevor die Registry die allgemeine Verfügbarkeit erreicht.

Weitere Informationen sind auf dem MCP-Blog zu finden.


(mai)



Source link

Weiterlesen

Beliebt