Container erobern Stück für Stück den IT-Markt, und immer mehr Entwickler stehen vor der Herausforderung, die eigene Anwendung sinnvoll in einen Container zu verpacken. Wir zeigen, was es in Sachen Handling und Sicherheit zu beachten gilt, und präsentieren sinnvolle Möglichkeiten, eine eigene Registry zu hosten.
Auch wenn es manchen Administratoren und Entwicklern nicht schmecken mag: Container sind noch immer auf dem Vormarsch. Seit Jahren weist das Linux-Magazin darauf hin, dass insbesondere die großen Distributoren wie Red Hat und Suse absehbar schon deshalb auf Container setzen werden, weil es ihnen viel Arbeit erspart. Red Hat beispielsweise muss eigene Software in Container-Form nur einmal pflegen, um sie auf RHEL 7, 8 und 9 verfügbar zu machen.
Solange auf einem System eine Laufzeitumgebung für den Betrieb von Containern zur Verfügung steht, spielt das Betriebssystem darunter kaum eine Rolle. Auch im Hinblick auf jene Software, die die großen Distributoren nicht selbst im Portfolio haben, bieten Container eine sehr angenehme technische Alternative: Während Red Hat im Augenblick etwa noch MariaDB oder MySQL in verschiedenen Versionen für seine Enterprise-Distributionen pflegt, wird man künftig einfach auf die offiziellen Container-Abbilder der jeweiligen Hersteller verweisen und sich die Arbeit selbst gar nicht mehr antun.
Beim Desktop lässt sich dieser Effekt bereits erkennen. Kürzlich erst gab Fedora bekannt, LibreOffice selbst gar nicht mehr in Paketform pflegen zu wollen, sondern die eigene Nutzerschaft auf die offiziellen LibreOffice-Flatpaks zu verweisen. Die sind im Kern auch nichts anderes als Container, und zwar solche, um die Red Hat sich selbst nicht kümmern muss. Wie das Thema weitergeht, kann man sich leicht ausmalen.
Von der beschriebenen Vorgehensweise profitieren allerdings nicht nur die Hersteller. Auch und gerade die Entwickler kleinerer Anwendungen haben dank des Container-Formats die Möglichkeit, ihre eigenen Anwendungen schnell und unkompliziert an die Benutzer auszuliefern. Mit lästigen Details wie Paketmanagern und unterschiedlichen Paketen für unterschiedliche Versionen einer Distribution müssen auch sie sich dann nicht mehr herumschlagen. Verlockend ist das Thema insofern allemal.
Fragen über Fragen
Allerdings steht mancher Entwickler, der zum ersten Mal seine eigene Anwendung in einen Container verpacken möchte, wie der sprichwörtliche Ochse vor dem Berg. Administratoren, die mit Containern bis dato noch nicht viel Erfahrung hatten, geht es ähnlich, wenn sie kleine Werkzeuge für den Eigenbedarf in Container-Form bringen und lokal ausliefern möchten. Die Fragen, die im Raum stehen, sind dabei stets dieselben: Wie werden aus den als Tarball vorliegenden Quellen eines Programms Docker-Container, die man per Docker Hub ausliefern kann? Gibt es praktische CI/CD-Werkzeuge, die nicht nur den Container-Bau erleichtern, sondern auch professionalisieren und automatisch Fehler finden? Und ist es überhaupt eine gute Idee, Docker Hub zu nutzen, oder wäre eine lokale Registry speziell für lokale Abbilder nicht eigentlich eine bessere Idee?
Interessierte stellen schnell fest: Zwar lässt sich das benötigte Wissen in mühseliger Kleinstarbeit über Google zusammensuchen, doch das dauert lange, und Spaß macht es auch keinen. Dieser Artikel eilt zur Hilfe: Neben den Basics des Image-Baus kommen Best Practices und CI/CD-Mechanismen ebenso zur Sprache wie die Frage nach einer guten Image-Registry in Eigenregie. So viel sei vorab schon verraten: Ganz so komplex, wie viele Kritiker vermuten und behaupten, ist das Thema gar nicht.
Das ist nicht zuletzt den Docker-Entwicklern selbst zu verdanken. Die haben mit Docker von Anfang an die nötigen Werkzeuge ausgeliefert, um lokale Container-Abbilder zu erstellen und zu verteilen. Erfreulicherweise haben sie sich dazu weder eine komplizierte Syntax noch ein ganz neues Format für die Metadaten des zu bauenden Abbilds überlegt. Um schnell das erste eigene Abbild an den Start zu bringen, genügt ein lokaler Ordner auf einem Linux-System mit einigen Grundwerkzeugen und einer installierten Laufzeitumgebung für Docker.
Vorbereitungen
Im Klartext bedeutet das, dass vor dem eigentlichen Image-Bau zunächst ein paar Vorbereitungen auf dem Bausystem anstehen. Dazu kann durchaus der eigene Computer herhalten. In Unternehmen, die viele Abbilder bauen, hat sich in den vergangenen Jahren aber der Brauch eingebürgert, das auf einem eigens dafür präparierten System zu erledigen. Das muss kein echtes Blech sein, eine virtuelle Instanz genügt völlig. Spätestens, wenn eine CI/CD-Toolchain ins Spiel kommt, findet der Bauvorgang ohnehin nicht mehr auf dem lokalen System statt, wohl aber die Entwicklung des Abbilds inklusive eventuell nötiger Testläufe. Hier entscheidet letztlich die Präferenz des Entwicklers über das gewünschte Vorgehen.
Die generelle Vorgehensweise, um ein neues Abbild aus dem Boden zu stampfen, ist gänzlich unabhängig von den persönlichen Präferenzen. Docker selbst liefert wie beschrieben die Baufunktionalität als Teil von »docker« aus. Um sie zu nutzen, muss Docker aber auf dem lokalen System installiert sein. Der erste Schritt besteht folglich darin, die Community-Edition von Docker lokal einzurichten. Das folgende Beispiel geht von einem System mit Ubuntu 22.04 aus.
Dafür installieren Sie zunächst einige benötigte Pakete zur Softwareverwaltung (Listing 1, erste Zeile). Dann laden Sie den GPG-Schlüssel herunter, mit dem die Paketlisten von Docker signiert sind (Zeile 2). Nur mit diesem Schlüssel kann Apt sicherstellen, dass die Pakete aus einer zuverlässigen Quelle kommen. Nun fügen Sie die Paketquellen für Docker in die lokale Liste der Paketverzeichnisse ein (Zeile 3) und aktualisieren dann den lokalen Paket-Cache (Zeile 4). Zu guter Letzt holen Sie via Apt die Community-Edition von Docker auf das System (Zeile 5). Ein Aufruf von Systemctl (Zeile 6) sollte im Anschluss »active« als Status für »docker.service« anzeigen. Ist das der Fall, war die Installation erfolgreich, und die für den Image-Bau nötigen Befehle liegen lokal vor.
Listing 1
Docker-Umgebung
$ sudo apt install apt-transport-https ca-certificates curl softwareproperties-common $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg $ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null $ sudo apt update $ sudo apt install docker-ce $ sudo systemctl status docker
Wüst und leer
Beim Bau von Docker-Abbildern starten Sie mit einem Arbeitsverzeichnis, das zwar nicht wüst ist, wohl aber leer. Als ersten Schritt legen Sie nun zum Beispiel mit »mkdir nginx« einen neuen Ordner an. Der bleibt nicht lange leer, denn schon im nächsten Schritt legen Sie mit »touch .dockerignore« darin eine Datei an, die später als Ausschlussliste für Dateien dient, die Docker beim Bau des Abbilds nicht zu beachten braucht.
Der weitere Verlauf gestaltet sich dann etwas komplizierter und setzt vor allem ein wenig Wissen rund um Docker-Abbilder voraus. Ganz grundsätzlich haben Sie an dieser Stelle mehrere Möglichkeiten. Sie können entweder ein fertiges Base-Image für Ihr eigenes Abbild nutzen oder sich dieses selbst bauen.
Zur Erinnerung: Ein laufender Container auf einem System enthält ja erst einmal nur ein Dateisystem, das der Linux-Kernel über verschiedene Funktionen (Namespaces, Cgroups) in einen quasi-abgetrennten Bereich des Systems verfrachtet und dort betreibt. Anders als die Virtualisierung im Voll- oder Paravirtualisierungsmodus benötigt ein Docker-Abbild keinen eigenen Kernel. Es muss aber sehr wohl alle Dateien enthalten, die das gewünschte Programm zum Funktionieren benötigt, denn das normale Dateisystem des Hosts ist für den laufenden Container später grundsätzlich tabu.
Über Bind-Mounts und Volumes lässt sich diese Sperre zwar aufweichen. Trotzdem würde man den Container aber stets so bauen, dass er keine Abhängigkeiten zu außerhalb gespeicherter Software aufweist. Ein Docker Image ist, so die Prämisse, stets self-contained, hat also keine Abhängigkeiten zur Außenwelt.
Praktisch jedes Docker-Abbild enthält deshalb ein einigermaßen komplettes Dateisystem eines lauffähigen Linux-Systems. Wie komplett, das hängt stark von der Anwendung und ihren Abhängigkeiten ab. Mancher Entwickler greift hier intuitiv zu Tools wie Debootstrap und bastelt sich sein Grundsystem selbst. Eine sonderlich gute Idee ist das aber nicht: Selbst eine Grundinstallation von Debian oder Ubuntu enthält heute viel mehr, als man für einen Container tatsächlich benötigt. Hinzu kommt, dass es komplett selbst gebaute Abbilder auch komplett selbst zu pflegen gilt. Je nach Situation bedeutet das einen erheblichen Aufwand.
Allerdings hat man das Problem bei Docker kommen sehen und mittels eines Tricks praktisch Abhilfe geschaffen. Statt den gesamten Inhalt des Container-Abbilds lokal vorzuhalten, beherrscht Docker beim Image-Bau den Befehl »FROM«. Der verwendet ein öffentliches Image von Docker Hub als Grundlage für das zu erstellende Abbild und fügt lediglich die vom Entwickler erbetenen Komponenten hinzu.
Alle großen Distributoren pflegen eigene Mikroabbilder für den Container-Bau ihrer eigenen Distribution und stellen diese auf Docker Hub zur Verfügung. Für RHEL, Suse, Ubuntu, Debian, Arch Linux und das besonders schlanke, weil für den Container-Betrieb optimierte Alpine Linux gilt gleichermaßen: Die Distributoren sind sehr gut darin, Kleinstabbilder der eigenen Distribution zu bauen, und können das viel effizienter erledigen als der unerfahrene Endanwender.
Zudem pflegen sie ihre Abbilder regelmäßig. Kommt eine neue Version eines Basisabbilds heraus, genügt es, das eigene Image auf Grundlage des neuen Abbilds ebenfalls neu zu bauen, um Problemen in Sachen Sicherheit oder Funktionalität den Garaus zu machen. Ein praktischer Nebeneffekt besteht darin, dass das lokale Arbeitsverzeichnis für den Abbildbau übersichtlich und sauber bleibt.
Hier kommt eine weitere angenehme Eigenschaft des Container-Baus zum Tragen: Während des Baus lassen sich durch den »CMD«-Befehl Anweisungen ausführen, die beispielsweise zusätzliche Pakete in das Basisabbild des Distributors installieren. Der Inhalt, den der Entwickler für seine eigene Anwendung beisteuern muss, beschränkt sich deshalb im Regelfall auf die Anwendung selbst sowie deren Dateien. Hinzu kommen lediglich Abhängigkeiten, die für das genutzte Basisabbild nicht in paketierter Form zur Verfügung stehen.
Ein konkretes Beispiel
Nach so viel Theorie geht es nun zur Sache: Der Bau des ersten Containers steht an. Das folgende Beispiel ist bewusst möglichst einfach gehalten. Es beschreibt den Bau eines Containers auf Grundlage eines Ubuntu 22.04 (Abbildung 1), auf dem Nginx läuft, wobei der Webserver eine einfache HTML-Seite ausliefert. Die in Listing 2 gezeigte Datei namens »Dockerfile« ist eine der beiden erforderlichen Grundzutaten. Alten Container-Hasen erscheint der Inhalt wenig spektakulär. Wer allerdings noch keinen Container gebaut hat, fragt sich möglicherweise, was die einzelnen Befehle tun.

Abbildung 1: Es empfiehlt sich, für den Container-Bau ein fertiges Basis-Image einer der großen Distributoren zu verwenden. Nur selten bekommen Einsteiger schlankere Abbilder hin, ohne einen Teil der Funktionalität zu beeinträchtigen.
Listing 2
Dockerfile für Nginx
# Pull the minimal Ubuntu image FROM ubuntu # Install Nginx RUN apt-get -y update && apt-get -y install nginx # Copy the Nginx config COPY default /etc/nginx/sites-available/default # Expose the port for access EXPOSE 80/tcp # Run the Nginx server CMD ["/usr/sbin/nginx", "-g", "daemon off;"]
»FROM« ist der bereits erwähnte Verweis auf ein Basisabbild eines Anbieters, in diesem Fall Ubuntu. Bevorzugen Sie eine spezifische Version, geben Sie diese hinter einem Doppelpunkt an, beispielsweise »:22.04«. Das »RUN«-Kommando leitet einen Befehl ein, den Docker beim Bauen innerhalb des heruntergeladenen Basisabbilds ausführt. Im Beispiel installiert er das Paket nginx. »COPY« kopiert eine Datei aus dem lokalen Ordner an die angegebene Stelle im Abbild. Das Beispiel setzt also voraus, dass es im Bauordner eine Datei namens »default« gibt, die im Abbild später in der Site-Konfiguration von Nginx liegt (Listing 3).
Listing 3
Datei default
server {
listen 80 default_server;
listen [::]:80 default_server;
root /usr/share/nginx/html;
index index.html index.htm;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
»EXPOSE« weist die Laufzeitumgebung an, den Port 80 des laufenden Containers zur Außenwelt hin zu exponieren, um einen Zugriff zu ermöglichen. Bei »CMD« handelt es sich um den Befehl, den Docker aufruft, um den Container zu starten. Im Beispiel ruft er Nginx mit deaktiviertem Daemon-Modus auf, damit »stdout« offen bleibt. Anderenfalls würde die Laufzeitumgebung den Container sofort wieder beenden.
Danach geht es an den Bau des eigentlichen Abbilds. Das Kommando aus der ersten Zeile von Listing 4 stößt den Prozess an. Sie rufen es direkt aus dem Bauverzeichnis heraus auf. Danach findet sich in der lokalen Docker-Registry das fertige Abbild, das Sie im nächsten Schritt probehalber starten (zweite Zeile). Zeigt »docker ps« danach den Nginx-Container an, war der Paketbau erfolgreich (Abbildung 2).
Listing 4
Probelauf
$ docker build . -t lm-beispiel/nginx $ docker run -d -p 80:80 lm-beispiel/nginx
Abbildung 2: Hat der Bauvorgang funktioniert, lässt sich der Container aus unserem Beispiel starten und erzeugt eine laufende Nginx-Instanz. Quelle: Haidar Ali
Mehr Spaß mit CI/CD
Zugegeben: Das dargestellte Beispiel ist unspektakulär und lässt viele Möglichkeiten des Paketbaus ebenso außen vor wie Möglichkeiten, Nginx in einer komplexeren Konfiguration zu betreiben. Im echten Leben benötigt eine Nginx-Instanz beispielsweise stets ein SSL-Zertifikat samt dazugehörendem Schlüssel.
Der übliche Weg, das Problem in Docker zu lösen, besteht darin, dem Container zur Laufzeit ein Volume unterzujubeln, auf dem die jeweiligen Dateien liegen. Damit das wie gewollt funktioniert, muss man Nginx im Container jedoch entsprechend vorkonfigurieren. Das kann durch eine statische Konfiguration geschehen, wozu man allerdings das Dockerfile entsprechend ändern müsste. Alternativ lassen sich entsprechende Parameter über Variablen in der Shell-Umgebung übergeben, aus der heraus der Administrator den Container startet. Im Dockerfile würde der Entwickler dann mittels »ENV«-Anweisung die Variable definieren und in der Datei selbst über »$VARIABLE« darauf zugreifen.
Das alles kann jedoch nicht darüber hinwegtäuschen, dass das beschriebene Beispiel recht rudimentär ausfällt. Im Alltag wird man gerade bei komplexeren Anwendungen kaum mit so wenigen Befehlen auskommen – und von den Problemen, die sich aus der Pflege eines Abbilds ergeben, ist dabei noch gar nicht die Rede. Denn das wie beschrieben gebaute Image wurde ja beispielsweise noch nicht veröffentlicht. Etwaige Tests, die automatisiert die Funktionalität des Abbilds prüfen, sind bis dato ebenfalls nicht vorgesehen.
All das lässt sich allerdings relativ flott ändern. Das Zauberwort heißt Continuous Integration and Continuous Development, üblicherweise als CI/CD abgekürzt. Gemeint ist, dass der eigentliche Bau des Abbilds sowie eventuelle Tests automatisiert und standardisiert erfolgen. Der Entwickler eines Abbilds checkt, wenn er das Abbild neu bauen möchte, beispielsweise nur noch eine neue Version des Dockerfiles in Git ein, das den Rest automatisch abwickelt. Am Ende steht das neue Abbild auf Docker Hub automatisch zur Verfügung und lässt sich benutzen.
Allerdings geht die Anzahl der fertigen CI/CD-Lösungen für Docker mittlerweile praktisch gegen unendlich, nicht zuletzt, weil Kubernetes in diesem Geschäft ebenfalls eine bedeutende Rolle spielt und bekanntlich seit Jahren so etwas wie das It-Thema der gesamten IT ist. Dabei geht es dann auch nicht mehr nur um den Bau einzelner Abbilder. Ziel ist vielmehr das Erstellen kompletter Anwendungspakete, die am Ende einer CI/CD-Pipeline vollständig automatisiert ihren Weg in die Kubernetes-Zielinstanz finden und den dort laufenden Workload ohne Downtime ersetzen.
Man muss aber nicht das ganz große Rad drehen, um bei Docker Chancen auf CI/CD zu haben. Github bietet sich an: Es verfügt über eine umfassende CI/CD-Integration für Docker inklusive der Option eines automatischen Uploads fertiger Abbilder in Docker Hub.
Am Anfang steht dabei ähnlich wie im Beispiel ein beinahe leerer Arbeitsordner mit einem Dockerfile und eventuell benötigten Zusatzdateien. Ihn unterstellt der Entwickler zunächst der Versionsverwaltung Git und lädt das Repository danach auf Github hoch. Für das Verzeichnis definiert er anschließend die Umgebungsvariable »DOCKERHUB_USERNAME« sowie ein Personal Access Token (PAT) in der Variablen »DOCKERHUB_TOKEN«. Dann fügt er seinem Verzeichnis eine Aktion hinzu, die hier die Form eines gesamten Arbeitsablaufs (“Workflow”) hat. Die Datei ».github/workflows/main.yml« innerhalb des Repositories könnte beispielsweise aussehen wie in Listing 5.
Listing 5
Workflow-Konfiguration für Github
name: ci
on:
push:
branches:
- "main"
jobs:
build:
runs-on: ubuntu:22.04
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
-
name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/lm-beispiel:latest
Liegt die Datei im Verzeichnis, führt jedes Einchecken von Veränderungen in das Repository dazu, dass Github das Abbild automatisch baut und in Docker Hub mit den gegebenen Zugangsdaten eincheckt. Von dort aus kann das fertige Image dann selbst Bestandteil von CI/CD-Pipelines werden, die das Deployment beispielsweise innerhalb von Kubernetes steuern.
Wohlgemerkt: Gitlab und Github sind nur zwei von zahllosen Anbietern im Docker-Geschäft, die mit CI/CD für Docker ihre Brötchen zu verdienen versuchen. Auch der CI/CD-Klassiker Jenkins (Abbildung 3) bewegt sich unter anderem in diesem Umfeld.

Abbildung 3: Github und Gitlab bieten mittlerweile umfangreiche CI/CD-Funktionen für Docker. Auch Standardlösungen wie Jenkins versuchen an dieser Stelle zu punkten. Sie entbinden den Entwickler von der strikten Abhängigkeit von einer spezifischen Git-Lösung. Quelle: Gary Stafford
Die eigene Registry
Gitlab enthält übrigens ganz ähnliche Funktionen wie Github. Möchten Sie also bei Github kein Geld lassen, um private Repos anlegen zu können, weichen Sie stattdessen auf eine lokale Gitlab-Instanz aus. Wollen Sie außerdem Ihre Images nicht der Öffentlichkeit zur Verfügung stellen, brauchen Sie eine private Registry für Container-Abbilder.
Die zu betreiben, ist allerdings gar nicht so leicht, wie man im ersten Augenblick glaubt. Vernünftige Software für eben diese Aufgabe gab es lange nicht unter einer freien Lizenz. Mittlerweile sind jedoch mehrere Anbieter mit passenden Angeboten auf dem Markt. Einer davon ist Docker selbst. Das Kommando aus Listing 6 startet eine lokale Docker-Registry. Die Details des Kommandos sind allerdings wichtig.
Listing 6
Lokale Docker-Registry
<pre> docker service create \ --name registry \ --secret domain.crt \ --secret domain.key \ --constraint 'node.labels.registry==true' \ --mount type=bind,src=/mnt/registry,dst=/var/lib/registry \ -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/run/secrets/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/run/secrets/domain.key \ --publish published=443,target=443 \ --replicas 1 \ registry:2 <pre>
Das Beispiel geht davon aus, dass auf dem Host der Ordner »/mnt/registry/« existiert, denn der wird im laufenden Container später nach »/var/lib/registry/« eingehängt. Ferner müssen Sie auf dem Host durch Docker hindurch die Secrets »domain.crt« und »domain.key« anlegen. Das erledigen Sie mit den Kommandos aus den ersten zwei Zeilen von Listing 7, die auch den Inhalt der beiden Dateien als Passwörter in die Metadaten von Docker übernehmen. Ebenfalls noch vor dem Hinzufügen des Docker-Services müssen Sie ein Label für den Knoten erstellen, auf dem die Registry läuft (letzte Zeile).
Listing 7
Zusatzarbeiten
$ docker secret create domain.crt certs/domain.crt $ docker secret create domain.key certs/domain.key $ docker node update --label-add registry=true Hostname
Auch dieses Beispiel ist freilich wieder sehr einfach gestrickt. So fehlt etwa die Möglichkeit, den Zugang zu Abbildern über die Kombination aus Benutzername und Passwort zu sichern. Technisch wäre das durchaus kein Problem, die Docker-Dokumentation enthält dazu weitere Informationen.
Deutlich umfangreicher als der Standardweg von Docker ist der Betrieb einer Registry mit Quay (Abbildung 4). Der von Red Hat maßgeblich entwickelte Dienst kann Abbilder nicht nur an Clients ausliefern, sondern hat im Hintergrund auch umfassende CI/CD-Funktionen an Bord (Abbildung 5). Das Projekt [1] steht unter einer freien Lizenz, das Setup gestaltet sich jedoch in Summe wenig intuitiv. Die einfachste Option besteht darin, Quay in Form eines fertigen Containers in Kubernetes auszurollen.

Abbildung 4: Quay, eine Registry für Container-Abbilder, bietet neben der eigentlichen Up- und Download-Funktionalität auch statistische Daten zu einzelnen Abbildern. Quelle: Quay

Abbildung 5: Neben der Registry-Funktionalität hat Quay viel zusätzliche Technik an Bord. Dazu zählt auch eine umfangreiche CI/CD-Toolchain, die Entwickler beim Bau von Abbildern unterstützt. Quelle: Quay
Fazit: Nicht schwer
Wie unsere Beispiele zeigen, ist der Bau von Docker-Containern nicht besonders kompliziert. Und selbst der Betrieb einer eigenen Registry für Container geht alles in allem recht leicht von der Hand. Falls Sie größere Workloads auf Basis von Containern planen, müssen Sie sich früher oder später zwangsläufig mit der Frage nach dem Image-Bau beschäftigen. Verwenden Sie als Basis für die eigene Arbeit am besten ausschließlich offizielle Abbilder aus Docker Hub. Alle anderen Ansätze bergen die große Gefahr eines Blindflugs, der sich schnell zum Alptraum auswachsen kann. CI/CD-Werkzeuge helfen dabei, den heute praktisch erforderlichen Container-Bau bequemer zu gestalten. (jcb/jlu)
Infos






