- Ein ACM-Artikel beleuchtet die technische Evolution von Docker, das seit seiner ersten Veröffentlichung 2013 die Art und Weise, wie Entwickler Anwendungen bauen, bereitstellen und ausführen, grundlegend verändert hat, und ordnet die jahrzehntelange Systemforschung hinter der schlichten CLI ein
- Die technische Grundlage von Docker ist die Nutzung von Linux-Namespaces, um Prozessisolierung auch ohne virtuelle Maschinen zu erreichen; durch die Kombination von sieben Namespace-Typen, die seit 2001 schrittweise hinzugekommen sind, werden leichtgewichtige Container umgesetzt
- Für die Unterstützung von macOS und Windows wurde eine gegenläufige Architektur gewählt, bei der ein Library Virtual Machine Monitor (HyperKit) direkt in die Desktop-App eingebettet ist; statt eines herkömmlichen Hypervisor-Ansatzes läuft Linux innerhalb eines User-Prozesses
- Heute unterstützt Docker heterogene Hardware wie ARM und RISC-V sowie AI-Workloads und hat sich in Cloud, Desktop und Edge als standardisierte Entwicklungsinfrastruktur etabliert
- Mit dem Aufstieg von AI-Workloads ist das Management von GPU-Abhängigkeiten zu einer neuen Herausforderung geworden; die Weiterentwicklung von Docker setzt sich mit GPU-Unterstützung über CDI (Container Device Interface) und der Integration von TEE (Trusted Execution Environment) fort
Technische Ursprünge
- Anfang der 2000er Jahre war es unter Linux-Distributionen üblich, zahlreiche Abhängigkeiten manuell zu installieren und Software direkt zu kompilieren und zu konfigurieren; mit dem Aufstieg des Cloud Computing im Jahr 2010 wurde dieser Prozess noch komplexer
- Docker vereinfachte dies, indem Entwickler ihre Anwendungen samt aller Abhängigkeiten als **Dateisystem-Image („Container“) ** verpacken konnten, das auf jeder Maschine mit installiertem Docker ausgeführt werden kann
- Im Gegensatz zu virtuellen Maschinen ist dafür keine vollständige Betriebssysteminstallation nötig; wenige Befehle genügen
Typischer Workflow
- Schreibt ein Entwickler ein Dockerfile, definiert es einen schrittweisen Build-Prozess auf Basis einer Shell-Syntax
- Python-Website-Beispiel: Beginnend mit
FROM python:3 werden die Installation von Abhängigkeiten, das Kopieren des Codes, die Freigabe eines Ports und der Startbefehl in einer einzigen Datei beschrieben
- Mit
docker build wird ein Container-Image erzeugt und mit docker push in den Docker Hub gepusht
- Die Ausführung erfolgt mit Angaben wie gemounteten Daten-Volumes und freigegebenen Netzwerkports, etwa
docker run -v data:/app/data -p 80:80
- Seit 2013 wurde die CLI stark erweitert und das Backend vollständig neu entworfen, doch der grundlegende Workflow aus Dockerfile schreiben →
docker build → docker run ist konsistent geblieben
- Auf GitHub wurden mehr als 3,4 Millionen Dockerfiles im Root öffentlicher Repositories gefunden
Interne Funktionsweise: Linux-Namespaces
- Der OS-Kernel isoliert den Prozessspeicher, doch viele Systemressourcen wie Dateisysteme, Konfigurationsdateien und dynamische Bibliotheken bleiben gemeinsam genutzt
- Auf derselben Maschine ist es sehr schwierig, mehrere Apps mit widersprüchlichen Anforderungen an dynamische Bibliotheken zu installieren
- Außerdem kann es zu unerwünschten Interferenzen zwischen Prozessen kommen, etwa durch Konflikte bei Netzwerkports
- Das ließe sich lösen, indem jede App in einer eigenen virtuellen Maschine (VM) läuft, doch das ist wegen redundanter Kernel, Dateisysteme, Caches und Bridge-Netzwerke sehr schwergewichtig
- Da jedes Gast-OS unabhängig arbeitet, ist auch die Deduplizierung von Storage und Arbeitsspeicher schwierig
chroot() aus Unix v7 von 1978 erlaubte zwar ein separates Root-Dateisystem, unterstützte aber keine Komposition von Dateisystemen für mehrere Apps
- Nix und Guix lösen dies über app-spezifisches Repackaging von Verzeichnissen plus dynamisches Linking, sind jedoch schwer auf proprietäre Software anwendbar und beheben keine Konflikte bei Netzwerkports
- Docker entschied sich für Linux-Namespaces: Für jeden Prozess lässt sich individuell steuern, wie er auf gemeinsam genutzte Ressourcen wie Dateien und Verzeichnisse zugreift
- Beispiel: Zwei Prozesse in unterschiedlichen Namespaces können
/etc/passwd unterschiedlich interpretieren, etwa als /alice/etc/passwd beziehungsweise /bob/etc/passwd
- Namespaces werden nur beim Öffnen einer Ressource angewendet; danach verhalten sich File-Deskriptoren ohne zusätzlichen Overhead wie normale Kernel-Ressourcen
- Entwicklungsgeschichte der Namespaces
- 2001, Linux 2.5.2: Mount-Namespace
- 2006, Linux 2.6.19: IPC-Namespace
- 2007, Linux 2.6.24: Netzwerk-Stack-Namespace
- Insgesamt werden sieben Namespace-Typen unterstützt
- Anders als bei Plan 9 wurden Namespaces nicht von Anfang an entworfen, sondern schrittweise ergänzt, weshalb sie Low-Level blieben und schwer zu verwenden waren
- Vergleichbare Funktionen in FreeBSD und Solaris fanden ebenfalls keinen breiten praktischen Einsatz
- Der zentrale Beitrag von Docker im Jahr 2013 war es, einen praktikablen Mittelweg zwischen der schwergewichtigen Isolation von VMs und der Benutzerfreundlichkeit nativer OS-Bausteine zu finden
Ausführungsarchitektur von Docker-Linux-Containern
- Docker verwendet eine Client-Server-Architektur und besteht aus einem auf dem Host laufenden Server-Daemon (
dockerd) sowie einem CLI-Client, der Anfragen über eine RESTful API sendet
- Um 2015 wurde der monolithische Daemon aufgespalten und in spezialisierte Komponenten umstrukturiert
- BuildKit: setzt Dateisystem-Images zusammen
- containerd: instanziiert Images als laufende Container und verwaltet Netzwerk- und Storage-Ressourcen
Container-Images
- Beim Aufruf von
docker build wird ein geschichtetes Dateisystem-Image erzeugt, das die ausführbaren Dateien und Daten des Dockerfiles abbildet
- Unterste Schicht: eine OS-Distribution wie Debian oder Alpine Linux (oder manuell aus einem tar-Archiv zusammengesetzt)
- Weitere Schichten: die Dateisystem-Differenzen, die durch die Ausführung einzelner Dockerfile-Befehle entstehen
- Gespeichert wird dies in einem content-addressed Storage-System, bei dem der Hash des Dateisystem-Images als Schlüssel dient
- Effiziente Deduplizierung, garantierte Unveränderlichkeit und Manipulationsprüfung über den Hash
- 2016 standardisierte die Open Container Initiative (OCI) das Image-Format; es gibt zahlreiche unabhängige Implementierungen
- Linux-Dateisysteme wie overlayfs, btrfs und ZFS werden genutzt, um Copy-on-Write-Schichten effizient zu snapshotten und zu klonen
- Unterstützt wird außerdem Lazy Pulling von Images über den
stargz-Storage-Snapshotter
Container-Instanzen
- Beim Aufruf von
docker run werden Systemressourcen zugewiesen, um aus einem OCI-Image einen per Namespace isolierten Prozess („Container“) zu erzeugen
containerd richtet die für jeden Container nötigen Namespaces dynamisch ein und übernimmt dabei folgende Aufgaben:
- Definition von Prozess-cgroups (Control Groups) für Ressourcenisolierung und I/O-Drosselung
- Remapping lokaler Netzwerkports im Container auf extern freigegebene Ports der Host-Schnittstelle
- Anbindung mutierbarer Storage-Volumes des Host-Dateisystems für einen persistenten Anwendungszustand
- Isolierung des Prozessbaums des Containers über einen PID-Namespace
- Abbildung lokaler UIDs im Container auf andere UIDs des Hosts über einen User-Namespace (z. B. UID 1000 im Container → UID 12345 oder 23456 auf dem Host)
- Das Einrichten von Namespaces verursacht etwas Overhead, ist aber deutlich leichter als das Starten einer vollständigen Linux-VM und dauert meist weniger als eine Sekunde
- Der Linux-Kernel garbage-collected beendete Container wie gewöhnliche Prozesse
Jenseits von Linux: Unterstützung für macOS und Windows
- Dank der Client-Server-Architektur kann die CLI Befehle über eine sichere Netzwerkverbindung an entfernte Docker-Instanzen senden
- 2015 war Docker in der Linux-Entwicklung bereits breit etabliert, stieß jedoch auf eine Usability-Hürde, weil Entwickler unter macOS und Windows keine Linux-Container ausführen konnten
- Die meisten Entwickler nutzen macOS oder Windows als primäre Entwicklungsumgebung, Docker-Dateisystem-Images lassen sich jedoch nur auf einem Linux-Kernel ausführen
- Mit dem Aufstieg der Public Cloud wurde Linux zudem als Deployment-Umgebung bevorzugt
Entwicklung der Docker-for-Mac-Anwendung
- Zentrale Einschränkung: Für Entwickler, die an die Linux-Version von Docker gewöhnt sind, muss es ohne zusätzliche Konfiguration funktionieren und dieselben Docker-Images ausführen können
- Der bisherige Ansatz (Linux separat neben dem Desktop-OS ausführen) wurde umgedreht: Der Hypervisor wurde in eine User-Space-App auf macOS/Windows eingebettet, in der dann Linux läuft
- Inspiration aus der Unikernel-Forschung: Sie zeigte, dass sich OS-Komponenten flexibel in größere Anwendungen einbetten lassen
- HyperKit: eine Library-VMM, die mit den Hardware-Virtualisierungserweiterungen von Intel-CPUs einen Linux-Kernel in einem normalen User-Prozess ausführt
- Der eingebettete Linux-Kernel führt den Docker-Daemon aus, der die Container verwaltet und als normaler Docker-Server-Endpunkt dient
- Alle Details der Linux-Verwaltung sind in der Desktop-App verborgen →
docker build und docker run auf dem Desktop werden an die eingebettete Linux-Instanz weitergeleitet und „funktionieren einfach“
- Dieser Ansatz wurde auch von anderen Containersystemen wie Podman übernommen und hat sich als Standardmethode für das Ausführen von Containern auf macOS/Windows etabliert
LinuxKit: eingebettete benutzerdefinierte Linux-Distribution
- Eine benutzerdefinierte Linux-Distribution, die nicht als eigenständiges System gedacht ist, sondern als Komponente in andere Apps eingebettet wird
- Aufbau eines benutzerdefinierten User Space, der nur die minimalen Komponenten enthält, die zum Ausführen von Docker-Containern nötig sind, um die Startzeit der App zu minimieren
- Jede einzelne Komponente läuft in einem Container, sodass im beim Booten verwendeten Root-Namespace gar nichts direkt läuft
- Nutzung derselben Copy-on-Write-Dateisysteme und Netzwerk-Namespaces, die auch Docker-Container verwenden
- Mit der Kombination aus LinuxKit + HyperKit lassen sich Linux-Prozesse mit nahezu derselben Geschwindigkeit wie native macOS-Prozesse starten
- 2016 als Docker-for-Mac- und Windows-App veröffentlicht
Netzwerkprobleme und die SLIRP-Lösung
- Netzwerkverbindungen von eingebetteten Linux-Containern zu macOS/Windows erwiesen sich als unerwartet schwieriges Problem
- Das bestehende Ethernet-Bridge-Verfahren erforderte komplexes Netzwerkmanagement, und Firewalls sowie Virenscanner auf Unternehmens-Desktops stuften den Verkehr als potenziell bösartig ein, was bei Beta-Nutzern Tausende Bugreports auslöste
- SLIRP als Lösung: ein Tool, das Mitte der 1990er erstmals genutzt wurde, um Palm-Pilot-PDAs mit dem Internet zu verbinden
- Beim TCP-Handshake des Containers werden Ethernet-Frames per Shared Memory über das virtio-Protokoll an den Host übertragen
- Mithilfe von Unikernel-Bibliotheken aus MirageOS werden Linux-Netzwerkanfragen in native Socket-Calls von macOS/Windows übersetzt
- Der in OCaml geschriebene User-Space-TCP/IP-Stack vpnkit nimmt sie auf dem Host-OS entgegen und ruft den macOS-
connect()-Syscall auf
- Aus Sicht von VPN-Richtlinien wird ausgehender Traffic nicht als von einer separaten Maschine kommend erkannt, sondern als vom Docker-App erzeugt
- Nach der Einführung von vpnkit in den Betatests 2016 gingen die Bugreports von Unternehmensnutzern um mehr als 99 % zurück
- Der SLIRP-Ansatz wurde später auch im Bereich serverloser Cloud-Dienste übernommen; eine alte Dial-up-Netzwerktechnik half dabei, neue Probleme der Containerverwaltung zu lösen
Verarbeitung eingehenden Netzwerk-Traffics
- Wenn ein Linux-Container auf einen Port lauscht, wird er nicht automatisch ins Internet exponiert, sofern dies nicht explizit in der CLI angefordert wird (z. B.
docker run -p 80:80 nginx)
- Ideale User Experience: Der Container-Port erscheint direkt auf der Desktop-IP und ist im Browser unter
http://localhost:8080 erreichbar
- Bestehende Desktop-Virtualisierung wie VMware Fusion legte statt
localhost eine temporäre Zwischen-IP offen
- Installation eines benutzerdefinierten eBPF-Programms im LinuxKit-Kernel → löst die Erstellung eines passenden Listening-Sockets auf dem Desktop-Host aus → aktiviert den Port-Forwarder
- Ergebnis: Läuft ein Linux-Container auf dem Mac, ist er sofort über
localhost erreichbar – mit derselben Developer Experience wie auf einer nativen Linux-Maschine
Storage
- Entwickler müssen Code lokal bearbeiten und dabei Code und Tests im Container ausführen können
- Unter Linux ermöglicht
docker run -v /host:/container per Bind Mount direkten Live-Zugriff auf Dateien
- Auf macOS und Windows funktioniert das wegen der unterschiedlichen Kernel nicht
- Docker nutzt das aus dem KVM-Hypervisor stammende Shared-Memory-Protokoll virtio-fs, um Dateisystemoperationen an den Host zu übertragen (im Format von FUSE-Anfragen)
- Der Host empfängt diese Anfragen und ruft die entsprechenden
open-, read- und write-Syscalls auf
- Code und Daten des Entwicklers bleiben im Host-Dateisystem erhalten und sind dadurch für Backup- und Suchtools wie Apples Time Capsule oder Spotlight zugänglich
Windows Services for Linux (WSL)
- 2017 veröffentlichte Microsoft WSL: Linux-Apps direkt unter Windows ausführen
- Die erste Version verfolgte statt Virtualisierung einen Library-OS-Ansatz, bei dem Syscalls von Linux-Binärdateien dynamisch in Windows-Systemaufrufe übersetzt wurden
- Für viele Apps war das erfolgreich, doch zum Ausführen von Docker-Containern fehlten unterstützte Syscalls
- 2018 erschien WSL2: neu konzipiert, um ähnlich wie Docker for Mac im Hintergrund eine vollständige Linux-VM auszuführen
- Docker unter WSL2 führt Daemon und User-Container innerhalb einer LinuxKit-WSL-Distribution aus
- Docker-API und Netzwerk-Port-Forwarding werden für Windows selbst und andere Linux-Distributionen verarbeitet
- Die Schlüsselarchitektur, die die plattformübergreifende Entwicklung von Docker-Containern ermöglichte: ein Library-OS-Ansatz, bei dem traditionell „nur für den Kernel bestimmter Code“ als User-Space-Bibliothek wiederverwendet und in andere Apps eingebettet wird
- Der Erfolg dieser Architektur zeigt sich darin, dass sie unsichtbar und allgegenwärtig ist: Millionen Entwickler nutzen Docker täglich, ohne sich darum zu kümmern, auf welchem OS es gerade läuft
Neuer Developer-Workflow: mehrere CPU-Architekturen
- In der Anfangszeit von Docker basierten die meisten Cloud-Workloads auf der Intel-Architektur
- Mit dem Erscheinen der Amazon-Graviton-ARM-Prozessoren 2018 und der Apple-M1-ARM-CPU 2020 änderte sich die Lage
- Workloads auf ARM können Kosten senken und die Performance verbessern
- Es wurde notwendig, innerhalb desselben Docker-Images mehrere CPU-Architekturen wie Intel, ARM, POWER und RISC-V zu unterstützen
- Serverseitig wurde das OCI-Image-Format um Multiarch-Manifeste (multiarch manifests) erweitert
- Für das Bauen von Images für mehrere CPU-Architekturen auf einem einzelnen Host kommt die Linux-Funktion
binfmt_misc zum Einsatz
- QEMU ermöglicht dabei die transparente Übersetzung zwischen ARM- und Intel-Binaries
- Der Overhead fällt hauptsächlich nur in der Build-Phase an; das resultierende Multiarch-Image läuft auf jedem Host nativ
- Apple führte mit Rosetta Hardware- und Software-Unterstützung für die Übersetzung von CPU-Befehlssätzen ein → ließ sich leicht in die Docker-Architektur integrieren
- Heute ist es ein gängiger Developer-Workflow, Intel- und ARM-Container nebeneinander auszuführen
Geheimnisverwaltung mit Trusted Execution Environments (TEE)
- Die Verwaltung von Secrets wie Passwörtern oder API-Keys in Container-Umgebungen ist immer eine Herausforderung
- Sie müssen dynamisch eingespeist werden, statt in das Filesystem-Image eingebacken zu sein
- Docker unterstützt Socket-Forwarding, sodass lokale Domain-Sockets in Container gemountet werden können
- Bei Docker for Mac/Windows erfolgt das Socket-Forwarding bis in die Linux-VM
- Schlüsselverwaltungssysteme wie
ssh-agent können im Container genutzt werden, ohne die Schlüssel direkt offenzulegen
- Socket-Forwarding bietet ein grundlegendes Schutzniveau, doch gegen Malware in der wachsenden Software-Lieferkette sind weitere Verteidigungsebenen nötig
- Hypervisor-Schutz wird direkt in die Container-Runtime integriert, um das Schutzniveau zwischen Containern zu verbessern
- Trusted Execution Environments (TEE): Hardware-Funktionen moderner CPUs ermöglichen die Erstellung von „Confidential VMs“, die Secrets selbst vor dem Host-OS schützen
- Beschränkungen beim Datenzugriff lassen sich über die Grenzen von App, Kernel und Hypervisor hinweg durchsetzen
- Die Konfiguration und Nutzung von TEEs bringt jedoch eine administrative Komplexität mit sich, ähnlich wie bei OS-Virtualisierung
- Die Arbeitsgruppe Confidential Containers entwickelt Apps, die in TEEs laufen und mit Docker verwaltet werden
- Die Docker-CLI leitet verschlüsselte Nachrichten vom lokalen Desktop-TEE über den Host bis in entfernte Cloud-TEE-Umgebungen weiter
- Entwickler können sich in sensiblen Cloud-Umgebungen authentifizieren, ohne vor Ort zu sein; Zugangsdaten werden sicher in der Desktop-Enklave gespeichert
GPGPU-Unterstützung für AI-Workloads
- Mit dem Aufkommen von AI-Workloads ist eine völlig neue Herausforderung entstanden: Machine-Learning-Workloads laufen größtenteils auf GPUs
- Das Kernproblem: GPU-Workloads benötigen exakt passende Kernel-GPU-Treiber und User-Space-Bibliotheken, während mehrere Container auf einem gemeinsam genutzten Kernel laufen
- Wenn zwei Apps unterschiedliche Versionen desselben Kernel-GPU-Treibers verlangen, entsteht derselbe grundlegende Konflikt, den Docker ursprünglich lösen wollte
- Seit März 2023 unterstützt Docker CDI (Container Device Interface)
- Dabei wird das Filesystem-Image beim Start des Containers angepasst
- GPU-Device-Files und GPU-spezifische dynamische Bibliotheken werden per Bind-Mount eingebunden und der
ld.so-Cache neu erzeugt
- CDI stellt die Portabilität von Images zwischen bestimmten GPU-Klassen und -Anbietern sicher, ist zwischen verschiedenen OS- und Hardware-Marken jedoch nicht vollständig nahtlos
- Die von CDI hinzugefügten dynamischen Bibliotheken definieren unterschiedliche APIs, daher gibt es nichts Vergleichbares zur stabilen Linux-System-Call-ABI als traditioneller Schnittstelle des Containers
- Warum Apps für Nvidia-GPUs schwer auf Apple-M-Series-CPUs laufen: Die Unterstützung für GPU-Virtualisierung ist noch nicht so ausgereift, dass Vektorbefehle zwischen unterschiedlicher Hardware übersetzt werden können
- Gemeinsam mit der Container-Community und GPU-Herstellern wird an flexibleren und sichereren Methoden zur Verwaltung GPU-bezogener Abhängigkeiten gearbeitet
- Es besteht die Hoffnung, dass die Initiative für portable Schnittstellen zu einem Konsens kommt
Fazit
- Docker startete 2013 mit dem Ziel, Entwicklern das Bauen, Teilen und Ausführen von Apps zu erleichtern
- Heute ist es tief in standardmäßige Cloud- und Desktop-Entwicklungs-Workflows integriert, wird täglich von Millionen Entwicklern weltweit genutzt und verarbeitet monatlich Milliarden von Requests
- Ein beständiges Ziel war der Erhalt einer aktiven und vielfältigen Open-Source-Community, die Standards für Interoperabilität aufbaut
- Die CNCF (Cloud Native Computing Foundation) fungiert als Hüterin vieler zentraler Komponenten
- Die Open Container Initiative (Teil der Linux Foundation) ist Hüterin des Image-Formats
- Heute gibt es viele aktive Implementierungen dieser Elemente, und die Verbreitung nimmt in Edge-Umgebungen wie Cloud, Desktop sowie Automobilen, Mobilgeräten und Raumfahrzeugen zu
- Der typische Entwickler-Workflow im Jahr 2025 integriert Continuous Testing und Deployment, IDE-Sprachserver sowie AI-Unterstützung durch agentisches Coding
- Aus Docker-Sicht ist der zentrale „Build-and-Run“-Workflow dem von vor zehn Jahren sehr ähnlich geblieben, doch die Systemunterstützung zur Verringerung von Reibung in unterschiedlichen Umgebungen wurde stark ausgebaut
- Ziel ist es, Docker zu einem unsichtbaren Begleiter zu machen, der Entwicklern hilft, Code schneller auszuliefern, und der für moderne AI-Coding-Workflows skalierbar ausgelegt ist
1 Kommentare
Hacker-News-Kommentare
Als Docker zum ersten Mal erschien, war ich schon genervt davon, wieder von einer weiteren „Innovation“ zu hören
Ich mochte weder halbfertiges NoSQL noch dogmatische Microservices noch den Trend, jeden Funktionsaufruf in RPC zu verwandeln
Heute nutze ich es aber wegen seiner Einfachheit häufig
Container anderer Leute bleiben allerdings die Hölle. Ich versuche zumindest, alles einfach zu halten, aber manche packen so viel hinein, dass es wirkt, als wüssten sie selbst nicht mehr, wie der Deployment-Prozess funktioniert
Inzwischen scheint dank LLMs die Zeit angebrochen zu sein, in der massenhaft Code entsteht, den Entwickler nie selbst angesehen haben
Dass sich am Ende aus so vielen Versuchen gerade das Dockerfile durchgesetzt hat, liegt an seiner Flexibilität
Die Struktur, Dateien zu kopieren und Befehle auszuführen, war aus bestehenden Betriebsweisen vertraut
Es wirkt zwar grob, aber diese einfache Flexibilität wird wohl auch künftig Mainstream bleiben
Wenn alle Nix oder Bazel nutzen würden, wäre
docker buildvielleicht zur Lachnummer gewordenWenn sich Hashes zwischen verschiedenen Builds unterscheiden, sind sie nicht vertrauenswürdig; solange Dinge wie Datei-Änderungszeiten in den Hash einfließen, ist vollständige Konsistenz schwer zu erreichen
Ich persönlich mag mkosi, aber nicht jeder will mit einem leeren OS-Template anfangen
In den meisten Fällen zieht man aus einer public registry und pusht nur in eine private registry, deshalb werden lokale Images fast nie verwendet
Das ist etwas ineffizient, aber offenbar nicht lästig genug, um es zu ändern
Ich erinnere mich daran, wie Docker 2013 auf der PyCon US in Santa Clara erstmals vorgestellt wurde
Wenn man sich das damalige YouTube-Vortragsvideo ansieht, ist das ein historischer Moment
Es scheint Verwirrung gegeben zu haben, weil der Veröffentlichungszeitpunkt des Papers und der tatsächliche Vortrag auseinanderlagen, aber es ist grob 13 Jahre her
„A decade of Docker“ klang natürlicher als „Twelve years of Docker containers“
Ich erinnere mich an den frühen HN-Post zur Ankündigung
Damals war ich Alternativen wie LXC oder Vagrant leid, und Docker wirkte wirklich wie ein Retter
Ich finde es interessant, dass Docker zum Umgehen von Firewalls ein Einwahl-Tool aus den 1990ern namens SLIRP wiederverwendet hat
Eingehende Verbindungen gingen zwar nicht, aber das Konzept war eine Art Vorläufer von NAT
Ich wollte Docker gern nutzen, aber jedes Mal fehlte eine Funktion, die ich brauchte
Vermutlich lag das daran, dass ich einen eher ungewöhnlichen Tech-Stack verwende
Dass Docker aus „läuft auf meinem Rechner“ einen Industriestandard gemacht hat, ist seine eigentliche Größe
Heute sind wir an dem Punkt, an dem gleich dieser Rechner selbst in Produktion „ausgeliefert“ wird
Früher war Deployment ein riesiger Prozess, heute kann man direkt ein Dateisystem deployen
Die aktuelle Revolution der Coding Agents fühlt sich nach einem ähnlichen kulturellen Wandel an
Wenn sich eine Umgebung mit einem 10-Zeilen-Skript reproduzieren lässt, ist „eine Maschine deployen“ gar keine so schlechte Idee
Man sollte sich fragen, warum dieser Ansatz so attraktiv ist
Abstraktion gewinnt immer, weil es zu schwierig ist, das eigentliche Grundproblem zu beheben
Ich kenne mich mit Networking nicht besonders aus, aber auf dem Mac hätte ich gern, dass Container eine eigene IP-Adresse bekommen
Ich möchte ohne Port-Mapping über
container_ip:80darauf zugreifenUnter Linux ging das, auf dem Mac ist es wegen des VM-Zwischenschritts kompliziert
Ich habe eine WireGuard-basierte Methode ausprobiert, aber die geht nach Docker-Updates immer wieder kaputt
Eine offiziell unterstützte Lösung wäre schön
Die Tailscale Docker Extension übernimmt die Einrichtung automatisch
Wenn du Port-Mapping wegen dynamischer Ports vermeiden willst, probiere die Option
--net=hostund aktiviere Host Networking2013 war ein außergewöhnliches Jahr für Packaging: Docker, Guix und NixOS kamen alle in diesem Jahr auf
Beim Schreiben des zugehörigen Papers ist mir das aufgefallen
Ich frage mich, ob es danach noch einmal ein Jahr gab, in dem so viele großartige Projekte gleichzeitig erschienen sind
Guix und Nix sind weiterhin eher bei einer kleinen Nutzergruppe geblieben
Mit ML und AI überall wachsen Image-Größen exponentiell
Allein torch bringt schon mehrere GB mit
Ich vermisse die alten 30-MB-Images
Da Dateien zwischen Layern nicht gemeinsam genutzt werden, ist die Verschwendung enorm
Deshalb baue ich gerade selbst eine alternative Registry, die Deduplizierung auf Dateiebene unterstützt
Dass Docker sich als VPN tarnte, um unternehmensweite Sicherheitssoftware auszutricksen, fand ich wirklich faszinierend
Auch als Technikgeschichte ist das ein spannender Fall