Container Seminare

Container (Bild Unsplash: timelab-pro-sWOvgOOFk1g-unsplash.jpg)

Container (Bild Unsplash: timelab-pro-sWOvgOOFk1g-unsplash.jpg)

Virtualisierungen und Container nehmen in den IT-Infrastrukturen eine immer größere Bedeutung ein.

[Wer sofort mit den Seminarunterlagen loslegen will: Einführung]

Manche sprechen bei Containern von der nächsten Evolutionsstufe der Virtualisierung. Diese Seminare widmen sich der Praxis von Containern mit Docker - bzw. anderen Container-Alternativen - und wird auch technische, theoretische und sicherheitsrelevante Themen - wie z.B. für Applikationscontainer in der Softwareentwicklung - nicht vernachlässigen.

Sie werden die Administration von Docker (bzw. Containern) erlernen und den unterschiedlichen Einsatz von Containern für Projektumgebungen kennen lernen. Und natürlich werden auch die netzwerk- und sicherheitsspezifischen Aspekte nicht zu kurz kommen.

Die Techniken bieten eine große Bandbreite: von kleinen technischen Umgebungen im Rahmen von SW-Development bis zu den großen Cloud-Lösungen von Microsoft (Azure), Google (GCS) oder Amazon (AWS).

Hier eine erste, schnelle Übersicht mit den Vorzügen der Umsetzung von Techniken mit Hilfe von Containern:

Anmerkung zur folgenden AI-Recherche

Die folgenden Quellen [1] bis [5] stammen von Perplexity.ai und wurden von mir aus Gründen der Transparenz exakt belassen - meine Online-Empfehlungen stellen sie nicht dar.

Die Ausführungen in der Aufzählung müss(t)en noch präzisiert werden!

  • Effiziente Ressourcennutzung: Container sind leichtgewichtiger als virtuelle Maschinen, da sie das Betriebssystem des Hosts teilen. Dies ermöglicht eine höhere Dichte an Containern pro Server und einen geringeren Ressourcenverbrauch. [1] [2]

  • Schnelle Bereitstellung und Skalierbarkeit: Container-Images sind innerhalb von Sekunden einsatzbereit und lassen sich beliebig oft klonen, was eine schnelle Skalierung von Anwendungen ermöglicht. [4]

  • Hohe Portabilität: Container kapseln Anwendungen mit allen Abhängigkeiten, sodass sie plattformunabhängig und konsistent auf verschiedenen Systemen ausgeführt werden können. [2] [5]

  • Vereinfachte Verwaltung und Updates: Container erleichtern die Verwaltung von Anwendungen, da sie isoliert voneinander und von der Infrastruktur sind. Updates lassen sich einfach durchführen. [3]

  • Unterstützung von Microservices: Die Modularität von Containern ermöglicht die Aufteilung von Anwendungen in kleinere, unabhängige Microservices. [2] [3]

Hier das Zitat für die AI-Recherche:

„Erstelle eine 5 Punkteliste mit den Vorteilen von Container Techniken wie Docker, Podman oder Kubernetes.“

—Recherche und Quellen: Perplexity.ai

Die Umsetzungen basieren dabei oft auch auf Virtuellen Maschinen (VMs) als Basis - bzw. Host - für die Container.

Die Techniken drängen aktuell auch in die Private IT, Smart Home oder auch Homelabs Umgebungen:

  • VMs und Container auf dem NAS

  • SW-Entwicklungsumgebung per Container auf dem Raspberry Pi

  • Web-Oberflächen für das Smart-Home

Die Listen im Enterprise- und Home-Bereich ließen sich beliebig verlängern. Wir wollen uns alle relevanten Techniken an praktischen Beispielen und Vorgehensweisen erarbeiten.

Ihr Trainer Joe Brandes, Braunschweig 2024

Für einen schnelleren Überblick - in den HTML-Dokumenenten - folgt hier das Stichwortverzeichns und die Dokumentstruktur:


Stichwortverzeichnis


Willkommen zu Docker

Erste Aufrufe mit Docker Containern

Erste Aufrufe mit Docker Containern

Für den Einstieg ein paar Anmerkungen zum Begriff Docker.

Docker bzw. Firma Docker Inc.

Für die Bereitstellung von Containern gibt es diverse Alternativen (siehe zum Beispiel podman.io - Red Hat).

Ich zitiere an dieser Stelle einfach aus dem aktuellen Docker Praxisbuch von Bernd Öggl und Michael Kofler (Rheinwerk Verlag):

Langer Rede kurzer Sinn: Wir behandeln in diesem Buch sowohl Docker als auch Podman. Dennoch gilt für uns Docker als der »Goldstandard«.

—Praxisbuch Docker (2024) - Bernd Öggl und Michael Kofler (Rheinwerk Verlag)

Docker Software gibt es für nahezu alle Betriebssysteme. Und in unseren Seminaren wollen wir die OS-Implementierungen versuchen in Gänze zu erfassen.

Zur Erinnerung: Docker ist heimisch auf Linux-Plattformen!

Die Firma Docker.Inc bietet an:

  • Verschiedene (pure) Docker Engines: klassisch: docker-ce (Community) oder docker-ee (Enterprise)

    Im Seminar werden wir immer versuchen diese CE-/EE-Versionen einzusetzen. Also nicht die Versionen in den Paketmanagements der Distros (siehe docker.io Packages bei Debian/Ubuntu)

  • Verschiedene Docker Desktops für Windows, Mac und auch Linux

  • Tools: Docker Compose, Build-Tools, Extensions

  • Docker Hub - zentrale Bereitstellung und Austausch von Images

  • Docker Scout - Image Analyse und Einschätzung von Security Risks

Charakter dieser Unterlage

Manche meiner RST-Unterlagen sind im Laufe der Jahre zu kleinen Büchern gewachsen. Das möchte ich mit dieser Unterlage (eigentlich) nicht (er)schaffen. Und verschiedene Autoren haben mir/uns die Arbeit Buch ja auch schon abgenommen!

Diese Unterlage sollte eher als „Cheat Sheet und Roter Faden“ verstanden und genutzt werden!

Und jetzt viel Spaß beim Containern ;-)

Docker Inc. und Software

Docker Inc. und das Software und Leistungsangebot

Docker Inc. und das Software und Leistungsangebot

Die Übersicht beim (aktuellen) Navigationspunkt Products macht deutlich, dass es sich bei Docker nicht um eine reine Softwareschmiede für die lokale Containerisierung handelt.

Das würde bei einer Technik, die grundsätzlich auf Open Source basiert und für die es diverse kostenlose und freie Umsetzungen gibt auch kein realistisches Geschäftsmodell darstellen. Und Docker ist eben auch Docker Inc.

In Kürze: seit 2015 ist Docker eines der Gründungsmitglieder und Unterstützer der Open Container Initiative.

Mitglieder der OCI - Open Container Initiative

Mitglieder der OCI - Open Container Initiative

Somit werden also seitens Docker alle freien Container Standards unterstützt.

Dabei hat man sich mit starken Partnerschaften umgeben (AWS, Azure, JFrog) und arbeitet intensiv und erfolgreich bei der Integration von Docker Tools und Docker Images in andere Entwickler-Infrastrukturen (GitLab, GitHub, Bitbucket, Kubernetes, …).

Zentraler Softwareteil bei diesen Bemühungen ist der Docker Desktop. Wie gesagt: reine Containertechnik gäbe es zuhauf frei und insbesondere auf Linux-nativen OS (siehe: KVM/qemu, ProxmoxVE/KVM/LXC, LXD, …).

Docker Desktop

Docker versucht den Docker Desktop als erste Anlaufstelle für Entwickler und Firmen zu etablieren. Die beworbenen Vorzüge:

  • Schnell zu installieren und einzusetzen

  • einfach und sicher in Stand zu halten

  • Einfach zu skalieren - Docker Business - Info PDF Docker Business

  • Für alle relevanten Betriebssysteme verfügbar (Windows, MacOS, Linux) und einheitlich auf allen OS nutzbar.

Gerade bei der Unterstützung für das Containern (also auch Entwickeln) auf Windows hat man mit dem Docker Desktop für Windows eine erfolgreiche Software am Start.

Man kann auf Windows Systemen das WSL2 (Windows Subsystem Linux 2) als native Linux Umgebung für Container nutzen. Davor war man gezwungen auf schwergewichtigen Hyper-V-VMs zu containern. Das schloss dann zusätzlich auch noch alle Windows Home Nutzer aus.

Unter Linux kann man mit der Docker Desktop Installation sowohl den Desktop als auch die Standard Docker Engine nutzen. Man erhält über docker context ... verschiedene Umgebungen.

Docker Desktop für Linux - hier: Gnome Desktop with Debian 12

Docker Desktop für Linux - hier: Gnome Desktop with Debian 12

Ein einfaches systemctl --user start | stop docker-desktop.service schaltet zwischen Context default (Docker Engine) und desktop-linux (Docker Desktop) hin und her. Das kann allerdings auch schwer verwirren, wenn man mal Images sucht!

Aber die gleiche Umgebung unter verschiedenen Betriebssystemen beim Entwickeln von Software mit Hilfe von Docker (Desktop) Containern macht schon Sinn.

Wenn man den Docker Desktop auf virtuellen Maschinen nutzen will, dann muss man Nested Virtualization beachten, da der Docker Desktop mit einer eigenen VM arbeitet. Auf Linux VM-Technik kein Problem - auf Windows mit Hyper-V bitte einfach per PowerShell die verschachtelte Virtualisierung aktivieren: (MS Learn Portal - Enable Nested Virtualization ).

Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true

Die Installationsanleitungen für den Docker Desktop beschreiben alle ebenfalls alle notwendigen Vorbereitungen und den Einsatz von Docker Desktop Software in einer VM.

Docker Umgebungen

Docker Software gibt es für nahezu alle Betriebssysteme. Und in unseren Seminaren wollen wir die OS-Implementierungen versuchen in Gänze zu erfassen.

Operating Systems für Hosts und Container

Operating Systems für Hosts und Container (Bild Unsplash: claudio-schwarz-z508Zk08HNU-unsplash.jpg)

Besonderen Wert sollte man beim Einstieg in die Materie auf die genutzten Docker (bzw. Container) Bereitstellungen legen.

  • Hosts: beliebige OS wie Windows, MacOS und Linux

  • Container OS: Linux Container vs. Windows Container

Die natürliche Umgebung für Container-Techniken ist Linux. Das liegt nahe, da in fast allen Fällen auch Linux Container zum Einsatz kommen. Und auf Windows Systemen steht mit dem Windows Subsystem Linux (WSL / WSL2) eine windows-systeminterne Umsetzung zur Verfügung.

Hinweis

Im 1400 Seiten zweiten Container-Werk von O. Liebel sind Windows Container komplett herausgefallen und der Nano-Server findet ebenfalls nicht statt!

Wir werden uns also im Weiteren auf Linux Container konzentrieren und uns jeweils für ein Operating System nach Wahl für die Umsetzung als Container Host (oder auch Container Serverumgebung) entscheiden.

Schauen wir uns also die üblichen Verdächtigen für einen Einsatz als Docker Hosts an.

Windows

Für den Einstieg - und zur Erinnerung - ist es wieder wichtig zu unterscheiden:

  • OS für Container: Linux Container (gewünscht)

  • Host für Container-Technik: hier jetzt Windows 10 bzw. 11

Wir können also Windows als Host-System für unsere Linux Container-Umsetzungen nutzen.

Wo bekommen wir unter Windows eine Linux Maschine - einen Linux Kernel - her, den wir für die Linux Container nutzen können?

Docker Desktop für Windows mit WSL2

Ich empfehle diese Variante und verweise auf die Docker Dokumentation.

Install Docker Desktop on Windows

Install Docker Desktop on Windows

Wir starten mit der aktuell attraktivsten Docker-Kombi zur Umsetzung mit Windows.

Docker Desktop für Windows mit WSL2

Die Dockerversionen liegen für alle OS als Docker Desktop für Mac/Linux/Win vor. Das ermöglicht auf allen OS dieselben Arbeits- und Deployumgebungen. Allerdings setzt man unter Linux/MacOS im Grunde immer auf die nativen Installationen.

Hinweis

Bitte dann später Anleitungen für unterschiedliche Projekte wie Portainer beachten, die auf diese unterschiedlichen Umgebungen hinweisen!

Installarchiv für die Docker für Windows (Hyper-V) Technik am Besten über Umweg docs.docker.com

Entweder wir nutzen den Downloadlink für Docker Desktop Installer auf der Docker Dokumentation oder aber wir installieren einfach schnell über die PowerShell per winget install --id Docker.DockerDesktop.

Ich will auch kurz die alternativen Umsetzungen auf einem Windows Host darstellen.

Docker Desktop für Windows mit MobyVM

Wir bnenötigen Windows 10/11 Pro (oder Enterprise, Education) für Hyper-V mit MobyLinuxVM!

Die Nutzung des Docker Desktop unterscheidet sich nicht grundsätzlich von der WSL2-Technikkombination. Die Umsetzung ist allerdings nicht so effizient und schlank.

Hinweis

Bei dieser Technikumsetzung könnte man auch zwischen den Linux und Windows Containern switchen!

Linux VMs mit Hyper-V

Man kann sich einfach eine Linux-Distro nach Wahl im Hyper-V installieren und dann mit der gewünschten Container Technik experimentieren.

Da Container keine wirkliche Virtualisierung benötigen ist Docker in einer VM also überhaupt kein Problem! Und Hyper-V würde über das Feature ExposedVirtualization ja sogar ein sogenanntes Nested (sprich: verschachteltes) Virtualisieren erlauben!

Docker Toolbox (DEPRECATED)

Das sollte die letzte Bastion für eine Umsetzung darstellen, da wir die Techniken sehr aufwändig und ineffizient kombinieren und bereitstellen. Und es gibt ja auch in der Kombination Windows (auch Home) mit WSL2 keinen Grund mehr gegen Docker Desktop für Windows!

Achtung

Legacy Tech: Docker Toolbox - officially deprecated since late 2020: Docker Archive Link Toolbox .

Wir würden hier eine vorhandene VirtualBox Installation mit der Docker Toolbox kombinieren.

Linux

Verschiedene Installationen in meinen Seminaren zeigen die native Kombination aus Linux Container Host und Linux Containern.

Früher oder später - ehrlich gesagt eher früher ;-) - stellt man fest dass viele Docker / Container Umsetzungen sich nur unter Linux wohl fühlen - also problemlos funktionieren.

Insbesondere viele Versuche mit mehreren vernetzten Containern streiken gerne mal in einer improvisierten Non-Linux-Container OS Umgebung.

Statt einem Docker Desktop für Linux können wir auch die klassische Installation der Docker Engine nutzen. Die Umsetzungen erstellen unterschiedliche Context für Docker (siehe docker context ls) und werden bei der Installation des Docker Desktop für Linux beide installiert.

Install Docker Engine on Linux

Install Docker Engine on Linux

Docker Engine vs. Docker Desktop

Ich empfehle für den Einstieg immer die individuelle Installation der klassischen Docker Engine. Diese Umgebung sollte man dann testen und und hat eine vorbereitete Maschine für den nachinstallierbaren Docker Desktop.

Die Firma Docker empfiehlt die Installation des Docker Desktop aus folgenden Gründen:

  • Einheitliche Entwicklerplattform auf Windows, Mac und Linux über den Docker Desktop

  • GUI mit Erweiterungen und Zusatzfunktionalitäten der Docker Technik und Docker Umgebung

  • Eine mögliche One-Klick-Installation inklusive der Docker Engine - da werde ich allerdings immer unruhig ;-)

  • Einfache Aktualsierung und Behebungen für Security Topics (siehe auch Docker Scout)

Ich lasse die Topics hier einfach mal stehen. Wir werden uns mit der sozusagen Rohinstallation der Docker Engine beschäftigen, weil serverseitig das auch die Standardvorgehensweise ist.

Im Idealfall zeige ich auch die sehr ressourcenarme Umsetzung einer Docker-Umgebung mit LXC-Containern auf ProxmoxVE.

Enterprise / Company vs. Community

Wir haben eine riesige Auswahl an Linux Distributionen und auf nahezu allen Distros lassen sich Docker und Co - also Docker Compose, Podman bis hin zu Kubernetes - installieren.

Wie wählt man also aus? Die meisten Firmen sind über die Jahre bei Distros hängengeblieben. Fragen Sie mal bei Firmen, die viele Jahre CentOS geschäftsmäßig eingesetzt haben und jetzt vor teils großen Problemen stehen.

In meinem Seminarumfeld orientiere ich mich bei Firmenschulungen an den dortigen Umgebungen: wird Red Hat eingesetzt machen wir Red Hat, wird Suse eingesetzt machen wir Suse…

Für meine Schulungen habe ich mich nach den Erfahrungen der letzten Jahre (s. a. o.) nach folgenden Unterscheidungskriterien orientiert:

  • Enterprise Distros - die teuere (nicht kostenlose) und oft nicht mal quell-offenen Distributionen - Marktführer in diesem Segment: RHEL, SLES

    Analyse: ich will zwar genau wissen, wie diese Distros funtkionieren; aber: Einsatz in Seminaren oder auch persönlichem Umfeld nur eingeschränkt möglich oder clever!

  • Company driven Distros - Linux Distributionen, die maßgeblich von Firmen und deren Interessen unterstützt werden

    Auswahl: Red Hat CentOS oder auch Fedora, Suse openSUSE / Tumbleweed, Canonical Ubuntu

    Analyse: ich bin als Techniker wieder sehr interessiert; aber: die Abhängigkeit von Entwicklungen und die Willkür bei Entscheidungen sowie die LTS Zuverlässigkeit ist zumindest sehr getrübt

  • Community Driven Distos - also Linux Distributionen, die ausschließlich mit Open Source Charakter im Netz gepflegt und entwickelt werden - Communities eben!

    Auswahl: Debian - seit über 3 Jahrzehnten der Ursprung für viele Derivate; mit Debian 12 Bookworm Öffnung für Firmware Unterstützungen aktuellerer Hardware!

Andere Nennungen:

Arch Linux - die Rolling Release Variante mit Top Softwareunterstützung; im Grunde aber Nischendasein mit hohem Nerd-Potential („BTW - i use Arch“)

Gentoo - der absolute Programmierer/Coder Dream und wer hat eigentlich Bock und Zeit mal eben 3 Stunden auf den neu kompilierten Firefox zu warten?

Die Wahl fällt bei mir also seit sehr langer Zeit auf Debian und wir wollen in unseren Docker Seminaren ebenfalls von Debian profitieren.

Aus Vereinfachungsgründen lasse ich häufig Standardinstallationen von Debian inklusive Standard Desktop Environment (DE) Gnome durchführen.

Mit Desktop Umgebung lassen sich vielen Übungen dann einfacher direkt mit der Debian Maschine durchführen.

Distribution nach Hersteller

Hier folgen weitere Anmerkungen zu Linux-Distros.

  • Debian (oft Standard-OS für Services im Internet)

    Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/debian/

  • CentOS - Vertreter Red Hat OS - war seit 2019 der Platzhirsch für Container

    Allerdings seit Umsetzung als Quasi-Rolling-Release (CentOS Stream) nicht mehr gut für Enterprise Umsetzung geeignet. Alternative: Alma Linux / Rocky Linux oder das recht frische Liberty Linux von Suse.

    Install-Anleitung auf docs.docker.com: https://docs.docker.com/install/linux/docker-ce/centos/

  • openSUSE (Vertreter Novell SLES und über Jahrzehnte in meinen Seminaren)

    Installation: (Versionen vorher checken!)

    per zypper installieren oder besser/aktueller über Build-Service Versuchspakete Virtualization:Container

    https://software.opensuse.org/package/docker

    Probleme möglich: z.B. Netzwerk/DNS - genauer: Bei Nutzung von Docker-DNS-Servicen - andere/normale funzen! siehe z.B.: Robin Winslow - fix docker

Generell eignen sich alle Linux-Distros für eiese Umsetzungen. Sehr häufig wird in diesen Zusammenhängen natürlich auch der Ubuntu Server genannt, der auf Grund seines LTS Charakters diverse Vorzüge verspricht.

Inbetriebnahme / Check

Die Nutzung der Docker Umgebung ist unter den Linux Distros immer gleich.

Hinweis

Bitte überprüfen, ob der Docker Daemon läuft und enabled ist für Standard-Target/Runlevel! Des Weiteren achtet man auf laufende Firewalls oder Security-Tools wie Selinux/Apparmor.

Alle Aufrufe (hier folgend) und dann auch für docker sollten mit root-Rechten durchgeführt werden.

systemctl status docker.service
systemctl start docker.service           # oder gleich
systemctl enable docker.service --now    # enable und start
docker version

Im letzten Aufruf müssen Client und Server aufgelistet sein.

Im Seminar wird auch der Standarduser für docker berechtigt werden, um die tägliche Seminar- und Schulungsarbeit zu erleichtern.

Hierfür muss manchmal die Gruppe docker neu erstellt werden

groupadd docker    # falls noch nicht vorhanden und nicht mit dockerroot (CentOS) verwechseln
usermod -aG docker standarduser

Bitte bei der obigen Syntax unbedingt auf die korrekte Schreibweise der Gruppenzuordnung (Parameter a mit Groß G) achten!

Gefahr

Docker mit Standarduser kann ein großes Sicherheitsrisiko darstellen! Darstellungen hierzu folgen!

Debian

Bei der Auswahl der Linux Distribution sind viele Firmen durch verschiedenste Vorgaben beeinflusst.

Ich habe mich im Vorkapitel auf kurze Differenzierungen und Einschätzungen beschränkt und werde mich im Weiteren auf Debian konzentrieren.

Install: Docker Engine

Dokumentation Docker für die Installation Docker Engine on Debian: https://docs.docker.com/engine/install/debian/

Docker Engine Install

Docker Engine Install

Den Einstieg führe ich of mit einer aktuellen stabilen Debian Installation durch (aktuell: Debian 12 Bookworm). Da greift man einfach mal zu einer virtuellen Umsetzung (in Seminaren oft Hyper-V unter Windows) und installiert Debian inklusive Gnome Desktop für eine erste einfache Bedienung. Später sind diese VMs natürlich ohne GUI und reine Serverinstallationen.

Wichtig: wir installieren die Docker Engine und nicht wie unter Windows mit WSL2 den Docker Desktop (hier: für Windows)!

Kurzanleitung:

  • Debian aktualisieren und nötige Tools / Pre-Installationen checken

  • Docker Repo für Debian inkl. Key hinzufügen

  • Debian Repos aktualisieren / neues Repo nutzen

  • Docker Engine (Docker CE) und weitere vorgeschlagene Paket installieren

  • Hello World testen: sudo docker run hello-world

  • für sudo-lose Docker-Nutzung wird User Mitglied der Gruppe docker: sudo usermod -aG docker $USER (und Neustart)

Nochmals: Bitte hier die Docker Engine installieren und nicht die Software Docker Desktop für Linux!

Für den Docker Desktop für Linux würde man jetzt schon eine „Nested VM“ benötigen - also eine VM mit eigener Virtualisierungsfähigkeit. Das ist mit Hyper-V oder anderen Virtualisieren kein Problem - benötigt aber weiter Konfigurationen!

Install: Docker Desktop

Der Docker Desktop wird - anders als die Docker Engine - eine Virtuelle Maschine nutzen. Hierzu muss für die Linux Umgebung die Anforderung an Virtualisierungsumgebung erfüllt sein.

Die Anleitungen findet man unter https://docs.docker.com/desktop/install/linux-install/.

Erster Test: lsmod | grep kvm - in einer Standard Hyper-V VM erhalten wir hier leider keine gewünschte Rückmeldung!

Über die PowerShell aktivieren wir die Unterstützung von Nested Virtualization!

Set-VMProcessor -VMName vmname -ExposeVirtualizationExtensions $true (Bitte vnname anpassen!)

Wir kontrollieren die gemachte Einstellung:

Get-VMProcessor -VMName tpl-deb12docker | fl (in der PowerShell)

Und wieder in der VM testen:

lsmod | grep kvm (in der VM - bekommen wir Ausgaben dann OK und Fortsetzung der Installation)

Für die Nutzung der KVM-Technik sollte der User noch Mitglieder der Gruppe kvm werden:

sudo usermod -aG kvm $USER (siehe ggf. vorher welche Gruppe /dev/kvm zugewiesen ist)

Hinweis: bei virtuellen Maschinen - insbesondere mit Desktop Environments - funktionieren die Aktualisierungen der Gruppenzugehörigkeiten (oft) erst nach einem Neustart der VM.

Für die Integration des Docker Desktop in die Gnome Shell (siehe später Docker Desktop Icon in Oberer Gnome Leiste) muss man AppIndicator und KStatusNotifierItem per Klicks in der Gnome Shell hinzufügen. Das ist in der Anleitung entsprechend verlinkt.

Danach einfach das DEB-Paket herunterladen und installieren. Der Docker Desktop lässt sich einfach über den Desktop starten.

Spätestens jetzt ist der Context der Docker-Umgebung wichtig bzw. nutzbar.

docker context ls (zeigt die genutzte Umgebung)

Docker Context

Docker Context

Im Screenshot kann man die Gnome Integration für den Docker Desktop sehen. Bei gestartetem Docker Desktop ist der Kontext dann auch auf desktop-linux geändert. Es handelt sich um komplett getrennte Docker Arbeitsbereiche.

macOS

Pers. Anm.: fast so außer Konkurrenz wie das Dockern unter Windows ;-). Aber über den Linxux/BSD Hintergrund und den Docker Desktop für Mac natürlich eine funktionale Wahl für das Entwickeln mit Docker auf Mac.

Docker Desktop for Mac

Docker Desktop for Mac

Die Installationsdatei (DMG) für Docker Desktop für Mac (MacOS) finden Sie unter folgender Adresse: Docker für Mac

Die Installer sind auch für die neueren Apple Silicon M1 bis M3 (und so weiter) Prozessoren verfügbar.

Container Fachbegriffe

Das folgende Image ist eine einfache Übersicht über beteiligte Techniken und Fachbegriffe. Man lehnt sich an einem (s.a. Netzwerke) üblichen Layer System an.

Virtuelle Layers

Virtuelle Layers (Bild: Liebel - Skalierbare Container-Infrastrukturen für Ihr Unternehmen)

Basis-Begriffe:

  • Images - unveränderlich / ro

  • Container - basieren auf Images, nutzen ein Overlay-Dateisystem

    Container basiert auf Image; Container-Instanz ist R/W (Read/Write) Layer

    maximale Anzahl Layer: 128 (bei overlay2, devicemapper; s.u.)

    Container-Hosts: physikalische/reale oder virtuelle Maschine

  • Volumes - möglichst vom Container getrennte Verzeichnisse im Docker-Host-System

Vertiefung:

  • Services - Dienst/Aufgabe

    Um diese Services kümmert sich Docker selbst! Sogar auf welchem Docker-Host!

  • Stacks - Administration von Service-Gruppen

  • Cluster - Vorraussetzung für Services und Stacks;

    Docker Nomenklatur: Swarm; s.a. Python-Skriptool docker-compose

  • Kubernetes - Google Open Source für Container-Verwaltungen;

    Läuft Docker Swarm den Rang ab und auch Fa. Docker Hat mittlerweile auf K8s umgeschwenkt!

  • Continouus Delivery / Continous Integration (CD/CI)

    Versuch der Eklärung: (semi-)automatisierte Verfahren (CI) von kleinteiligen Releases mit ebenfalls möglichst automatischen Deployment-Test (CD)

    siehe: Liebel Kap. 2.3ff

Container Technik

Weitere Fachbgegriffe und kurze Erläuterungen:

Docker Client-Server-Modell

Anm.: bei Windows/MacOS Umsetzungen wird das komplizierter, weil die Schnittstelle nicht direkt erreichbar ist.

Die Umsetzung mit Linux: docker CLI mit dockerd (Docker Daemon/Engine)

Klassische Docker Technik und Unix Socket per curl und jq

Klassische Docker Technik und Unix Socket per curl und jq

Docker-Client und Server kommunizieren über eine HTTP-RESTful API.

Anm.: für eine sichere Kommunikation siehe Docker Security HTTPS und nutzen Docker Context Techniken.

Einfacher Test der HTTP-Verbindung:

curl -s --unix-socket /var/run/docker.sock http://localhost/images/json

Das erzeugt einen etwas unleserlichen (serialisierten) Infostrom, der sich mit dem Tool jq besser analysieren und lesen lässt:

curl -s --unix-socket /var/run/docker.sock http://localhost/images/json | jq

Tipp

Paket jq nachinstallieren! Anm.: für CentOS benötigt man EPEL-Repo!

Bei diesen Ausgaben bitte auch gleich auf die Syntax der JSON-Strukturen achten:

  • Klammerungen

  • Aufzählungen mit Kommata

  • Keine Kommentare!

Registry

Technisch: Image-Datenbank mit Service zum pullen und pushen von Images

Im Produktionsbetrieb müsssen aus Sicherheitaspekten vertrauenswürdige und daher firmeninterne Registries genutzt werden.

Docker Registry: https://index.docker.io/v1/

Registry finden/analysieren: docker info | grep -i registry

Alternative Registries:

Anm.: Werden im Seminar - bis auf Weiteres - keine Rolle spielen (siehe auch nötige Accounts, ggfs. Kosten, …)

Repository

Hier erhalten wir Logische Unterteilungen einer Registry.

Wir haben mehreren Images mit verschiedenen Tags - siehe ubuntu:… (beliebige Ubuntu-Varianten)

Erinnerungen:

  • Wir habe keine init/systemd Techniken!

  • Was passiert bei mehr als einem Dienst pro Container?

Virtuelle VMs vs. Container

Die Container gelten als Leichtgewichte und kommen ohne Prozesse-Lasten aus.

VMs werden häufig für den Einsatz als Docker-Hosts genutzt.

Virtuelle Maschinen vs. Container

Virtuelle Maschinen vs. Container

Virtuelle Maschinen und Container (Bild: Liebel - Skalierbare Container-Infrastrukturen für Ihr Unternehmen)

Container Lösungen

Siehe auch: Wikipedia Containervirtualisierung )

  • Klassiker:

    FreeBSD Jails (ca. 2000), Solaris Zones (ca. 2005), OpenVZ (ca. 2005; siehe Virtuozzo von Parallels)

  • LXD für LXC (ca. 2008; Linux Containers oder Lightweight Linux Container) Ausgangsbasis für Docker; Heute: Canonical

  • rkt (sprich: Rocket) - von CoreOS (bzw. Produkt Container Linux)

  • VMware Photon (Heute: Broadcom)

  • Docker

    März 2013 Fa. dotCloud - dann Oktober 2013 umbenannt in Docker Inc. mit Sitz in Berlin

    Neue Componenten (ab Version >= 1.11): containerd, runc,

    aus „Docker Daemon“ wurde Docker Engine; ab Version 1.12 mit eingebauter Swarm Technik: Swarm Mode

    Schwerpunkt auf Applikationsvirtualisierung und nicht auf abgespeckte VMs

Tipp

Darstellung runc als eigenständiges Container-Tool bei Liebel (S. 85ff.)

Container Formate

Alle sprechen heute ein gleiches Containerformat OCF

  • klassische Formate: Docker, CoreOS/rkt, LXD/LXC, Photon, …

  • OCF (Open Container Format) der OCI (Open Container Initiative - www.opencontainers.org

Namespaces

Die Ressourcen vom Kernel lassen sich isolieren. Prozesse erhalten so quasi eigene Umgebungen.

Tipp

Übung mit uname -r und grep -i pretty_name /etc/os-release Aufrufen in Host und Containern!

Docker Windows Images

Wie schon mehrfach gesagt: die Windows Images spielen im Grunde keine Rolle bei den Container-Umsetzungen.

Bitte aber gerne die folgenden Technikhinweise beachten:

  • Windows Server Core

  • Nano Server

  • IIS

  • ASP.NET

Anm.: Nano Server nur für Windows Server Instanzen verfügbar!

Container Sicherheit

Faktoren für die Sicherheit der Container-Techniken:

  • Herkunft der genutzten Images

  • Wegen der Kernel-syscall Techniken (siehe namespaces) problematisch!

Empfehlungen:

  • Implementierungen mittels cgroups (Control Groups für Nutzung von Limits)

  • Applikationen in Container möglichst nicht mit root

  • Fähigkeiten der Images einschränken

  • User-Namespace aktiv

  • seccomp/SELinux/Apparmor

  • keine SUID im Container

  • aktuelle Kernel

  • Container-Host härten, aktualisieren, patchen

  • Container-Host Zugriffe einschränken

  • Netzwerk sichern / konfigurieren

seccomp

Der Secure Computing Mode ist eine Kernelunterstützung und sollte gecheckt werden.

Tipp

Bitte seccomp >= Version 2.2.1

# cat /boot/config-$(uname -r) | grep CONFIG_SECCOMP=
CONFIG_SECCOMP=y
# rpm -qa | grep seccomp
libseccomp2-2.3.2-lp150.1.9.x86_64
joeb@opensuse:~/rst/docker>

Links:

Hinweis

Also: SELinux und auch Firewalltechnken (Netfilter/iptables, firewalld, …) bedenken.

Zu diesen vertiefenden Themen in Produktionsumgebungen an dieser Stelle keine weiteren Ausführungen.

Faktoren für Security

Ganz wichtige aber eben auch ganz dicke Bretter…

  • AppArmor (Application Armor)

  • SELinux (Security Enhanced Linux) - wollen wir für Test auf permissive

    Status ermitteln mit: sestatus oder ls -Z (bei CentOS; bei Debian, openSUSE sollte SELinux deaktiv sein)

    (Auszug/Zeile:) Current Mode: enforcing

    Ausschalten mit setenforce 0

    Dauerhafte Konfiguration in /etc/sysconfig/selinux

  • Netfilter/iptables (bzw. Dienste firewalld, ufw)

    Anm.: auch immer mal verantwortlich bei vermeintlichen Docker Technik Problemen!

Sicherheitstechnik

Container sind zwar durch Namespaces isoliert. Doch das ist bei Weitem nicht derselbe Schutz, wie es bei echten Virtualisierungen erreicht werden kann.

Technische Ansätze zur Isolierung zum Host:

  • Namespaces (siehe UIDs, GIDs, PIDs pro Container)

  • Mount-Namespaces auf Kernelebene (sicherer als chroot)

  • eigener Netzwerkstack

Gefahr

Docker Prozess verlangt nach root!

Siehe Rechte für

ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0  7. Jan 12:35 /var/run/docker.sock

Aus Vereinfachungs- und Seminargründen entscheiden wir uns dennoch für

usermod -aG docker joeb

Ansätze zur Verbesserung der Sicherheit und Grundverständnisse hierzu:

Docker Daemon in Rootless Mode

Wir können den Docker Daemon auch ohne Root-Rechte nutzen. Das erfordert allerdings einigen Installations- und Konfigurationsaufwand.

Die nötigen Schritte und Installationen zeigt die Docker Dokumentation:

Proof of Concept

Wir wollen die Container-Technik checken. Mit einem Proof of Concept - oder besser gesagt mit einem Proof of Technique.

Hello World mit PHP

Hello World mit PHP

Hier sollen jetzt für den weiteren Einstieg in die Materie Container mit Docker einsetzbare erste Beispiele folgen.

Wir wollen schnell testen, das die Technik funktioniert (siehe hello-world) und einen ersten schnellen Eindruck vom Nutzen von Containern (siehe ubuntu) bekommen.

Test: Hello World!

Hello World - Docker Beispiel

Hello World - Docker Beispiel

Was wäre ein Seminar in solchen Technikbereichen ohne ein Hello World! Beispiel!

Wir finden das Image bei den offiziellen Images auf dem Docker Hub unter https://hub.docker.com/_/hello-world. Bei den späteren Analysen wird der _ (tiefe Strich) in der URL den Status eines offiziellen Image auf dem Docker Hub wiederspiegeln.

Die folgenden Aufrufe erfolgen erst einmal ohne weitere Erläuterungen. Erste Aufrufe also:

docker run hello-World                    # Offizielles Image vom Docker Hub
docker container ls -a                    # bwz. klassisch: docker ps -a
docker image ls                           # bzw. klassisch: docker images
docker container start -i container-name  # Ausgabe nochmals erzeugen

Es ist zu beachten, dass jeder Aufruf docker run hello-world einen neuen Container erzeugt!

Der docker run Befehl erzeugt einfach nur einen Container, der ein einfaches ausführbares Programm (Binary) namens hello ausführt. Der Container wird danach sofort beendet, da er durch keinen Prozess am Leben erhalten wird!

Mehr Infos zum Image hello-world erhält man unter https://github.com/docker-library/hello-world. Dort lässt sich auch der C-Code inspizieren, der für die Erzeugung von Programm hello genutzt wird.

Test: Ubuntu

Ubuntu Recherche auf Docker Hub

Ubuntu Recherche auf Docker Hub

Beispielhafte Suche nach offiziellen Basis-Images: Docker Hub - Offizielle Basis Images ergibt für Ubuntu die URL https://hub.docker.com/_/ubuntu

Wir folgen einer Anregung aus dem Hello World Beispiel:

docker run -it ubuntu                 # Ubuntu bereitstellen und starten
docker start -i <name-oder-id>        # Bestehenden Container nutzen

Wir werden die Kommandos in Kürze genauer erkunden.

Tipp

Bei Container-Namen funktionieren die Completions!

Man sollte also beim Erstellen der Container bereits auf die Vergabe sinnvoller Namen achten und nach Wunsch auch noch einen ordentlichen Hostname vergeben.

docker run -it --name meinubuntu -h meinubuntuhostname ubuntu
docker exec -it meinubuntu /usr/bin/top      # Befehl in Container ausführen

Eine Erkenntnis hier sollte die Aufrechterhaltung der Containerumgebung durch einen Prozess (PID 1) sein. Im Fall dieses Distro-Image Ubuntu wird hier die Bash-Shell genutzt.

Eine andere Frage, die man sich hier stellen sollte: Welches Ubuntu haben wir denn jetzt hier bereitgestellt bekommen und genutzt?.

CLI Kommandos

Docker Kommandos auf docs.docker.com

Docker Kommandos auf docs.docker.com/engine/reference/commandline/cli/

Auflistung von Docker Befehlen: Docker CLI Befehle

Wir haben schon einige Docker CLI Kommandos genutzt. Jetzt sollen komplettere Aufstellungen folgen.

Die Aufrufe sind nach Kategorien gegliedert. Die Aufrufe lassen sich teilweise in langer/moderner und kurzer/klassischer Schreibung aufrufen:

docker container ps -a     # oder auch kürzer
docker ps -a

Das hat auch mit historischen Entwicklungen innerhalb der Docker-Versionen zu tun!

Eine neue, sauberere und stringenter Kommanostruktur wurde mit Docker Version 1.13 eingeführt. Insbesondere für die Vervollständigung von Befehlen hat das Wunder bewirkt.

Tipp

Bash: Paket docker-bash-completion in der Shell nutzen. Also fleißig mit Tab bzw. TabTab vervollständigen! Bei manchen Distros muss man hier manuell nachinstallieren. Und selbstvertändlich kann man auch andere Shells nutzen.

PowerShell: Bitte Modul DockerCompletion nutzen.

Wir beginnen aber - eigentlich wie immer bei Konsolenvertiefungen - mit der eingebauten Hilfe.

Hilfe in CLI

Wir steigen mit ein paar Links aus dem Onlineportal für die Docker CLI ein.

Tipp

Die weiteren Befehle (z.B. docker container) lassen sich einfach in URL an Stelle von image ersetzen!

  • https: // docs.docker.com / reference / cli / docker / image /

  • https: // docs.docker.com / reference / cli / docker / container /

Und natürlich kann man auch jederzeit mal die interaktive Docker Hilfe nutzen. Wir starten mit einem generellen docker help in der Konsole.

docker help (Zeilen teils länger/ungekürzt)
Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
  images      List images
  login       Log in to a registry
  logout      Log out from a registry
  search      Search Docker Hub for images
  version     Show the Docker version information
  info        Display system-wide information

Management Commands:
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.11.2)
  compose*    Docker Compose (Docker Inc., v2.21.0)
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  plugin      Manage plugins
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Swarm Commands:
  swarm       Manage Swarm

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Global Options:
      --config string      Location of client config files (default "/root/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker
                           context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket to connect to
  -l, --log-level string   Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/root/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/root/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/root/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Run 'docker COMMAND --help' for more information on a command.

For more help on how to use Docker, head to https://docs.docker.com/go/guides/

Mit der Hilfe kann man sich dann auch weiter in die Kommando-Hierarchien (Subkommandos) begeben: docker container ps --help.

docker container ps –help
Usage:  docker container ls [OPTIONS]

List containers

Aliases:
  docker container ls, docker container list, docker container ps, docker ps

Options:
  -a, --all             Show all containers (default shows just running)
  -f, --filter filter   Filter output based on conditions provided
      --format string   Format output using a custom template:
                        'table':            Print output in table format with column headers (default)
                        'table TEMPLATE':   Print output in table format using the given Go template
                        'json':             Print in JSON format
                        'TEMPLATE':         Print output using the given Go template.
                        Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates
  -n, --last int        Show n last created containers (includes all states) (default -1)
  -l, --latest          Show the latest created container (includes all states)
      --no-trunc        Don't truncate output
  -q, --quiet           Only display container IDs
  -s, --size            Display total file sizes

Anm.: es handelt sich bei der Textausgabe der Hilfe nicht um einen Fehler. Es wurde docker container ps --help aufgerufen - man erkennt dann die Aliase.

Und zuletzt wurden auch klassische Man-Pages für die docker-Kommandos implementiert, die man einfach über mit „-“ (Bindestrich) zusammengesetzte Aufrufe erhält: man docker-start. Allerdings sind diese Hilfen auf manchen Distros stark minimiert oder erwarten Nachinstallationen.

CLI Subkommandos

Die folgenden Auflistungen sind heute aufgrund der mehr als ordentlichen Synta**SUB**-Vervollständigungen in der CLI/Konsole obsolet.

Docker Vervollständigungen in der CLI/Konsole

Docker Vervollständigungen in der CLI/Konsole

Allerdings will ich sie an dieser Stelle belassen, um damit der Struktur der Befehle und deren internen Verdrahtungen Rechnung zu zollen.

Es folgen dann noch ein paar Subkommandos in lockerer Schüttung.

Tabelle - Docker Infrastruktur

Kommandos

Subkommando

Funktionalität

docker container

container

Container verwalten (eigener Abschnitt)

docker image

image

Images verwalten (eigener Abschnitt)

docker network

network

Netzwerke verwalten

Online: Infoseite Docker Networking

Subkommando für Docker Networking: docker network --help

docker volume

volume

Volumes (Storge) verwalten

Online: Infoseite Docker Storage

Subkommando für Docker Volumes: docker volume --help

docker events

Laufende (!) Aktionen des Docker-Systems anzeigen - Beispiele…

Alle Events in einem bestimmten Zeitraum:

docker events --since '2019-01-01' --until '2019-01-10'

in den letzten 50 Minuten

docker events --since '50m'

für ein bestimmtes Image (oder auch ‚container=…‘)

docker events --since '40m' --filter 'image=alpine'

Event nach types filtern:

docker events --since '2019-01-01' --filter 'container=alpinejoeb' --filter 'event=start'

Die Ausgaben können formatiert (Parameter --format) ausgegeben werden (auch JSON).

docker info

Infos zum Docker System.

Beispiel: Anzahl der laufenden Container anzeigen

docker info | grep Running

docker init

(Docker Desktop!)

Projektordner mit Basisdateien compose.yml, .dockerignore, Dockerfile und einer Readme befüllen.

Anm.: kann man heute über Docker Entwicklungstools für IDEs einfacher haben

Der Befehl steht nur mit Docker Desktop zur Verfügung!

docker stats

Laufende (!) Auslastung CPU, MEM … anzeigen lassen

entspricht dem Linux-Klassiker top für die Shell

docker search

Image auf dem Docker-Hub suchen: docker search ubuntu

Anzahl Images mit Namen ubuntu:

docker search ubuntu | grep "\/ubuntu\ " | wc -l Filtern der Suchergebnisse:

docker search --filter=stars=7 --filter=is-official=true ubuntu

docker login | logout

am Docker-Hub-Account an-/abmelden

docker version

Docker Version(en) anzeigen lassen

docker system

system

Infos zu Docker System - s.a. docker (system) info | events Systemauslastung Filesystem: docker system df

Aufräumen / Echt Alles ;-) Tabularasa mit

docker system prune (--all --force)

Eine laufende Konsole erfordert immer weitere Fenster für den Workflow. Also gerne wieder mit mehreren Terminalfenstern arbeiten (siehe Tilix, TMUX oder Tiling WM).

Die nachfolgenden Tabelle und habe ich der Vollständigkeit halber belassen. Die Docker Swarm Techniken werden entweder durch Compose (bei kleineren Umsetzungen und in den Entwicklungsphasen von Projekten) oder durch vollständige Orchestrierungen (siehe K8s Kubernetes) ersetzt.

Tabelle - Docker Swarm

Kommandos

Subkommando

Funktionalität

docker swarm

swarm

Swarm einrichten / verwalten

docker node

node

Docker Swarm Knoten verwalten

docker secret

secret

Secrets für Swarm Services

docker service

service

Swarm Services verwalten (siehe Cluster)

docker stack

stack

Stack (Gruppe von Services) verwalten

Viele der verschiedenen Kommandos für die Docker Infrastruktur werden wir uns über praktische Übungen erarbeiten.

CLI Images

Wenn wir uns später die gesamte Nutzung der Technik erarbeitet haben, dann werden die beiden zentralen Beisteine für die Umsetzung (Image + Container) noch deutlicher.

Docker Image command CLI

Docker Image command CLI

Für den Anfang will ich hier eine einfach erste Übersicht über die docker image Kommandos bereitstellen.

Das Training findet wieder über praktische Anwendungen und Übungen statt.

Tabelle: Docker Kommandos für Images

docker image

Funktionalität: Image verwalten

… build

neues Image erzeugen mittels Datei Dockerfile

… history

Build-History eines Images

… inspect

lokale Images analysieren

… ls

Images auflisten - klassisch docker images

… pull

Image aus Registry herunterladen / bereitstellen

… push

Image in Docker Registry hochladen

… rm

Image löschen - klassisch: docker rmi

… save | load

aus Images einen Tarball erzeugen und laden

… tag

Image-Namen bzw. Tag anpassen

Aus diversen Ausarbeitungen und Unterlagen haben sich noch die folgenden Infos bewährt, die ich hier bereitstellen möchte.

Infos: docker pull

Wenn nur ein Imagename angegeben wird, dann wird das Image mit Tag :latest gepullt!

Images mit Tag:latest müssen nicht immer die aktuellsten Images sein!

Kompletter Aufruf: docker pull [OPTIONS] REGISTRY:REG-PORT/IMAGE:TAG|@DIGEST

Optionen: -a | --all-tags um alle Images(:tags) mit einem Imagenamen zu pullen (gesamtes Image-Repository)

Infos: docker image ls

Mit Option --no-trunc komplettere Ausgaben und -q für quiet, was einfach die (kurzen) IDs ausgibt!

Alle Images auflisten:

docker images -a

REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
mariadb                    <none>              2bdd97ca79d9        6 days ago          366MB
joebrandes/testwebserver   latest              9ff70d3871d4        7 days ago          183MB
<none>                     <none>              7c54877665f7        7 days ago          183MB
<none>                     <none>              6a247201e8a3        7 days ago          183MB
<none>                     <none>              aef9419d7b92        7 days ago          183MB
<none>                     <none>              c21c0c4fe351        7 days ago          183MB
<none>                     <none>              a3ff1c7635da        7 days ago          183MB
<none>                     <none>              2bd50cd1f5b1        7 days ago          86.7MB
<none>                     <none>              86e536f3da5c        7 days ago          86.7MB
hello-world                latest              fce289e99eb9        2 weeks ago         1.84kB
wordpress                  latest              9ec2fcdda9ef        2 weeks ago         420MB
mariadb                    latest              4f2e75647d2a        2 weeks ago         366MB
ubuntu                     18.10               d4452947e3fa        2 weeks ago         73.7MB
ubuntu                     18.04               1d9c17228a9e        2 weeks ago         86.7MB
alpine                     latest              3f53bb00af94        3 weeks ago         4.41MB

Die hier aufgelisteten none:none Images enstehen durch das Layersystem von Images und belegen und verschwenden keinen Platz im System!

Problematisch sind Images die mit none:none bei normalem docker images (ohne -a) auftauchen:

Erinnerung: bei docker images bitte auf Plural achten!

Tipp

docker image ls -q bzw. docker image ls --quiet listet nur die IDs auf und kann somit gut zum Pipeling für andere Docker-Aufrufe genutzt werden!

Dangling Images - verwaiste Einträge

Finden von Dangling Images: docker images -f "dangling=true"

Löschen / Aufräumen: per Filtern oder mit docker image prune

docker images -f "dangling=true" -q | xargs -n1 docker rmi -f
# oder einfach mit:
docker image prune

Infos: docker image inspect

Formatierte Ausgaben mit Parameter --format

docker inspect --format='{{.Config.Cmd}}' alpine:latest
[/bin/sh]
# oder einfacher mit:
docker inspect alpine:latest | grep -i Cmd

Das lässt sich auch wieder aufbereiten (Tool jq):

docker image inspect alpine:latest | jq -CS                       # C Color; S sortiert
docker image inspect alpine:latest | jq -CS .[0].Config.Cmd       # Zugriff auf Array
[
"/bin/sh"
]

Die Ausgabe von Docker Kommandos ist auch über Go-Templates möglich: (Go Templates )

docker image inspect alpine:latest --format '{{.Config.Cmd}}'
[/bin/sh]
docker image inspect alpine:latest --format '{{json .Config.Env}}' | jq
[
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]

Diese Ausgabeformate lassen sich auch bei anderen cmd-Techniken nutzen (siehe docker container ls ...).

Infos: docker save | load

Speichert Images in einem Tarball - nicht mit dem Export / Import von Containern verwechseln

docker save -o ~/alpine-out.tar alpine
tar -tvf alpine-out.tar

-rw-r--r-- 0/0            1511 2018-12-21 01:21 3f53bb00af943dfdf81...129d57d5991.json
drwxr-xr-x 0/0               0 2018-12-21 01:21 a21b1050952cdc06771...57cae64904b/
-rw-r--r-- 0/0               3 2018-12-21 01:21 a21b1050952cdc06771...57cae64904b/VERSION
-rw-r--r-- 0/0            1184 2018-12-21 01:21 a21b1050952cdc06771...57cae64904b/json
-rw-r--r-- 0/0         4672000 2018-12-21 01:21 a21b1050952cdc06771...57cae64904b/layer.tar
-rw-r--r-- 0/0             202 1970-01-01 01:00 manifest.json
-rw-r--r-- 0/0              89 1970-01-01 01:00 repositories

In layer.tar befindet sich das eigentliche Image mit den Ordnerstrukturen /, /bin, /usr, …

Diese Sicherung lässt sich dann auf einem anderen Rechner wieder loaden.

CLI container

Auch hier gilt wieder, dass wir nicht alle Befehle bis in die letzte Nutzung aufführen wollen.

Docker Container command CLI

Docker Container command CLI

Wir starten wieder mit einer tabellarischen Übersicht.

Tabelle: Docker Kommandos für Container

docker container

Funktionalität

… ls | ps

Laufende Container auflisten - mit -a alle Container

Klassische Kurzform: docker ps (Container = Prozess)

… attach

I/O eines Containers mit Terminal connecten

… commit

neues Image aus Container

… cp

Kopieren von Daten zwischen Container <-> Host

… create

Container erzeugen, aber nicht starten

… diff

veränderte Dateien eines Containers erzeugen

… exec

Kommando in laufendem Container ausführen

… export | import

Container in Archiv speichern | aus Archiv erzeugen

… inspect

Konfiguration und Status eines Containers

… kill

Container sofort beenden

… logs

Container-Loggings

… pause | unpause

Container anhalten | fortsetzen

… port

Container Ports auflisten

… rename

Container umbenennen

… rm

Container löschen

… run

neuen Container erzeugen und starten

… start | stop | restart

Container starten | stoppen | neu starten

… top

Container Prozesse anzeigen

… update

Container Optionen anpassen

… wait

Container Ende erwarten

Wie bei den Images wollen wir auch für die Container ein paar Beispiele für Kommandos auflisten und ausführen.

Infos: docker container ls

Filterung mit Kriterium: -f <Kriterium=Wert> - Docker filter

Filter output based on these conditions:
- ancestor=(<image-name>[:tag]|<image-id>| image@digest )
  containers created from an image or a descendant.
- before=(<container-name>|<container-id>)
- expose=(<port>[/<proto>]|<startport-endport>/[<proto>])
- exited=<int> an exit code of <int>
- health=(starting|healthy|unhealthy|none)
- id=<ID> a container's ID
- isolation=(default|process|hyperv) (Windows daemon only)
- is-task=(true|false)
- label=<key> or label=<key>=<value>
- name=<string> a container's name
- network=(<network-id>|<network-name>)
- publish=(<port>[/<proto>]|<startport-endport>/[<proto>])
- since=(<container-name>|<container-id>)
- status=(created|restarting|removing|running|paused|exited)
- volume=(<volume name>|<mount point destination>)

Es gibt weitere Formatierungsmöglichkeiten für die ls-Ausgabe.

# filtere container mit Ports 8080 bis 8083 (tcp)
docker container ls -a --filter publish=8080-8083/tcp

# container ls mit formatierter Tabelle
docker container ls -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Labels}}"

# container ls mit manuellem printf Mechanismus
docker container ls -a --format '{{printf "%-30s%-30s" .Names .RunningFor}}'

# auch hier wieder JSON Formatierung möglich:
docker container ls -a --format '{{json . }}' | jq

Die Formatierungs-Schalter (siehe Go-Templates) ann man wieder gerne per Hilfen zu den Tools docker-ps bzw. docker-container-ls|ps nachschlagen. Da findet man auch weitere Aufrufe und Beispiele.

Valid placeholders for the Go template are listed below:
- .ID           - Container ID.
- .Image        - Image ID.
- .Command      - Quoted command.
- .CreatedAt    - Time when the container was created.
- .RunningFor   - Elapsed time since the container was started.
- .Ports        - Exposed ports.
- .Status       - Container status.
- .Size         - Container disk size.
- .Names        - Container names.
- .Labels       - All labels assigned to the container.
- .Label        - Value of a specific label for this container.
                  For example '{{.Label "com.docker.swarm.cpu"}}'.
- .Mounts       - Names of the volumes mounted in this container.
- .Networks     - Names of the networks attached to this container.

Infos: docker container attach

Auf Container die man mit docker run -it oder docker start -a -i gestartet hat, kann man immer über die interaktive Konsole zugreifen.

Andernfalls kann man mit docker attach diese Funktionalität nachholen. Man könnte sagen, dass erzeugte Container die Terminalfähigkeit eingebaut haben. Man muss diese nur noch ankoppeln/attachen.

Infos: docker container exec

Hiermit kann man Befehle in einem laufenden Contaier aufrufen. Der Container muss aktiv sein - also laufen.

Wird eine Shell per exec benutzt und mit exit verlassen, dann läuft der Container weiter!

docker container start ubuntu-container                 # kein Terminal/tty!
docker container ls                                     # Container läuft
docker container exec -i -t ubuntu-container /bin/bash  # Shell mit tty
exit                                                    # exit Bash aus exec
docker container ls                                     # Container läuft noch1

Infos: docker container cp

Manuelle Kopieren von Daten zwischen Container und Host, was normaler Weise automatisch beim Erzeugen von Images genutzt wird.

echo "Testing" > /tmp/testdatei
docker start alpinejoeb
docker container cp /tmp/testdatei alpinejoeb:/
docker exec alpinejoeb cat /testdatei
docker stop alpinejoeb

Infos: docker container inspect

Das inspect-Kommando arbeitet mit Images und Containern und erzeugt Infos im JSON-Format.

Für die Analyse von Containern unterscheidet sich der inspect nach dem Status, also ob der Container läuft oder nicht läuft.

JSON anzeigen:

docker inspect -s mariadb-test5
...
...
    {
        "Id": "cd42b1a7c4542f76174f936e5a2060f1f87e3511d3fe5e07bb27e15a1ca74ea5",
        "Created": "2019-01-06T19:56:47.958915783Z",
        "Path": "docker-entrypoint.sh",
        "Args": [
            "mysqld"
        ],
        "State": {
            "Status": "exited",
            "Running": false,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2019-01-06T19:56:48.881461371Z",
            "FinishedAt": "2019-01-06T20:15:04.192413984Z"
        },
...
...

Analyse über Parameter -f (format)

docker inspect -s -f "{{.State.Status}}" mariadb-test5
docker inspect -s -f "{{.State.FinishedAt}}" mariadb-test5

Infos: docker container start | stop

Mit Parametern -ai (attach) kann man direkt in eine Shell eines Containers starten: docker start -ai containername, wenn der Container die Shell als Prozess bereitstellt.

Tipp

Die Container-Instanz wird mit exit beendet!

Mit der Tastenkombination Strg + P gefolgt von Strg + Q läuft der Container weiter!

Alle vorhandenen Container stoppen: docker stop $(docker ps -a -q)

Alle gestoppten Container entfernen: docker rm $(docker ps --filter "status=exited")

Oder mit einem prune (dt.: stutzen, beschneiden) Schalter: docker container prune

Infos: docker container top

Das Container Kommando ist angelehnt an das top Kommando - hier aber als Einzelausgabe.

Aber der Reihe nach… wir starten erst einmal einen Container: docker start alpine (oder natürlich docker run ...).

CONTAINER ID   IMAGE    COMMAND    CREATED        STATUS        PORTS    NAMES
ba4471eeb783   alpine   "/bin/sh"  10 days ago    Up 17 minutes          alpinejoeb

Analyse auf Docker-Host mit ps axf ergibt (Anm. gekürzt und Umbrüche erzeugt):

1705 ?        Ssl    0:00  \_ docker-containerd
--config /var/run/docker/containerd/containerd.toml
--log-level info

3602 ?        Sl     0:00      \_ docker-containerd-shim -namespace moby
-workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/ba4471eeb783b...

3619 pts/0    Ss+    0:00          \_ /bin/sh

Man erkennt die PIDs für Container und Shell.

Jetzt mal die Prozesse im Container klassisch: docker container exec alpinejoeb ps ax

PID   USER     TIME  COMMAND
  1   root     0:00  /bin/sh
 11   root     0:00  ps ax

Und mit dem docker container top alpinejoeb -x Kommando: (Anm.: -x verkürzte Ausgabe)

PID                 TTY                 STAT                TIME                COMMAND
3619                pts/0               Ss+                 0:00                /bin/sh

Hinweis

Also völlig unterschiedliche Prozess-IDs aus verschiedenen Ansichten! Der erste Prozess im Container hat immer die Container-PID 1.

Prozesse lassen sich jederzeit von außen stoppen (killen).

Exit Status

Informationen zu Exit Status der Ausgaben von docker container ps -a

Die Nummern in Angabe Exited (#) von Spalte STATUS beziehen sich auf Exit-Meldungen beim Verlassen, stoppen oder killen eines Containers.

Eigene Docker Exit Return Code:

  • 125 Docker Daemon hat Fehler

  • 126 Container Kommando kann nicht aufgerufen werden

  • 127 Container Kommando konnte nicht gefunden werden

Ansonsten orientiert sich das Exit-Coding an

Infos: docker (container) run

Der Docker run Befehl kommt in vielen Abhandlungen zu Docker aus verständlichen Gründe sehr früh, da er (siehe docker run hello-world) viele Aufgaben in einem Arbeitsschritt erledigt.

Leider vernebelt sich häufig bei den Anwendern der Blick auf die eigentliche technische Bewandnis und Funktion des Aufrufs.

Im Grunde stelle das Kommando alle Schalter zum Bau - oder besser gesagt zur Bereitstellung - unserer genutzten Container zur Verfügung. Warum besser gesagt? Weil wir beim Bauen besser an den Build-Prozess für eine Image denken sollten.

Docker run Schalter - alle Konfigurationen für Container

Docker run Schalter - alle Konfigurationen für Container

Der Befehl docker run erledigt die folgenden Schritte in einem Aufruf:

  • Benötigtes Images lokal checken oder pullen

  • Container erzeugen

  • Container starten

Dabei wird also, falls noch kein Image lokal vorhanden ist das entsprechende Image erst gepullt - also lokal bereitgestellt!

Bei Image-Namen ohne Tag wird versucht das image:latest genommen!

Siehe auch Extensives Manual für Kondsolentool docker-run!

Optionen

Funktionalität

--cpus="1.25"

maximal 1,25 CPU Cores

-d | --detach

Container im Hintergrund (detached) - für Daemons!

-e | --env VAR=value

Variable für Container setzen

-h | --hostname

Hostname

-i | --interactive

interaktiv ausführen lassen

-t | --tty

Pseudo-Terminal mit Standardausgabe verbinden

-m | --memory 512m

Container-RAM auf 512 MiB limitieren

--name <container-name>

Containername

--network <nw-name>

Netzwerk verwenden

-p | --publish localport:containerport

Portweiterleitungen zwischen Host und Container

-P | --publish-all

alle Port des Containers mit zufälligen Host-Ports

--rm

Container nach Ausführung löschen

-v | --volume containerdir

Containerverzeichnis als Volume

-v vname:cdir - Volume mit Namen erzeugen

-v /localdir:cdir- Host-Dir mit Container-Dir verbinden

--volumes-from cname - Volume eines anderen Containers nutzen

Bemerkung

Enthalten Images keine aktiven Prozesse werden Container-Instanzen nicht am Leben gehalten!

Solche Prozesse (z.B. /bin/bash) müssen natürlich im Image vorhanden sein und direkt und sofort für den Container genutzt werden: also -it und nicht -d!

Infos: diverse Aufrufe

docker container commit

Man sollte besser über Dockerfile und Builds arbeiten, weil sonst die Aufbauten der Images nicht mehr nachvollziehbar sind!

docker container diff

Abweichungen zwischen Container und ursprünglichem Image auflisten.

  • A (added - hinzugefügt)

  • C (changed - geändert)

  • D (deleted - gelöscht)

docker export

Beim Exportieren eines Containers werden alle Layer zusammengefasst! Man spricht vom flatten für Image Layer.

Das ist beim docker save | load für Images gänzlich anders.

Achtung

Daten in Volumes werden nicht berücksichtigt!

Test:

# Endlosschleife im Container exec-uten:
docker container exec -d alpinejoeb /bin/sh \
  -c "while true; do echo palimpalim; sleep 1; done"

# Prozess für Schleife im Container ermitteln
docker container exec alpinejoeb ps ax (hier: Schleife mit PID 16)
# Prozess mit Container-PID 16 stoppen
docker container exec kill 16

Docker Technik

Die komplette Administration ergibt sich erst durch längere Praxis und Erfahrungen mit den mannigfachen Docker-Aufrufen und Tools.

Docker Techniküberblick bei Microsoft Dot.Net Learn Portal

Docker Techniküberblick bei Microsoft Dot.Net Learn Portal

Hier eine erste kleine Übersicht und Einstiege in verschiede Aspekte der Container.

Images und Container

An dieser Stelle will ich weiteres Grundverständnis über die fraglichen Techniken und Begriffe bereitstellen. Für meine Trainees halte ich diverse digitale Unterlagen bereit. Hier für die Darstellung ein Cheat Sheet.

Docker Cheat Sheet Trainer Joe Brandes

Docker Cheat Sheet Trainer Joe Brandes

Der (1-2-3) Lebenszyklus eines Containers lässt sich gut erkennen.

Hinweis

Ich erinnere an die klassische Grundidee für Container:

1 Prozess (bzw.Service) = 1 Container.

Daher kommt ja auch die klassische docker ps Syntax!

Im Grunde fängt Alles mit der Schablone für einen Container an dem Image. Und die Frage stellt sich, wo liegen diese Images. Die Images liegen in einer Registry.

  • Registry - Online- oder Offline-Fundus für Images

    Der digitale Fundus für gewünschte Images. Man sollte hier (noch) den Begriff Repository vermeiden. Es gibt diverse Registries online von verschiedenen Anbietern. Und was ist eigentlich mit den Themen Vertrauen, Privacy oder Schutz meiner digitalen Güter - hierzu in einem späteren Abschnitt mehr.

    Wir beziehen uns an dieser Stelle der Einfachheit halber auf den sogenannten Docker Hub - eben eine solche Anlaufstelle für Images.

  • Image Pull oder Build - Image bereitstellen

    Über einen Image Pull laden wir das gewünscht Image auf unseren Docker-Host, falls es noch nicht aktuell vorliegt. Oder wir bauen uns das gewünschte Image.

    Images stehen also in unterschiedlichen Entstehungen zur Verfügung:

    • Image from Scratch

    • Basis Images (mit Status Official)

    • Image Builds: Benutzerdefinierte Images basierend auf Images (s.oberhalb) und definiert über ein Dockerfile

    Zusammengefasst: ein Image stellt eine genau fixierte Ausgangssituation für eine technische Umgebung basierend auf Textdirektiven (Dockerfile) dar.

  • Container Create oder Compose - Container für die Nutzung erstellen

    Jetzt wird per create aus einem Image ein Container. Das Image ist der Read-Only Teil für den schreibbaren Container-Teil.

    • Image: Read Only / Vorlage für Container

    • Container: Read and Write / Umgebung für SW / ABER: Wegwerfware!

    Wenn wir später mehrere Container basierend auf unterschiedlichen Images erzeugen wollen, dann können wir (z.B.) zu Docker Compose Technik greifen.

Alle Schritte könn(t)en per (container) run zusammengefasst werden.

Zusammenfassung

Der Container kapselt somit unsere gewünschte Software/Dienstleistung. Diese Umgebung lässt sich jederzeit nachvollziehbar bereitstellen. Und das auf völlig verschiedenen Maschinen oder sogar Betriebssystemen. Wir benötigen nur unser Container Management!

Volumes und Mounts

Die Grundidee ist immer gleich: die Daten unserer Container - z.B. Webverzeichnis eines Webservers - müssen außerhalb vom Container gespeichert sein! Diese Ides bezeichnet man als Volumes.

Volumes und Bind Mounts

Volumes und Bind Mounts

Volumes lassen sich unter Docker als Mounts oder Docker Volumes nutzen und können unterschiedlich erstellt und gebunden sein.

Docker Volumes

Eine Übersicht in Kürze: Link docs.docker.com - Storage - Volumes)

Wie der Name schon andeutet kümmert sich hier die Docker Technik um die Verwaltung der gewünschten Datenspeicher.

Die Konfiguration und Verdrahtung der Volumes kennt unterschiedliche Herangehensweisen.

  • Mit dem Docker Befehl docker volume create ... werden Docker Volumes manuell erzeugt und dann über den Schalter -v den Docker Containern mitgeteilt.

  • Mit der Dockerfile Direktive Volume kann man nur Volumes innerhalb des Containers erzeugen!

    Link docs.docker.com Reference Builder Volume

  • Beim create oder run für den Container kann man Mount-Points mit Parameter --mount spezifizieren.

    Link docs.docker.com - Reference run - Volume mounts and Bind mounts

  • Mit der Docker Compose Direktive volumes:

    In der docker-compose.yml werden echte Docker Volumes erzeugt und (persistent) nutzbar gemacht.

Nur echte Docker Volumes lassen sich mit docker volume ls auflisten - die Mounts sind hier nicht aufgelistet!

Die Volumes lassen sich wieder mit docker volume inspect ... analysieren.

Die Volumes werden beim Löschen von Containern nicht mitgelöscht, was ja auch ganz im Sinne der technischen Nutzung ist (siehe Container als Wegwerfware bzw. Aktualisierung von Containern).

Verzeichnis für Volumes (bei Linux): /var/lib/docker/volumes

Hinweis zu Docker Compose

Wenn man mit docker-compose Container genutzt hat und dann beim docker-compose down noch den Schalter -v anhängt werden automatisch alle Volumes der docker-compose.yml gelöscht.

Backup für Volumes

Am Besten nutzen wir Docker Technik mit einem sehr einfachen Image in dessen Container wir das zu sichernde Volume und einen lokalen Ordner für das Sicherungsarchiv verdrahten.

Man sollte zuvor die Zugriffe auf das Volume stoppen.

docker run --rm \
   -v "$VOLUME_NAME":/backup-volume \
   -v "$(pwd)":/backup \
   busybox \
   tar -zcvf /backup/my-backup.tar.gz /backup-volume

Und dafür - und die Restores - haben sich diverse Skripte im Netz angesammelt.

Beispiel: GitHub Repo BretFischer/docker-vackup

Volumes beim Docker Desktop für Windows

Die Analyse von Docker Volumes bei Nutzung von Docker Desktop für Windows ist nach ganz so einfach, da die Verdrahtung der Docker Volumes im Windows WSL2 Subsystem manchmal mehr Analyse verlangt um die Ordnerstruktur für die Volumes zu finden.

Beispiel eines Standard Docker Volume für eine Portainer Datenstruktur unter Linux:

/var/lib/docker/volumes/portainer_data/_data/ (Volume: portainer_data)

Dasselbe Portainer Volume portainer_data auf einem Docker Desktop für Windows Volume:

\\wsl.localhost\docker-desktop-data\data\docker\volumes\portainer_data\_data

Trick für Docker Desktop für Windows mit WSL2:

Einhängen (hier Debian WSL2 Machine) mit einem Docker Container basierend auf Debian Image: (nsenter ruft Shell sh in anderem Namensraum auf)

docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -i sh

Jetzt lässt sich eine Volume Technik direkt mit dem Standardpfad /val/lib/docker/volumes/... aufrufen!

Bind Mounts

Eine Übersicht in Kürze: Bind Mounts (Link docs.docker.com - Storage - Bind Mounts)

Die Daten liegen außerhalb des Container in der Verzeichnisstruktur des Docker Hosts - z.B. -v /var/dc-test-www:/var/www/html.

Der Parameter -v kündigt die Zuweisung an. Links vom : ist das lokale Verzeichnis /var/dc-test-www und rechts der Standardordner /var/www/html des Containerservice (hier Webserver Apache2) zu finden.

Networking

Jeder Container verfügt standardmäßig über Netzwerkfähigkeit. So verbinden wir uns ja über Portweiterleitung (Publishing) funktionstüchtig mit Containerdiensten.

Network Drivers - Overview on https://docs.docker.com/network/drivers/

Network Drivers - Overview on docs.docker.com/network/drivers/

Die Docker Technik manipuliert die OS-spezifische Netzwerktechnik mit Paketfilter und Firewall Techniken (Linux/Unix: iptables bzw. die aktuelleren Netfilter Tools iptables-nft oder auch xtables-nft-multi).

Wie immer bietet die Docker Dokumentation einen sehr g uten Einstieg und Übersicht in die Docker Netzwerktechnik .

Für die Vernetzung von Containern nutzen wir später auch automatisierte Container Deployments - wie z.B. Docker Compose.

Für den Einstieg allerdings wollen wir uns die bereitstellbaren Netzwerktechniken in Docker manuell erarbeiten und nutzen.

Eine erste Übersicht über die verfügbaren Docker Netzwerke erhalten wir mit docker network ls.

> docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2be710ddb5b4   bridge    bridge    local
8c5ab405882d   host      host      local
8eb9e8218f21   none      null      local

Der Netzwerk Driver bridge stellt das Standardnetzwerk für Container dar. Der host Driver entfernt die Trennung (Isolation) zwischen Container und Docker Host.

Die Netzwerke lassen sich wie immer mit docker network inspect ... analysieren.

Tipp

Für die vertiefenden Ananlysen und Verständnisse rund um Docker Networking sollte man sich komplett in der Linux Docker Host Umgebung orientieren.

Unter Windows mit dem Docker Desktop für Windows ist eben alles immer ein wenig Anders.

Docker Daemon

Docker - der defacto Standard

Im Zentrum - und eben manchmal auch im Zentrum der Kritik - steht der Service / Daemon für die gesamte Docker Technik: der Docker Daemon.

Docker Daemon Technik - Übersicht - Root User

Docker Daemon Technik - Übersicht - Root User

Beginnen wir unsere Übersicht zum Docker Daemon - oder ganz allgemein gesprochen - zur Docker Technik mit ein paar Pros:

  • De-Facto Industriestandard

  • Einfache Nutzung

  • Stellt alle nötigen Tools für die Fertigungskette von Container zur Verfügung: Registries anbinden, Images bauen, Container erstellen und nutzen

  • Riesige Nutzergemeinschaft mit Community

  • Für nahezu alle Technik-Plattformen verfügbar

  • Stellt eine konsistente Umgebung für Entwicklung, Testen und Produktion bereit.

Aber es gibt natürlich auch Cons (Kritikpunkte):

  • Recht schwergewichtig verglichen mit alternativen Container Managern

  • Wir benötigen einen Daemon - also einen Service, der normaler Weise mit Root-Rechten läuft. Und das kann Sicherheitprobleme nach sich ziehen.

Für die Nutzung von Docker-Technik ohne Root-Rechte gibt es seit ein paar Jahren eine hausinterne Lösung: Run the Docker daemon as a non-root user (Rootless mode) .

Neben vielen Vorbedingungen für diese Umsetzung hat diese Technik auch auf vielen Distros etwas von Bastelstunde. Es ist aber im Rahmen diverser Entscheidungen rund um Ihre Containertechnik eine Empfehlung und Tests wert.

Hinweis

Wir führen unsere Docker Kommandos als Standarduser aus (s.o. Grafik). Das haben wir allerdings einfach über eine Gruppenzugehörigkeit (Gruppe docker) erreicht und vereinfachen so die Nutzung der Docker-CLI (ohne sudo).

Podman und Co - die Containeralternativen

Als Alternative zu Docker - für eine vermeintlich sicherere weil Root-lose Containerlösung - wird häufig Podman genannt.

Das ist im Grunde auch völlig richtig, wenn man sich auf die Kernkompetenz des Containern bezieht.

Für die tägliche Arbeit und Umsetzung der folgenden Aufgaben (s.a. oben) muss man allerdings wieder Extra-Tools nutzen (franz.: from Docker to Podman).

Vergleich Docker vs. Podman auf franz. Infoportal

Vergleich Docker vs. Podman auf franz. Infoportal

Hier ein paar Beispiele für diese Umsetzungen:

Die zusätzlichen (externen) Tools können wieder eigene Probleme nach sich ziehen.

Docker Daemon Konfiguration

Verschiedene Möglichkeiten für die Docker Daemon Konfiguration:

  • Beim Starten über die Kommandozeile - siehe dockerd --help

  • Docker config: /etc/sysconfig/docker (z.B. DOCKER_OPTS="")

  • Systemweite config: /etc/docker/daemon.json

  • Benutzer config: ~/.docker/config.json

Tipp

Die verschiedenen Konfiguratione möglichst nicht mischen/kombinieren!

Overlay-Dateisysteme

Hier mal eine Grafik zur Overlay2FS Technik:

Overlay(2)FS

OverlayFS(2)-Modell (Bild: Liebel - Skalierbare Container-Infrastrukturen für Ihr Unternehmen)

Struktur für Overlay-Techniken (allgemein - von unten nach oben!):

  • Read-only Schichten

    • bootfs mit Kernel und cgroups

    • Basis Image (z.B. Alpine)

    • Application Image (z.B. Webserver Apache oder Nginx)

    • weitere Application-Layers

  • Read-Write Container Schicht (quasi on top)

    Jetzt wird aus einem Image ein Container!

Copy-On-Write (COW)

Zugriff durch die Schichten und in oberster Schicht (rw-Container) Kopie anlegen, für Daten aus den unteren ro-Schichten.

Ermitteln des Storage-Overlay-Systems

docker info | grep Storage

Übersicht Overlay-Systeme:

  • vfs (nur für Testing/Debugging)

  • aufs (ältester Docker Storage Driver; Advanced Multi-layered Unification Filesystem)

    Anm.: nur noch selten vertreten; siehe: Knoppix

  • overlay2 (die modernisierte overlay Variante und Docker-Standard)

    Anm.: Kernel >= 4.0 nötig!

  • btrfs (siehe openSUSE/SLES)

    Achtung (siehe Suse Installationen): Literatur empfiehlt noch keinen produktiven Einsatz!

  • zfs

    performant, hoher RAM-Verbrauch, Lizenzfragen; hinterfragen: Ubuntu nutzt zfs

  • devicemapper

    in allen Distros verfügbar; muss mit direct-lvm eingebunden werden (nicht: loop-lvm)

Siehe hierzu auch Ordnerstrukturen: /var/lib/docker/overlay...

Basis Images

Für die meisten Docker-Umsetzungen werden erst einmal vorbereitete Images genutzt. Und in den meisten Fällen bezieht man diese Standard-Images aus dem Docker Hub - einem Fundus für öffentlichen und nicht öffentlichen Images auf einem Webportal der Firma Docker.

Docker Hub Images Webportal

Docker Hub Images Webportal

Schauen wir uns verschiedene Aspekte rund um die Basis Images an.

Docker Hub

Alle genutzten Images in bisherigen Beispielen basieren auf Grund-Images aus dem Docker Hub.

Docker Hub = Online Docker Registry

Diese Basis Images werden per Docker Registry in Form von Repositories (z.B. debian, postgres, alpine) bereitgehalten . Später wollen wir uns von der Docker Registry trennen und werden unsere eigenen Registrys betreiben wollen.

Besondere Erwähnung gilt der Suche nach vertrauensvollen Basis Images: Docker Registry

Offizielle Docker Basis-Images

Offizielle Docker Basis-Images

Docker Scout

Früher benötigte man eine Registrierung - einen Docker Account auf dem Docker-Hub - für einen Einblick in die automatisierten Sicherheitsüberprüfungen (heute: Docker Scout) für die verschiedenen Images in einem Repository (siehe Reiter Tags).

Docker Hub - Image: ubuntu - Tag: latest - Sicherheitslücken

Docker Hub - Image: ubuntu - Tag: latest - Sicherheitslücken

Diese Analytik / Sicherheitsüberprüfung steht auch über den Docker Desktop oder die CLI zur Verfügung. Es gibt auch ein Docker Dashboard.

Official Images

Einige Images auf dem Docker Hub bekommen einen speziellen Prämium-Standard: sie werden Docker Official Images.

Docker Hub Official Images

Docker Hub Official Images

Hier folgen ein paar der offiziellen Images vom Docker Hub, deren Anzahl in den letzten Jahren stetig gesteigert werden konnte.

  • Januar 2019 - Anzahl: 16

  • Mai 2024 - Anzahl: 176

Hinweis

Den Terminus Official Images will Docker reserviert wissen!

Für eine erste Orientierung kann man die folgenden Links nutzen:

Und die letzte Filterung kann man auch in der Konsole vornehmen.

Docker CLI: Docker CLI Search

Beispielaufrufe:

docker search ubuntu                                # Images ubuntu suchen
docker search --filter is-official=true ubuntu      # offizielle Images Ubuntu
docker search --filter stars=10 debian              # min. 10 Sterne

Die offiziellen Images haben einen einfachen Namen: also alpine und nicht testcom/alpine!

  • Scratch - für das Imagen „FROM scratch“

  • Alpine - Ein Image-Build from scratch mit kleinem Linux-rootfs-TAR - der aktuelle Docker Builds Liebling!

    Werden wir noch häufiger nutzen und bedarf einer weiteren Vertiefung, da es andere Administrationsmechanismen (z.B. Paketverwaltung) nutzt, als die Standard-Linux-OS.

  • CentOS - Image des RED HAT Community OS

  • Debian - Image Debian

  • Fedora - Image des Red Hat Fedora OS

  • Ubuntu - Image von Canonicals Ubuntu

  • Busybox - The Swiss Army Knife of Embedded Linux

  • Bash - wie der Name schon sagt: nur die Bash

  • Amazon Linux - Amazon Linux is provided by Amazon Web Services (AWS)

Beachten: der Unterstrich in den Links (Beispiel Alpine: https://hub.docker.com/_/alpine) für die offiziellen Images.

Hier mal eine kleine Übersicht über gängige Image-Größen:

Distribution

Docker Image Größe

Alpine Linux

ca. 4 MByte

CentOS 7

ca. 210 MByte

Debian 9 (Stretch)

ca. 100 MByte

Ubuntu 16.04 LTS

ca. 110 MByte

Ubuntu 18.04 LTS

ca. 80 MByte

Tendenziell versuchen die Ersteller die Images immer kompakter zu bauen über die Jahre.

Registry/Repository:Tags

Über Repositories in einer (Docker) Registry können unterschiedliche Images aus einem Image-Fundus bereitgestellt werden.

Die Tags spezifizieren die genaue Version des Image. Im Grunde sollte man - auch für spätere Umsetzungen mit eigenen Registries - die komplette technische Beschreibung - den Pfad zu einem Image - wie folgt kennen.

Die Pfade werden dann beim pull | push genutzt.

Registry|IP     : Port  /  Vendorname/Repository  : Tag               # Struktur / Erkl.
-----------       ----     ---------------------    ---

                                          ubuntu                      # Official Image

                                  ubuntu/apache2                      # ubuntu hier Vendor

                       kasmweb/core-ubuntu-jammy   : 1.15.0-rolling   # spezifischer Tag

hub.example.org : 5000  /    joebrandes/myubuntu   : 1.0              # Private Registry

Was passiert bei einem docker pull ubuntu?

  • Registry (oder IP): Standard-Registry der Docker Umgebung wird genutzt

    Die Default Domain docker.io (aka „Docker Hub“) ist hart verdrahtet. Das soll bewirken, dass der obige Pull auf allen Docker Systemen dieselbe Aktion durchführt. Im Enterprise Segment haben da manche Firmen (siehe z.B. Red Hat) andere Vorstellungen ;-).

    Siehe auch: in docker system info taucht Registry-Pfad nicht mehr auf!

  • Port: Standard-Port bzw. nach Konfiguration Privater Registries

  • Vendorname/Repository: hier nur Repository weil Official Image!

    Als Pfad zum Docker Hub: https://hub.docker.com/_/ubuntu (den Unterstrich beachten)

  • Tag: Wenn der Tag weggelassen wird, dann versucht das System den Tag latest zu nutzen!

Beispielhaft Übersicht (online - Images Centos): https://hub.docker.com/_/ubuntu/tags

Hinweis

Auf dieser Übersicht sahen angemeldete Docker Hub User auch immer die Sicherheitsanalysieren zu den Images! Über Docker Scout stehen diese Infos heute (wieder) Allen zur Verfügung.

Das lässt sich auch in der Kommandozeile zaubern - allerding will Docker das eigentlich nicht! Man soll doch bitte die Weboberfläche nutzen.

Für Registry Version 2:

# Einfache Abrage per wget und grep
wget -q -O - "https://hub.docker.com/v2/namespaces/library/repositories/debian/tags?page_size=100" |
   grep -o '"name": *"[^"]*' |
   grep -o '[^"]*$'

# statt grep jetzt mit jq - sollte eh installiert sein
wget -q -O - "https://hub.docker.com/v2/namespaces/library/repositories/debian/tags?page_size=100" |
   jq -r '.results[].name'

# bei nicht offiziellen Images wird der Pfad entsprechend angepasst:
wget -q -O - "https://hub.docker.com/v2/namespaces/kasmweb/repositories/dekstop/tags?page_size=100" |
   jq -r '.results[].name'
# Anzahl der Tags:
wget -q -O - "https://hub.docker.com/v2/namespaces/kasmweb/repositories/dekstop/tags?page_size=100" |
   jq -r '.count'

# Curl version mit Schleife
# ===================================================
# ließe sich als function oder shell-script erweitern
i=0
while [ $? == 0 ]
do
   i=$((i+1))
   curl https://registry.hub.docker.com/v2/repositories/library/ubuntu/tags/?page=$i 2>/dev/null | jq '."results"[]["name"]'
done

Für Registry Version 1: (Anm.: Tool jq genutzt für lesbare Darstellung)

curl -sL https://index.docker.io/v1/repositories/library/centos/tags | jq '.[].name'

"latest"
"5"
"5.11"
"6"
"6.10"
"6.6"
"6.7"
"6.8"
"6.9"
"7"
"7.0.1406"
"7.1.1503"
"7.2.1511"
"7.3.1611"
"7.4.1708"
"7.5.1804"
"7.6.1810"
...

Für eigene Images gerne ein eigenes Präfix/Vendorname für die Images nutzen: joebrandes/alpine:15.0

Vertrauenswürdige Images

Wir nutzen oft öffentliche Images aus offiziellen Quellen.

Wie sieht es aber mit wirklich vertrauenswürdigen Images aus? Also Images, deren Inhalte wir letztlich komplett selber erstellt haben.

Hinweis

Jedes lokale erstellte Image kann später immer nur über eine Registry genutzt werden!

Aus diesem Grund folgen entsprechende Übungen immer erst nach der Beschäftigung und Nutzung von eigenen Registries und einem Check, ob solcherlei Images von Interesse sind.

Debian / Ubuntu: (c)debootstrap

Diese Systeme gehen mit einem eigenen Tool zum Extrahieren eines Tarball aus einem System an den Start:

debootstrap bzw. cdebootstrap (Article Stackexchange - debootstrap vs. cdebootstrap )

Das Tool kann über das gleichnamige Paket installiert werden.

debootstrap --variant=minbase bookworm ./rootfs
tar -C ./rootfs -c . | docker import - joebrandes/debian:12

Anm.: nach Test ca. 199 MB groß!

Eigenes Basis-Image

Wir erstellen/installieren ein Template-System (hier: openSUSE) und erstellen daraus einen Tarball.

tar --numeric-owner --exclude=/proc --exclude=/sys --exclude=/.snapshots -cvf opensuse.tar /

Dieses lässt sich dann auf dem Docker-Host wieder Importieren.

docker import opensuse.tar joebrandes/opensuse:42.3

Images from Scratch

Wir starten über die offizielle Docker Registry: Offizielles Image Scratch

Anm.: dieses besondere Image lässt sich nur - siehe Anleitung - in einem Dockerfile nutzen. Man kann es also nicht pullen!

Image-Erzeugungen per Skriptes - CentOS!!

Beispiel mit CentOS: (Anm.: lange nicht mehr gecheckt! Welche CentOS Version?)

YUM-Based mit Skript online

Oder über das Moby-Project: wget https://raw.githubusercontent.com/moby/moby/master/contrib/mkimage-yum.sh

CentOS lieferte auch ein Tool mit - Aufruf:

bash mkimage-yum.sh joebrandes/centos

Und vielleicht wurde schon deutlich: bei CentOS stellen sich mir viele Fragen.

SUSE/SLES sle2docker

Auf Ruby basierendes spezielles Tool mit speziellen Registries für Suse-Plattformen.

Auf Github Projektseite sle2docker hat sich viele Jahre nichts getan.

Dockerfile

Docker Referenz zu Dockerfile

Docker Referenz zu Dockerfile

Bis jetzt haben wir fertige Images (siehe Quelle Docker Hub) genutzt und mit diesen Images die Container erstellt.

Die meisten Images waren auch bereits ordentliche Vorlagen, aber man würde in Ubuntu zum Beispiel vielleicht gerne das Paket iproute2 nachinstallieren, um den ip Befehl nutzen zu können.

Wir wollen jetzt unsere eigenen Images erstellen und bedienen uns hierzu eines Dockerfile, das alle nötigen Anweisungen / Direktiven enthält!

Hinweis

Für die Image-Erzeugung werden wir uns zumeist auf Basis Images der Container-Gemeinschaft berufen (siehe Direktive FROM).

Aber natürlich könnte man auch Image from Scratch erzeugen. Die entsprechenden Ausführungen kommen in einem späteren Abschnitt.

Schauen wir uns die Datei Dockerfile und den Docker Build Prozess einmal an.

Kurzanleitung Build

Falls jemand auch einmal anderen Trainern beim Dockern zusehen möchte nutze bitte den folgende YT-Link. Und der Kollege bezeichnet sich auf seiner Seite übrigens als Full Nerd - liegt also voll auf meiner Wellenlänge.

YT Techno Tim - Build YOUR OWN Dockerfile, Image, and Container - Docker Tutorial

YT Techno Tim - Build YOUR OWN Dockerfile, Image, and Container - Docker Tutorial

YT Techno Tim - Build YOUR OWN Dockerfile, Image, and Container - Docker Tutorial

Die Kurzanleitung als Liste:

  • Einen Ordner für Image Build Prozess erstellen - also eigentlich

    alles wie immer in der IT: 1 Projekt - 1 Ordner

  • Datei- und Ordnerstrukturen im Ordner bereitstellen

    z.B. Skripte, Webdateien, Ordner mit CSS, JS, … Link zu Github-Repo Video-Tutorial

  • Datei Dockerfile im Ordner erzeugen - Dockerfile aus YT-Video - einige Direktiven auskommentiert, weil im Base Image nginx:alpine bereits definiert!

    FROM nginx:alpine
    COPY src/html /usr/share/nginx/html
    
    # ENV PRODUCTION=true
    
    # this is really just documentation
    # EXPOSE 80
    
    # nginx defaults to this command
    # CMD ["nginx", "-g", "daemon off;"]
    
  • Inhalt und Konfiguration für Image festlegen (Direktiven)

  • Mit docker build Befehl ein neues Image lokal erzeugen

    docker build -t mynginx:1.0 . (Punkt am Ende beachten: akt. Verzeichnis)

  • mit docker push (ggf.) im Docker-Hub oder einer privaten Regitstry veröffentlichen

Alternative Veröffentlichungstechniken für eigene Images:

  • GitHub (oder andere Git-Repos) für automatisierte Builds

  • Private Image Repository auf Docker Hub

  • Eigenes Docker Repository

Links:

Dockerfile Syntax

Dockerfile Direktiven

Die wichtigsten Schlüsselwörte für ein Dockerfile als Tabelle und mit ein paar folgenden Anmerkungen zum Verständnis.

Schlüsselwort

Bedeutung

ADD

kopiert Dateien in das Dateisystem des Images

COPY

kopiert Dateien aus Projekverzeichnis in das Image

Scheint wie ADD - Erläuterungen s.u.

CMD

führt Kommando beim Start des Containers aus

ENTRYPOINT

führt Kommando beim Start des Containers aus

Scheint wie CMD - Erläuterungen s.u.

ENV

setzt eine Umgebungsvariable

EXPOSE

gibt die aktiven Ports an

FROM

gibt das Basis-Image an

LABEL

legt Zeichenkette fest

RUN

führt das Kommando aus

USER

Account für RUN, CMD und ENTRYPOINT

VOLUME

gibt Volume-Dirs an

WORKDIR

Arbeitsverzeichnis für RUN, CMD und ENTRYPOINT

Erläuterungen:

Analyse / Erläuterungen zu ADD vs. COPY und CMD vs. ENTRYPOINT:

ADD vs. COPY

Die Direktiven scheinen ja dasselbe zu tun, aber ADD kann…

  • … auch mit URL umgehen

  • … auch (wie COPY) Verzeichnisinhalte komplett kopieren

  • … mit TAR-Archiven arbeiten/entpacken (gzip, bzip2, xz)

Beide können mit –chown=user:group Parameter umgehen.

In Kürze: COPY nur für einfaches Kopieren einer lokalen Datei.

CMD vs. ENTRYPOINT

Feinheiten der Startkommandos für Container

Wenn man Container mit mit docker run Komandos anfügt, dann …

  • … wird bei CMD das angefügte Kommando anstelle von CMD ausgeführt

  • … wird bei ENTRYPOINT das Kommando hinzugefügt

Ubuntu Apache Webserver

Beispiel: Einfacher Apache2 Webserver mit http/https und eigener Start-/Indexseite

Fangen wir mit der Grundstruktur an.

Projektordner

Wir benötigen einen Basis- oder Projektordner $HOME/projektapache mit einer Struktur.

Struktur Projektordner mit Dockerfile
.
├── Dockerfile
└── samplesite
   ├── index.html
   └── style.css

Dockerfile erstellen

Das Dockerfile beschreibt mittels Direktiven den gewünschten Buildprozess.

Dockerfile mit Basis Image ubuntu:22.04 und Apache2 Installation
# Datei Dockerfile
FROM ubuntu:22.04

LABEL maintainer "name@somehost.com"
LABEL description "Test"

# Umgebungsvariablen und Zeitzone einstellen
# (erspart interaktive Rückfragen)
ENV TZ="Europe/Berlin" \
    APACHE_RUN_USER=www-data \
    APACHE_RUN_GROUP=www-data \
    APACHE_LOG_DIR=/var/log/apache2

# Apache installieren, unnötige Dateien aus dem Paket-Cache
# gleich wieder entfernen, HTTPS aktivieren
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    echo $TZ > /etc/timezone && \
    apt-get update && \
    apt-get install -y apache2 && \
    apt-get -y clean && \
    rm -r /var/cache/apt /var/lib/apt/lists/* && \
    a2ensite default-ssl && \
    a2enmod ssl

EXPOSE 80 443

# gesamten Inhalt des Projektverzeichnisses
# samplesite nach /var/www/html kopieren
COPY samplesite/ /var/www/html

CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

Projektdokumente

Hier handelt es sich um eine einfach Website mit einer CSS-Styling-Datei.

Webdokument samplesite/index.html

Website index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <link rel="stylesheet" href="style.css">
  <title>Testseite für Container Seminar Joe B.</title>
</head>

<body>
<h1>Testseite für Container Seminar Joe B.</h1>
<p>Diese Seite wird von einem Apache-Webserver präsentiert, der
in einem Docker-Container läuft.
<p>Als Base-Image kommt <tt>ubuntu:22.04</tt>
zum Einsatz.</p>
</body>
</html>

Webdokument samplesite/style.css (CSS Style)

Stylingdatei style.css
body {
    font-family: sans-serif;
}
h1, h2 {
    color: #dd1100;
}

Docker Build Prozess

Es folgt ein beispielhafte Vorgehen - in der Konsole - für das Beispiel: Einfacher Webserver.

Arbeitsschritte im Terminal / in der Shell
# Ordnerstruktur erstellen
mkdir -p $HOME/projektapache/samplesite

# in das Projektverzeichnis wechseln
cd $HOME/projektapache

# HTML/CSS-Site in HTML-Ordner kopieren
touch samplesite/index.html samplesite/style.css

# Dockerfile erstellen und Inhalt bereitstellen
touch Dockerfile

# Image erzeugen / taggen / bitte Punkt am Ende nicht vergessen!
docker build -t joebrandes/testwebserver .

# Container erzeugen
# -d                           Prozess im Hintergrund (detached)
# -p 8080:80 -p 8443:443       Ports/Publish
# -h webtest                   Hostname festlegen
# --name testwebserver         Containername
# joebrandes/testwebserver     Image für Container / Tag:latest
docker run -d -p 8080:80 -p 8443:443 -h webtest \
    --name testwebserver joebrandes/testwebserver

Die normale (und https-gesicherte) Seite sollte sich jetzt im Browser über die entsprechenden URLs öffnen lassen!

Dockerfile Beispiele

Ein paar Beispiele aus Literatur Öggl/Kofler und beliebig Quellen online…

PHP 8.2 + Apache + Debian

Einfaches Images mit PHP 8 und Apache2 Webserver basierend auf Basisimage mit dieser Kombination.

1FROM php:8.2-apache
2ENV TZ="Europe/Amsterdam"
3COPY index.php /var/www/html

Man erkennt die Festlegung einer Umgebungsvariablen und das Kopieren einer Datei in den Container. Man sollte wieder eine Recherche zum Image auf dem Docker Hub durchführen.

Image erstellen mit (z.B.): docker build -t joebseminar/myphpapache:1.0 .

Zu beachten ist hier wieder der Punkt am Ende für den Basisordner (Bedeutung: aktueller Ordner) des Build-Prozesses mit dem Dockerfile und der index.php.

Ubuntu 22.04 mit Package iproute2

Mit Basisimage Ubuntu (Tag: 22.04) ein Image mit Editor-Installation joe und Aufräumen der Apt-Technik.

Hier stellen wir auch eine Shell (hier: Bash) bereit, mit der wir später „-i / –interactive“ und „-t / –tty“ über ein Terminal kommunizieren können.

Dockerfile nach Öggl/Kofler (S. 63)
1FROM ubuntu:22.04
2LABEL maintainer "name@somehost.com";
3RUN apt-get update && \
4 apt-get install -y iproute2 && \
5 apt-get clean && \
6 rm -rf /var/lib/apt/lists/*
7CMD ["/bin/bash"]

Zu beachten ist hier, dass durch das einzeilige RUN-Command die Image-Größe und die Layer-Erzeugung (hier: 1 Layer für RUN) optimiert wird.

Alpine Linux mit Apache2

Hier sind wir durch Recherchen zu Alpine Linux und diversen Dockerfile Analysen herausgefordert worden (Anm.: Apache als Prozess am Laufen halten im Container!)

Dockerfile für Alpine Linux mit Apache2
 1FROM alpine
 2
 3LABEL maintainer "dummy@aol.com"
 4LABEL description "Test Alpine und Apache"
 5
 6RUN apk update && apk upgrade && \
 7    apk add --no-cache apache2 libxml2-dev apache2-utils
 8# rm -rf /var/cache/apk/*
 9
10# war zwischendurch nötig:
11# RUN mkdir /run/apache2
12
13ENV APACHE_RUN_USER=apache \
14    APACHE_RUN_GROUP=www-data
15
16EXPOSE 80 443
17
18COPY samplesite/ /var/www/localhost/htdocs
19
20CMD ["/usr/sbin/httpd", "-DFOREGROUND"]

Haskell und Ubuntu mit Pandoc

Als ausführlicheres Dockerfile-Beispiel liefern Öggl/Kofler für „Pandoc“.

Hinweis

Die Umsetzungen sind aufgrund fehlender Font-Einbindungen nicht komplett und funktionstüchtig.

Dockerfile pandoc Installationen nach Öggl/Kofler (S. 73ff.)
 1# Datei Dockerfile
 2FROM haskell
 3
 4# Pakete installieren
 5RUN apt-get update -y && \
 6    apt-get install -y -o Acquire::Retries=10 \
 7                     --no-install-recommends \
 8      texlive-latex-recommended \
 9      texlive-latex-extra \
10      texlive-fonts-recommended \
11      texlive-lang-german \
12      texlive-pstricks \
13      imagemagick \
14      unzip \
15      python3 \
16      ghostscript \
17      less && \
18    apt-get clean && \
19    rm -rf /var/lib/apt/lists/*
20
21# Pandoc installieren
22RUN cabal update && \
23    cabal install pandoc-2.1.1 && \
24    ln -s /root/.cabal/bin/pandoc /usr/bin/pandoc
25
26# Mitteleuropäische Zeitzone
27# (siehe https://serverfault.com/questions/683605)
28RUN cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime
29
30# Fonts für LaTeX installieren
31# ADD rheinwerkfonts.tgz /usr/local/share/texmf
32# RUN texhash
33
34# Volume /data, bei docker run mit dem Arbeitsverzeichnis
35# verbinden, also: docker run -v $(pwd):/data
36WORKDIR /data
37VOLUME  ["/data"]
38
39ENTRYPOINT ["/bin/bash"]

Die Kollegen richten also - wie ich mit SphinxDoc - eine Umgebung ein, in der sie mit Hilfe von Markdown und dem Werkzeug pandoc dann HTML als auch LaTeX-Versionen für Print/PDF generieren können.

Auch hier gibt es eine aktualisierte Variante:

Dockerfile pandoc Installationen nach Öggl/Kofler (AKTUELLE Version)
 1# Datei Dockerfile
 2FROM ubuntu:20.04
 3ENV TZ="Europe/Berlin"
 4RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
 5    echo $TZ > /etc/timezone && \
 6    apt-get update -y && \
 7    apt-get install -y -o Acquire::Retries=10 \
 8                     --no-install-recommends \
 9      texlive-latex-recommended \
10      texlive-latex-extra \
11      texlive-fonts-recommended \
12      texlive-lang-german \
13      texlive-pstricks \
14      texlive-fonts-extra \
15      imagemagick \
16      unzip \
17      python3 \
18      ghostscript \
19      locales \
20      joe \
21      vim \
22      curl \
23      wget \
24      ca-certificates \
25      less && \
26    apt-get clean && \
27    rm -rf /var/lib/apt/lists/*
28
29# Pandoc installieren
30RUN curl -L https://github.com/jgm/pandoc/releases/download/2.14/pandoc-2.14-1-amd64.deb \
31   -o /tmp/pandoc.deb && \
32   dpkg -i /tmp/pandoc.deb && \
33   rm /tmp/pandoc.deb
34
35# Fonts installieren
36# (die Font-Datei dürfen wir nicht weitergeben)
37# ADD myfonts.tgz /usr/local/share/texmf
38# RUN texhash
39
40# Volume /data, bei docker run mit dem Arbeitsverzeichnis
41# verbinden, also: docker run -v $(pwd):/data
42# Fedora, RHEL:    docker run -v $(pwd):/data:z
43VOLUME  ["/data"]
44
45# Startkommando
46ENTRYPOINT ["/bin/bash"]

Ubuntu + Apache2 + https + Projekt

Beispiel für einfachen Webserver: (s.a. Vorheriger Abschnitt)

Aktualisiertes Beispiel:

Dockerfile für Webserver nach Öggl/Kofler (AKTUELLE Auflage!)
 1# Datei Dockerfile
 2FROM ubuntu:22.04
 3
 4LABEL maintainer "name@somehost.com"
 5LABEL description "Test"
 6
 7# Umgebungsvariablen und Zeitzone einstellen
 8# (erspart interaktive Rückfragen)
 9ENV TZ="Europe/Berlin" \
10    APACHE_RUN_USER=www-data \
11    APACHE_RUN_GROUP=www-data \
12    APACHE_LOG_DIR=/var/log/apache2
13
14# Apache installieren, unnötige Dateien aus dem Paket-Cache
15# gleich wieder entfernen, HTTPS aktivieren
16RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
17    echo $TZ > /etc/timezone && \
18    apt-get update && \
19    apt-get install -y apache2 && \
20    apt-get -y clean && \
21    rm -r /var/cache/apt /var/lib/apt/lists/* && \
22    a2ensite default-ssl && \
23    a2enmod ssl
24
25EXPOSE 80 443
26
27# gesamten Inhalt des Projektverzeichnisses
28# samplesite nach /var/www/html kopieren
29COPY samplesite/ /var/www/html
30
31CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

Ich habe im folgenden mal eine alter Version belassen, um mögliche Probleme aufzuzeigen.

Gefahr

Für aktuellere Docker und Ubuntu Kombi fehlerhafte Umsetzung!

Dockerfile für Webserver nach Öggl/Kofler (ALTE AUFLAGE!)
 1# Datei Dockerfile
 2FROM ubuntu:18.04
 3
 4LABEL maintainer "kontakt@kofler.info"
 5LABEL description "Test"
 6
 7# Apache installieren, und unnötige Dateien aus dem Paket - Cache
 8# gleich wieder entfernen
 9RUN apt-get update && \
10    apt-get install -y apache2 && \
11    apt-get -y clean && \
12    rm -rf /var/cache/apt /var/lib/apt/lists/*
13
14# HTTPS -Unterstützung aktivieren
15RUN a2ensite default-ssl && a2enmod ssl
16
17ENV APACHE_RUN_USER=www-data \
18    APACHE_RUN_GROUP=www-data \
19    APACHE_LOG_DIR=/var/log/apache2
20
21EXPOSE 80 443
22
23# gesamten Inhalt des Projektverzeichnisses
24# samplesite nach /var/www/html kopieren
25COPY samplesite/ /var/www/html
26
27CMD ["/usr/sbin/apache2ctl" , "-D" , "FOREGROUND"]

Alpine Linux

Für das Linux zeichnet die Firma Gliderlabs verantwortlich: Alpine Linux Website.

Alpine Linux Website

Alpine Linux Website

Die Website sagt es ja ganz richtig: Small. Simple. Secure. Allerdings wird verschwiegen, dass man sich damit auch gerne den meist gewöhnten Komfort bei der Nutzung der Standard-Distros schenken kann!

Quellen zur weiteren Vertiefung mit Alpine Linux:

Kommen wir zu weiteren Erklärungen dieser sehr speziellen Distribution.

Alpine Technik

So klein und schön Alpine Linux auch ist - es verhält und nutzt sich allerding auch anders als seine anderen Linux-Alternativen.

  • Als C-Standardbibliothek wird musl statt glibc genutzt. Das stellt häufig ein Problem bei zu kompilierenden Programmen dar.

    Es existiert für Alpine Linux optimierte glibc (pkg-glibc ).

  • Einfachere Auswertung von /etc/resolv.conf (keine domain und search Beachtung)

  • Als Init-System wird OpenRC statt systemd oder sysv-init genutzt, welches eher an klassisches init-System erinnert. Alpine arbeitet mit /etc/inittab.

    Wichtig: OpenRC ist in in Images vorhanden - arbeitet aber nicht! S.a. Logging (rsyslog nachinst.)

  • Linux Kommandos stammen von BusyBox.

Alpine Linux lässt sich schnell ausprobieren:

docker run -it -h alpine --name alpine alpine

Und hierbei nutzen wir wieder einmal den Tag latest.

Image alpine:latest

Immer mal wieder stoße ich in Seminaren auf die Erklärungen zum Tag :latest. Und da ist gut, wenn mal eine Infoseite hat, welche die wichtigsten Fakten zusammenträgt.

Hinweis

Die folgende Zusammenstellung zum Image alpine:latest soll keine Besonderheiten der Alpine Image Technik darstellen, sondern sich der besonderen Analyse und Erkenntnis rund um Tagbezeichner widmen.

Eine mögliche Ausgabe in der Konsole: hier mit Tag alpine:latest als die Versionsnummer für Alpine 3.8.2 war!

docker run alpine - OLD
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
cd784148e348: Pull complete
Digest: sha256:46e71df1e5191ab8b8034c5189e325258ec44ea739bba1e5645cff83c9048ff1
Status: Downloaded newer image for alpine:latest
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.8.2
PRETTY_NAME="Alpine Linux v3.8"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"
/ #

Container-Analyse (in separater Shell natürlich): docker ps -s (Größen anzeigen)

Die Ausgabe zeigt einen nur wenige Bytes großen Container, was normal ist für frisch erstellte Container.

Für eine aktuellere Version 3.19.1 von Alpine gelten die folgenden Aufrufe und man sollte die jeweilige SHA256 Prüfsummen nachvollziehen. In diesem Fall auch über die Build Pipeline Jenkins, wo sich die Prüfsummen für jeden erstellten Tag checken lassen.

Wir machen mal einen frischen latest (3.19.1) Pull:

Docker Image Pull alpine:latest mit Version 3.19.1
docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
4abcf2066143: Already exists
Digest: sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

Die Anregung für das Kommando findet sich auch auf dem Docker Hub.

Docker Hub Infos zum Alpine Image

Docker Hub Infos zum Alpine Image

Hier der passende Screenshot zur Version - also dem Tag:

Docker Hub Alpine Tag: latest (amd64)

Docker Hub Alpine Tag: latest (amd64)

Wir checken die Alpine-Version des alpine:latest Image über einen docker run Befehl.

Image nutzen und Alpine Version analysieren
docker run -it alpine
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.19.1
PRETTY_NAME="Alpine Linux v3.19"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
/ #

Eine Image Liste für Alpine:latest (hier: 3.19.1) zeigt:

Docker Image Liste mit –no-trunc für lpine:latest Analyse
docker image ls --no-trunc
REPOSITORY       TAG       IMAGE ID                                                                  CREATED         SIZE
...              latest    sha256:2c38ae17a4b9252b1f7a310e9485e68e5294c0a241d2a652808ac14fc0b83511   4 days ago      119MB
alpine           latest    sha256:05455a08881ea9cf0e752bc48e61bbd71a34c029bb13df01e40e3e70e0d007bd   3 months ago    7.38MB
...              latest    sha256:e9800d4dc15dd264ea6cd95b742cdf6b125373fb3a346ebf2af4a375fa7da3b7   8 months ago    1.11GB

Beim Löschen des Image sieht man die folgenden Infos.

Docker Image alpine:latest löschen
docker image rm alpine:latest
Untagged: alpine:latest
Untagged: alpine@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b
Deleted: sha256:05455a08881ea9cf0e752bc48e61bbd71a34c029bb13df01e40e3e70e0d007bd

Bei einer Docker Image Inspektion - siehe docker inspect - finden wir die beiden SHA256 Prüfsummen wie folgt zugewiesen:

Image Inspect alpine:latest (Auszug)
[
    {
        "Id": "sha256:05455a08881ea9cf0e752bc48e61bbd71a34c029bb13df01e40e3e70e0d007bd",
        "RepoTags": [
            "alpine:latest"
        ],
        "RepoDigests": [
            "alpine@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b"
        ],
        "Parent": "",

    }

]

Der Jenkins Job zeigt unter der (zum Zeitpunkt aktuellen) Adresse für den letzten erfolgreichen Build

Jenkins Amd64 Job Alpine latest zeigt sha256:05455a08881ea9cf0e752bc48e61bbd71a34c029bb13df01e40e3e70e0d007bd (Voila)

SHA256 Prüfsumme für letzten erfolgreichen Build für alpine:latest

SHA256 Prüfsumme für letzten erfolgreichen Build für alpine:latest

Dieselben Prüfsummen zeigen (zum Zeitpunkt) die image-tags

  • alpine:3.19.1

  • alpine:3.19

  • alpine:3

  • alpine:latest

Und genau so findet man die Tags auch in der Docker Hub Doku zum Alpine Image (s.o.) aufgelistet!

Alpine Shell - BusyBox

Die Shell ist standarmäßig /bin/sh bzw. /bin/ash (Teil von BusyBox).

Die Bash lässt sich nachinstallieren, was den Komfort erhöht, aber auch die Speichergrößen deutlich anschwellen lässt.

apk add --update bash bash-completion

BusyBox

Die BusyBox nthält ca. 140 Linux Standardkommandos, die als Symlinks zu Tool busybox integriert sind.

Siehe: ls /bin /sbin -l

Online Busybox Hilfen: Hilfe zu BusyBox

Alpine Hilfe / Doku

Hilfen / Dokumentation

Es gibt keine man-Pages oder den Pager less! Nachinstallationen wären aber möglich mit:

apk add --update man man-pages mdocml-apropos less less-doc
export PAGER=less
apk add --update bash-doc

Die man-Pages der Tools habe immer die doc-Paketendung!

Hilfe und weiterführende Informationen zu diesen Topics: siehe Alpine Wiki

Paketverwaltung apk

Das Verwalten von Paketen (Software) mit apk unter Alpine Linux in Kürze:

Kommando

Funktion

apk add <paketname>

installiert Pakete

apk del <paketname>

entfernt Paket

apk info (<paketname>)

listet installierte Pakete auf (auch mit -L und --who-owns)

apk search <paketname>

sucht Paket in Paketquellen

apk stats

zeigt Anzahl Pakete

apk update

zeigt, welche Pakete aktualisierbar sind

apk upgrade

aktualisiert Pakete

Paket auflisten lassen in Roh-Alpine: apk info | sort

apk info
/ # apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/x86_64/APKINDEX.tar.gz
v3.8.2-19-g151c2021d6 [http://dl-cdn.alpinelinux.org/alpine/v3.8/main]
v3.8.2-18-gd7f33f856a [http://dl-cdn.alpinelinux.org/alpine/v3.8/community]
OK: 9546 distinct packages available
/ # apk info | sort
alpine-baselayout
alpine-keys
apk-tools
busybox
libc-utils
libressl2.7-libcrypto
libressl2.7-libssl
libressl2.7-libtls
musl
musl-utils
scanelf
ssl_client
zlib
/ #

Empfehlung / Übung: ein apk update vor irgendwelchen Installationen / Konfigurationen! Es gibt gut 9500 Pakete!

Tipp

Im Dockerfile auch mit apk ... --no-cache zum Updaten und Installieren arbeiten: Und nach den apk Befehlen wird das System wieder bereinigt!

Hier ein beispielhafter Aufruf:

apk mit Parametern no-cache nutzen
# Datei Dockerfile
...
RUN apk update --no-cache && apk upgrade --no-cache && \
    apk add --no-cache \
    build-base \
    python-dev \
    jpeg-dev \
    zlib-dev \
    ffmpeg \
    && pip install sigal \
    && pip install cssmin \
    && apk del build-base python-dev jpeg-dev zlib-dev

Paketübersicht online: https://pkgs.alpinelinux.org/packages

Online sind auch die Paketquellen erkennbar. Anzeige der Paketquellen mit: cat /etc/apk/repositories

Docker Registries

Wir wollen unsere eigene Docker Registry betreiben. Verwirrender Weise wird die Docker Registry auch unter dem Namen Distribution bezeichnet.

Distribution - Registry als Official Image auf Docker Hub

Distribution - Registry als Official Image auf Docker Hub

Wie auch immer! Für die Container-Registries stehen verschiedene technischen Umsetzungen zur Verfügung.

Die hier beschriebene Docker Registry steht in den Versionen Version 1, 2 und seit kurzem auch (per Vorabversion) in Version 3 zur Verfügung.

Vor den Bereitstellungen sollte man die entsprechenden Versionen recherchieren, falls man die Software direkt aus der Paketverwaltung der Distribtutionen installieren wollte (siehe CentOS / RHEL oft noch in mit V1).

Registry Techniken:

  • V1 - in Python implementiert

  • V2 - in Golang (Aktuell)

  • V3 in Entwicklung/Alpha seit 2024

Desweiteren starten wir erst einmal mit Umsetzungen von Insecure Registry - also ohne verschlüsselte Transporte.

Registry bereitstellen

Die technische Umgebung zum Verteilen (siehe Distribution) von Container-Images folgt einem offenen Standard. Somit haben wir verschiedenste Möglichkeiten um unsere Images zu verteilen bzw. zu hosten.

übersicht über Bereitstellungen für Docker Registries - ohne Anspruch auf Vollständigkeit:

  • Registry Software auf Github https://github.com/docker/distribution

  • Registry als Docker Image vom Docker Hub https://hub.docker.com/_/registry

  • Software in Linux-Distributionen - und wieder: bitte die Version der Registry vorher klären

  • Docker Hub Account

    Anm.: der Account hat weitere Vorteile bei der Nutzung von Docker Hub Images! Und man kann private und öffentliche Images pflegen.

Und natürlich kommen unterschiedlichste Anbieter von Cloud-Plattformen auch in Frage.

  • Amazon Elastic Container Regitstry (ECR)

  • Azure Container Registry (ACR)

  • GitHub Package Registry - Pull: ghcr.io/vendor/repo:tag

  • GitLab Container Registry - Pull: registry.gitlab.com/vendor/repo:tag

  • Google Artifact Registry (GAR) - ehemals Google Container Registry (GCR)

  • Red Hat Quay (sieher Podman.io) - Pull: quay.io/vendor/repo:tag

  • jFrog Container Registry - Partner von Docker Inc. seit 2021

    https://jfrog.com/de/download-jfrog-container-registry/

    Pull: docker pull releases-docker.jfrog.io/jfrog/artifactory-jcr:latest

jFrog Container Registry - alle Plattformen

jFrog Container Registry - alle Plattformen

Zum Abschluss: die Docker Technik auf dem Entwicklungsrechner hält eine feste Konfiguration vor, wo sie standardmäßig die Registry erwartet: den Docker Hub!

Das konnte man früher auch noch über die docker system info ausgeben lassen.

docker system info | grep -i registry
Registry: https://index.docker.io/v1/

Bei der Nutzung von Docker ist also der Docker Hub als Registry fix. Für die Nutzung eigener (Privater) Registries benutzen wir entsprechende Bezeichner/Pfade für die Images zum Ausschecken (pullen) und Einchecken (pushen) von Images.

Um die verschlüsselte Kommunikation mit unseren Privaten Registries oder die Nutzung von Registry-Mirrors werden wir uns (ggf.) später kümmern.

Registry Image

Die Umsetzung möglichst auf Debian-System. Anm./Alternative: eigenes Docker-Registry-Tool dann z.B. mit Suse-System.

Ein offizielles Registry-Image lässt sich auf dem Docker Hub finden und mit docker-compose nachhaltig implementieren.

Für eine Ansprache der eigenen Docker Registry nutzen wir z.B. hub.example.org oder andere FQDNs nach Wahl.

Diese Adresse müssen wir natürlich auflösen lassen - am einfachsten über die /etc/hosts.

Tipp

Bei der Nutzung Hyper-V Default Switch erhält man FQDNs und Namensauflösungen: hostname.mshome.net.

Aber: keine echtes DNS und Routing!

Jetzt benötigen wir nur noch ein Docker Compose Verzeichnis für die docker-compose.yml und schon kann es losgehen.

Docker Compose Ordner anlegen

mkdir ~/docker/registry && cd $_

und in Ordner wechseln.

docker-compose.yml (Registry)
registry:
  image: registry:2
  container_name: registry
  restart: always
  ports:
    - 5000:5000
  volumes:
    - /srv/docker/registry:/var/lib/registry

Und los geht es: docker-compose up -d

Damit jetzt auch der unsichere Zugriff auf die Registry möglich ist, muss Docker über /etc/docker/daemon.json entsprechend konfiguriert werden:

{
    [ggf. Vorherige Einträge - diese Zeile weglassen;-)],
    "insecure-registries": [ "hub.example.org:5000" ]
}

Testen der eigenen Registry:

docker pull ubuntu:16.04
docker tag ubuntu:16.04 hub.example.org:5000/ubuntu:16.04
# und jetzt pushen:
docker push hub.example.org:5000/ubuntu:16.04
# löschen der Images:
docker image rm ubuntu:16.04
docker image rm hub.example.org:5000/ubuntu:16.04
# und jetzt das Image aus eigener Registry holen:
docker pull hub.example.org:5000/ubuntu:16.04

Die genutzte Registry (quasi der Weg für das Image) erschließt sich also aus dem Image-Namen!

Hinweis

Ändern Sie den Namen der Registry muss man Anpassungen an Dockerfiles und docker-compose.yml-Dateien vornehmen!

Analyse des Registry-Containers:

docker exec registry ps aux
docker exec registry cat /etc/docker/registry/config.yml

Mit dieser config.yml kann die Registry Konfiguration dann auch angepasst/überschrieben werden.

Links zur Docker Registry:

Registry Distro-Package

Die Umsetzung erfolgt hier beispielhaft auf einem openSUSE-System mit dem Paket docker-distribution-registry.

Es muss mit systemctl entsprechend gecheckt (systemctl status registry) und gestartet (systemctl start registry) werden.

Auch hier muss wieder eine Konfiguration für insecure-registries nach obigem Beispiel für die Standard-Registry vorgenommen werden.

Also über /etc/docker/daemon.json entsprechend konfiguriert:

{
    [ggf. Vorherige Einträge - diese Zeile weglassen;-)],
    "insecure-registries": [ "opensuse.mshome.net:5000" ]
}

Repositories einer Registry anzeigen lassen:

curl http://opensuse.mshome.net:5000/v2/_catalog

Hinweis

Tests erst einmal nur mit den jeweils lokalen Maschinen, sonst benötigt man ja vollständiges DNS und Routing!

Das Löschen von Images in Privaten Registries ist extrem unhandlich und umständlich (Literatur: Liebel, Kap. 6.4.4, S. 418ff).

Registry Docker Hub

Empfehlung: eigenen Account auf https://hub.docker.com/signup erzeugen für Repositories.

Docker Befehle: docker login | logout

Authentifizierung hinterlegt (!) in /etc/docker/key.json

Docker Hub

Docker Hub - Webportal

Anm.: und ich kann nicht garantieren, dass diese tollen images da heute noch liegen ;-) !

Einzel Container

Wir nutzen einen einzelnen Container (Bild: bernd-dittrich-z6-nbPBBeUY-unsplash)

Wir nutzen einen einzelnen Container (Bild: bernd-dittrich-z6-nbPBBeUY-unsplash)

Die folgenden Beispiele geben einfach Umsetzungen mit einem einzelnen Container wieder.

Zur Erinnerung:

  • Container werden per create oder run aus Images erzeugt

  • Images beziehen wir entweder

    • aus Registries - Docker Standard: hub.docker.com oder

    • aus eigenen build Prozessen

Das grundlegende Image mit dem wir containern wollen hat immer eine technische Vorgeschichte und eine Möglichkeit die Umgebung (das Environment) zu beeinflussen.

Wir sollten also bei dem Nutzen von Images immer eine verfügbare Dokumentation heranziehen. Und damit die Vorgehensweise nachvollziehbar und trasparent ist beziehe ich mich hier jeweils erst einmal auf den Docker Hub. Aber natürlich ließen sich jeweils auch Alternativen nutzen.

Hinweis

Wer in den folgenden Abschnitten Alpine Container vermisst, sei an den Abschnitt Image alpine:latest erinnert. Dort wird das Image alpine:latest genauer analysiert und das Kapitel Alpine Linux widmet sich dem Alpine Linux in Gänze.

_/hello-world

Link: https://hub.docker.com/_/hello-world

Warum kommt der Trainer denn jetzt schon wieder mit hello-world an? Wir wollen erkennen, warum ein hello-world-Container sofort wieder aus der Containerliste mit laufenden Containern verschwindet und wo die Textinfo / die Ausgabe herkommt.

Image hello-world auf dem Docker Hub - Infoseite

Image hello-world auf dem Docker Hub - Infoseite

Das Image für den Funktionstest der Docker Umgebung: docker run hello-world.

Wir finden die Infos zum Image unter folgenden Links

Eine Besonderheit diese Image sind die Shared Tags für auch Nicht-Linux-Container - siehe:

Auf dem GitHub Repo kann man den Quellcode hello.c (Blob hello.c ) des Programms finden, der beim starten eine hello-world Containers ausgeführt wird.

Danach ist das Programm - und damit der einzige Prozess des Containers - beendet! Also wird auch der Container beendet, weil er keinen Prozess mehr hat, der ihn am Leben hält.

Testing mit erzeugten Containern:

  • Alle Container auflisten, die das Image hello-World nutzen:

    docker container ls -a --filter ancestor=hello-world

  • Einen dieser Container wieder starten (Ausgabe hello-world):abbr:

    docker container start -i <container-name>

    Anm.: wir benötigen den Schalter -i | --interactive für die Standardausgabe in Konsole. Ansonsten sehen wir nur kurz Feedback mittels Container-ID, dass der Container gestartet wurde.

Hinweis

Der Schalter -t | --tty wird für die Verbindung mit einer Shell-/ Terminal-Technik im Container benutzt. Der Container von Image hello-world besitzt keine Shell!

_/ubuntu

Link: https://hub.docker.com/_/ubuntu

Offizielles Ubuntu Image auf Docker Hub

Offizielles Ubuntu Image auf Docker Hub

Die Dokumentation beschreibt die Entstehung der Images und referenziert auf entsprechende Quelle, Anleitungen und Historien.

Im Screenshot kann man die Liste von - zum Zeitpunkt des Screenshots aktuellen - Taglisten erkennen:

  • 20.04, focal-20240427, focal

  • 22.04, jammy-20240427, jammy

  • 23.10, mantic-20240427, mantic

  • 24.04, noble-20240429, noble, latest, rolling

Die Namen sind Bezeichner für die jeweiligen Ubuntu-Versionen - z.B. Noble Numbat. Alle zwei Jahre erstellt Canonical für Ubuntu neue Long Term Support (LTS) Varianten: 20.04 - 22.04 - 24.04 - …

Übung

Recherchieren Sie (zum Seminarzeitpunkt) das Image mit Tag latest und den anderen aufgelisteteten Tags nach

Hier: 24.04, noble-20240429, noble und rolling

Analysieren Sie die aufgelisteten Eigenschaften und Prüfsummen.

Man erkennt die Philosophie/Idee hinter den Tags von Ubuntu und stellt fest, dass latest hier eben auch jeweils latest bedeutet.

Außerdem ergibt die Analyse, welcher Prozess dafür verantwortlich ist, dass ein Container am Leben erhalten wird: CMD ["/bin/bash"].

Im Container wird als die Bash als Prozess ausgeführt - er läuft!

_/debian

Link: https://hub.docker.com/_/debian

Offizielles Debian Image auf Docker Hub

Offizielles Debian Image auf Docker Hub

Auch diese Dokumentation beschreibt die Entstehung der Images und referenziert auf entsprechende Quelle, Anleitungen und Historien.

Insbesondere wird wieder die Entstehung erläutert und der Versuch beschrieben schlanke Images zu erzeugen.

Im Screenshot kann man die Liste von - zum Zeitpunkt des Screenshots aktuellen - Taglisten erkennen:

  • bookworm, bookworm-20240513, 12.5, 12, latest

  • bookworm-backports

  • bookworm-slim, bookworm-20240513-slim, 12.5-slim, 12-slim

  • bullseye, bullseye-20240513, 11.9, 11

  • bullseye-backports

  • bullseye-slim, bullseye-20240513-slim, 11.9-slim, 11-slim

Übung

Recherchieren Sie (zum Seminarzeitpunkt) das Image mit Tag latest und den anderen aufgelisteteten Tags nach

hier: bookworm, bookworm-20240513, 12.5 und 12

Analysieren Sie die aufgelisteten Eigenschaften und Prüfsummen.

Die Namen sind Bezeichner für die jeweiligen Debian-Versionen, die den Animationsfilmen Toy Story entstammen.

Die (aktuell) letzten beiden Versionen heißen:

  • Debian 11 - Bullseye

  • Debian 12 - Bookworm

In der vollständigen Liste tauchen dann auch weitere Bezeichner der Debian Roadmap auf:

  • Debian 13 - Trixie

  • Debian Testing - nächster Release Kandidat / entspricht aktuell Trixie

  • Debian Sid - eine unstable Entwicklerversion

  • Debian Experimental - Vorstufe zu unstable

  • [ Debian 14 - Forky - aktuell noch nicht auf Docker Hub ]

_/mariadb

Link MariaDB Official Image: https://hub.docker.com/_/mariadb

Environment Variables für MariaDB Container - Password required!

Environment Variables für MariaDB Container - Password required!

Weitere Info-Links zum Image MariaDB:

Das Image stellt mit dem MariaDB-Service einen Background Prozess zur Verfügung!

Wichtig

Container ohne Prozess(e) werden gleich wieder beendet - siehe: hello-world!

Aber natürlich kann der Datenbankprozess nicht im luftleeren Raum existieren. Die Analyse des MariaDB Image mariadb:latest ergibt, dass es historisch von ubuntu:jammy abstammt.

Das heißt, dass die MariadDB Entwickler uns ein quasi kombiniertes Ubuntu (Version: Jammy 22.04) + MariadDB Server 11.3.2 Image offerieren.

Hier ein paar der Layers für das Image:

# hier wird das Ubuntu:Jammy hinzugefügt - SHA s.a. Jammy Image!
 4 ADD file:a5d32dc2ab15ff0d7dbd72af26e361eb1f3e87a0d29ec3a1ceab24ad7b3e6ba9 in /

# ein Volume verdrahten - siehe später Volume list
18 VOLUME [/var/lib/mysql]

# Standard-Port anbieten
22 EXPOSE map[3306/tcp:{}]

# der Dienst, der den Container am Laufen halten soll als Letztes
23 CMD ["mariadbd"]

Es folgt ein Minimal-Aufruf für einen (immer neuen!) Container mit Name mariadb-test1 und die Nutzung:

docker run -d --name mariadb-test1 -e MYSQL_ROOT_PASSWORD=geheim mariadb
# der Container mit MariaDB Server läuft im Hintergrund (-d | --detached)
# und kann manuell gestoppt werden!

# Containerinfos auslesen:
docker inspect maria-db-test1

# Stoppen eines Containers:
docker stop mariadb-test1

Beachten: MariaDB Datenbank Verzeichnis /var/lib/mysql liegt im Docker-Container!

docker inspect maria-db-test1 | jq      # oder einfach less

Man sollte die Zeilen mit Bezeichner Mounts analysieren.

Die Datenbank - wenn diese läuft - mit MySQL/MariDB-Client checken:

docker exec -it mariadb-test1 mariadb -u root -p  # client mysql funzt nicht

Und gerne immer wieder den Container analysieren - mit inspect oder auch manuell.

docker exec -it mariadb-test1 /bin/bash

# Aufrufe:
cat /etc/os-release
ps ax
mysqld --version
exit

Das Logging übernimmt Docker für den Hintergrund-Daemon Mysqld:

docker logs mariadb-test1

Jetzt erweitern wir das Beispiel mit eigenem Volume im Userdir Home:

mkdir /home/joeb/varlibmysql     # manuelles mkdir - nicht nötig!

docker run -d --name mariadb-test2 \
    -e MYSQL_ROOT_PASSWORD=geheim \
    -v /home/joeb/varlibmysql/:/var/lib/mysql mariadb

So jetzt haben wir einen neuen Container mariadb-test2 mit den Datenbank-Dateien im Homedir eines Users.

Hinweis

Diese Umleitung für Volumes kann bei Nicht-Linuxen problematisch sein! Auf Windows-basierten Docker Hosts (z.B. Docker Desktop für Windows mit WSL2) haben wir im Host-Bereich NTFS-Dateisysteme.

Jetzt noch ein Container - hier publishen (s.a. gedanklich: Portumleitungen) wir den Container-internen Port 3306 nach außen an unseren Docker-Host Port 13306. Wir nutzen das selbe Volume.

docker run -d --name mariadb-test3 \
    -v /home/joeb/varlibmysql/:/var/lib/mysql \
    -p 13306:3306 mariadb

Und jetzt klappt der Zugriff auch direkt über den Docker-Host, wenn wir noch schnell den MySQL/MariaDB Client bereitstellen.

mysql -u root -p --port 13306 --protocol=tcp

Auf Debian also bitte einfach den MariaDB Client per sudo apt install mariadb-client nachinstallieren. Bei dieser Variante funktioniert sowohl Aufruf mysql (Symlink) als auch mariadb für den Datenbankclient.

Multi Container

Wir nutzen mehrere Container (Bild: ari-ara-n-rJWY7YquE-unsplash)

Wir nutzen mehrere Container (Bild: ari-ara-n-rJWY7YquE-unsplash)

Die bisherigen Beispiele haben die Container einzeln in Betrieb genommen und stellten auch singuläre - gemeint ist hier einzelne - Prozesse oder Dienste bereit.

Die folgenden Beispiele sollen jetzt die Zusammenarbeit mehrerer Container darstellen.

Ein Ansatz soll sich nicht ändern: wir nutzen die einfachen Docker Container Befehle - also keine Automatismen zum Vernetzen der Container oder dem gleichzeitigen Starten und Konfigurieren in einem Befehl.

MariaDB - phpMyAdmin

Link Official Image phpmyadmin: https://hub.docker.com/_/phpmyadmin

Link Old Image phpmyadmin/phpmyadmin: https://hub.docker.com/r/phpmyadmin/phpmyadmin

Verschiedene phpMyAdmin Images - auch als Offizielles Image!

Verschiedene phpMyAdmin Images - auch als Offizielles Image!

In 2024 basiert das Official Image auf zwei anderen Basisimages:

  • debian:12-slim

  • php:8.2-apache

Über das Publishen (Parameter -p | --publish) können wir die Ports von Anwendungen zum Docker Host veröffentlichen und verdrahten. Mit Ports kann man also (in)direkt auf die Dockerdienste / Dockerprozesse vom Docker-Host aus zugreifen.

Was ist aber mit einer sauberen und abgetrennten Vernetzung von Containern. Hier greifern wir besser zu eigenen Docker-Netzwerken, welche die nötigen Container verbinden.

Für die Darstellung nutzen wir die klassischen Partner im Hosting-Bereich für das Management von Datenbanken:

  • Datenbank: MySQL / MariaDB - wir bleiben bei MariaDB

  • phpMyAdmin: eine in PHP geschriebene Oberfläche für MySQL/MariaDB

Hinweis

Bitte in den Übungen daran denken, die vorher beteiligten MariaDB-Container zu stoppen. Bei gleichen Namen müssen Container zuvor entfernt werden.

Wir werden uns ein neues Netzwerk erstellen und und neue MariaDB- und PhpMyAdmin-Container nutzen.

# Neues Docker Netzwerk erstellen
docker network create test-net

# MariaDB Server erzeugen - keine Port Publishings
# Bitte nicht ENV für Root Password vergessen!
docker run -d --name mariadb-test4 \
   -e MYSQL_ROOT_PASSWORD=geheim \
   -v /home/joeb/varlibmysql/:/var/lib/mysql \
   --network test-net mariadb

# phpMyAdmin mit MariaDB Server verbinden (PMA_HOST)
# und dasselbe Netzwerk nutzen
docker run -d --name pma -p 8080:80 \
    -e PMA_HOST=mariadb-test4 \
    --network test-net \
    phpmyadmin                   # Official Image
    #phpmyadmin/phpmyadmin       # Old Image

Beim letzten Aufruf ist der alte volle Name für das PhpMyAdmin-Image zu erkennen. Mittlerweile gibt es phpMyAdmin ja auch als Official Image.

Die Docker-Netzwerke erledigen selbstständig die Namensauflösungen! Es werden die mit der Option -- name erstellten Bezeichner der Container verwendet.

Übung

Analyse und Inspection der Container und Netzwerke!

WordPress: DB+Web+PMA

Infos zum Wordpress Image siehe: Wordpress Image auf Docker Hub

Official Image WordPress auf dem Docker Hub

Official Image WordPress auf dem Docker Hub

Für die Bereitstellung von WordPress benötigen wir eine MySQL/MariaDB-Docker-Instanz, Datenbankmanagement und ein passendes Dockernetzwerk.

Hier wieder eine unvollständige Liste mit Tags (zu einem Zeitpunkt):

  • 6.5.3-php8.1-apache, 6.5-php8.1-apache, 6-php8.1-apache, php8.1-apache, 6.5.3-php8.1, 6.5-php8.1, 6-php8.1, php8.1

  • 6.5.3-php8.1-fpm, 6.5-php8.1-fpm, 6-php8.1-fpm, php8.1-fpm

  • 6.5.3-php8.1-fpm-alpine, 6.5-php8.1-fpm-alpine, 6-php8.1-fpm-alpine, php8.1-fpm-alpine

  • 6.5.3-apache, 6.5-apache, 6-apache, apache, 6.5.3, 6.5, 6, latest, 6.5.3-php8.2-apache, 6.5-php8.2-apache, 6-php8.2-apache, php8.2-apache, 6.5.3-php8.2, 6.5-php8.2, 6-php8.2, php8.2

  • 6.5.3-fpm, 6.5-fpm, 6-fpm, fpm, 6.5.3-php8.2-fpm, 6.5-php8.2-fpm, 6-php8.2-fpm, php8.2-fpm

Die Auswahl der verschiedenen Images:

  • Image: wordress - enthält Webserver inkl. PHP

    Tag latest: CMS/Blogging-Software WordPress 6.5.3 + Webserver Apache2 + PHP 8.2

  • Image: mariadb - der Datenbankserver

  • Image: phpmyadmin - das Datenbankmanagement / Dashboard

Auf dem Docker Hub Portal zu Wordpress finden sich auch die Erläuterungen für die speziellen WordPress Umgebungsvariablen (siehe Parameter -e).

Hier folgen die vollständigen Konfigurationen für die Docker Run Kommandos.

Wir werden lokale Host-Verzeichnisse für die Datenbank und die WordPress Website nutzen.

Man sollte - wie immer - für jedes Projekt einen eigenen Ordner reservieren. Die HomeFolder für DB + WordPress muss man nicht manuell erstellen. Hierbei fallen einem aber vielleicht gleich Komplikationen oder Probleme auf.

mkdir -p /home/joeb/docker-data/wp01-db
mkdir -p /home/joeb/docker-data/wp01-html

Das notwendige Netzwerk müssen wir bei dieser Lösung immer noch manuell erstellen. Das wird später bei Compose wegfallen.

docker network create wp01-net
docker network list

Jetzt kümmern wir ums die Container für die Umsetzung. Wir fangen mit der Datenbank MariaDB an.

Tipp

Bei Tests auf Containeramen mit Parameter --name achten und z.B. Nummerierungen nutzen. Überflüssige oder nicht nutzbare Container entfernen.

DB-Container mit MariaDB bereitstellen:

docker run -d --name mariadb-wp01 \
    --network wp01-net \
    --env MARIADB_USER=wpuser \
    --env MARIADB_PASSWORD=usergeheim \
    --env MARIADB_ROOT_PASSWORD=rootgeheim \
    --env MARIADB_DATABASE=wpexample01 \
    -v /home/joeb/docker-data/wp01-db/:/var/lib/mysql \
    mariadb

Jetzt der WordPress-Container (inkl. Webserver und PHP-Technik)

docker run -d --name wp01 \
    --network wp01-net \
    -e WORDPRESS_DB_PASSWORD=usergeheim \
    -e WORDPRESS_DB_HOST=mariadb-wp01 \
    -e WORDPRESS_DB_USER=wpuser \
    -e WORDPRESS_DB_NAME=wpexample01 \
    -v /home/joeb/docker-data/wp01-html:/var/www/html \
    -p 8081:80 \
    wordpress

Und als drittes kümmern wir uns um den phpMyAdmin Container:

docker run -d --name pma-wp01 \
    --network wp01-net \
    -e PMA_HOST=mariadb-wp01 \
    -p 8080:80 \
    phpmyadmin

Die gesamte Umsetzung sollte sauber textlich erfasst und im Betrieb wieder auf Herz und Nieren analysiert (inspect) werden.

Hinweis

Und auch auf die Gefahr hin mich zu wiederholen ;-) : Bitte immer auf die Ports achten! Das Netz ist voll mit Foreneinträgen von Containeranwendern, die kleinlaut einräumen mussten, das die Code eigentlich alle richtig waren, aber das lief dann doch noch irgendwie ein Webserver und lauschte auf Port 80.

Die Container wurden manuell gestartet - also müssen sie auch manuell wieder gestopt werden.

docker container stop mariadb-wp01
docker container stop wp01
docker container stop pma-wp01

Das Starten verlangt nach gleichem Muster und benötigt keinerlei Übergabe von Konfigurationen - die wurden ja in den docker run ... Kommandos für die Container etabliert!

# Alles wieder einschalten
docker container start mariadb-wp01
docker container start wp01
docker container start pma-wp01

Und natürlich werden wir uns im nächsten Schritt alle diese Arbeiten inklusive der Netzwerk- und Volumen-Verwaltungen weiter automatisieren und vereinfachen: wir verwenden Docker Compose.

Docker Compose

Jetzt wollen wir die Bereitstellungen von mehreren Containern weiter verbessern.

Docker Compose Overview auf docs.docker.com

Docker Compose Overview auf docs.docker.com

Mit einfachen Docker Aufrufen geht das zwar relativ gut, aber wir wollen die Anweisungen für mehrere Container inklusive Vernetzung und Volumes zentral organisieren - ein Kommando rollt alle benötigten Container Techniken aus und räumt am Ende auch wieder auf!

Compose Technik

Ich möchte kurz den technischen Hintergrund und die Historie von Compose beleuchten.

In Docker kann man die docker compose Techniken auch mit docker stack deploy Techniken - also: Swarm Services - ausführen und arbeitet quasi mit einem Minimal-Swarm bestehend aus einer Docker-Instanz!

Wir beschränken uns - an dieser Stelle - auf docker compose und behalten uns die Swarm-Techniken (Orchestrierungen) für später auf.

Hinweis

Das mit Bindestrich geschriebene docker-compose war ein klassisches Python-Skript und konnte Problemchen bereiten (Python!)

Die Docker Dokumentation bezieht sich mittels Begriff Compose standalone auf diese manuell bereitzustellende alte Technik.

Debian 12 Bookworm stellt ein Paket docker-compose bereit. Stattdessen nutzt man das docker-compose-plugin aus der Docker (CE) Installation.

In (relativ) aktuellen Docker Versionen ist die Compose Technik also einfach ein weiteres Subkommando des Docker CLI Befehls docker ... und wird im Fall von Compose als sogenanntes Plugin fertig zur Verfügung gestellt.

Alte/manuelle Bereitstellung von Compose Tool - NICHT EMPFOHLEN - OBSOLET

Die Standalone Compose Technik wird aber immer noch von Docker gepflegt.

Releases / Downloads: Github docker/compose Releases

Für den einfachen Download bzw. Installation des Compose Plugin bitte der Readme auf dem Github Repo folgen.

docker-compose.yml

Die Konfigurationsdatei docker-compose.yml (auch compose.yml möglich) ist die Textdatei mit allen benötigten Anweisungen (Direktiven) für das Tool docker compose!

Erstes Beispiel compose.yml

Ein vollständiges Beispiel folgt in einem weiteren Kapitel. Mit dem folgenden Code wollen wir uns dem Thema weiter annähern.

docker-compose.yml (Hier: einfache Wordpress-Installation)
# Datei test/docker-compose.yml
# version: '3.7'

services:
  db:
    image: mariadb:latest
    volumes:
      - /var/dc-test-db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: geheim
    restart: always

  wordpress:
    image: wordpress:latest
    volumes:
      - /var/dc-test-www:/var/www/html
    ports:
      - "8082:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: geheim
    restart: always

Dieses Hello WordPress!-Beispiel zu docker compose zeigt die zusätzliche Intelligenz des docker compose-Tools gegenüber den Basistools Docker.

CLI docker compose

Kommando: docker compose … (Auszug)

  • config (Analyse)

  • up | down (up normalerweise kombiniert mit -d)

  • events

  • kill (falls stop|down nicht funzt)

  • logs

  • pause | unpause

  • ps

Compose Projektordner

Nach Bereitstellung eines Projektordners mit docker-compose.yml reicht der letzte Befehl aus der folgenden Liste:

cd test                    # hier befindet sich das docker-compose.yml
mkdir /var/dc-test-www     # Volume Wordpress HTML; kann man weglassen (!)
mkdir /var/dc-test-db      # Volume MariaDB Databases; kann man weglassen (!)

# der eigentliche Startbefehl für alle Container inkl. Netzwerk + Volumes
docker compose up -d

Test hier einfach wieder mit Browser (URL): localhost:8082

Danach kann man alles beenden und löschen:

# Alle Compose Container beenden und entfernen!
docker compose down                        # hier bleiben die Volumes erhalten!

rm -Rf /var/dc-test-db /var/dc-test-www    # Volumes werden in diesem Beispiel manuell gelöscht

Anm.: bei Nutzung von docker compose down --volumes werden die volumes auch mit entfernt!

Compose Netzwerke und Volumes

Netzwerke für docker-compose.yml

services:
  web:
    ...
    networks:
      - mynet

# auf Top-Level die Netzwerke definieren
networks:
  mynet:
    external:
      name: host

Bei der letzten Konfiguration ist das Docker-eigene Host-Netzwerk gemeint (siehe docker network ls).

Netzwerkports

ports:
  - "8080:80"
  - "8443:443"

Auf die Hierarchie-Ebene für Definitionen achten.

Volumes

# Docker docker-compose.yml in Ordner testing
version: '3.7'
services:
  nginx:
    volumes:
      - webdata:/var/www/html
    ...
volumes:
  webdata:

Docker erstellt selbst ein Volume: /var/lib/docker/volumes/testing_webdata/_data

Mit einem weiteren docker-compose Beispiel (Joomla-Installation) können wir die Nutzung von Docker Volumes sehen:

Beispiel mit CMS Joomla und Volume webdata:

docker-compose.yml (Joomla-Installation) mit Volume
# Datei: joomla/docker-compose.yml
# version: '3.1'
services:
  joomla:
    image: joomla:apache-php7
    ports:
      - 8080:80
    volumes:
      - webdata:/var/www/html
    environment:
      JOOMLA_DB_HOST: mariadb
      JOOMLA_DB_NAME: dockerbuch
      JOOMLA_DB_USER: dockerbuch
      JOOMLA_DB_PASSWORD: johroo2zaeQu
  mariadb:
    image: mariadb:10
    environment:
      MYSQL_ROOT_PASSWORD: eengi7suXeut
      MYSQL_DATABASE: dockerbuch
      MYSQL_USER: dockerbuch
      MYSQL_PASSWORD: johroo2zaeQu
volumes:
  webdata:

Testen der Persistierten Speicherung von Webdaten und Diskussion die Volumes in eigene Datenstrukturen zu binden.

Compose restart

Für viele Dienste wollen und können wir die automatisierten Starts bzw. Neustarts der Container definieren. Hierfür hat Compose die Direktive restart.

Eine kurze Erläuterung aus GitHub Compose Specs - restart:

restart definiert die Richtlinie, die die Plattform bei der Beendigung eines Containers anwendet.

  • no: Die Standard-Neustart-Richtlinie. Sie startet den Container unter keinen Umständen neu.

  • always: Die Richtlinie startet den Container immer wieder neu, bis er entfernt wird.

  • on-failure: Die Richtlinie startet den Container neu, wenn der Exitcode einen Fehler anzeigt.

  • unless-stopped: Die Richtlinie startet den Container unabhängig vom Exitcode neu, stoppt das Neustarten jedoch, wenn der Dienst gestoppt oder entfernt wird.

Insofern kann man sich fragen, ob in vielen Beispielcodes nicht vielleicht start restart: always doch besser ein restart: unless-stopped genutzt werden sollte.

YAML

Die Konfiguration wird in der Textdatei docker-compose.yml bereitgestellt. Es handelt sich also um ein YAML gestylte Konfigurationsdatei.

Infoseiten zu YAML:

Für die Konformität der *.yml-Dateien kann wieder ein ordentlicher Editor (siehe VS Code) mit entsprechender Unterstützung sorgen.

Hinweis

Die Einrückungen (mit Leerzeichen) müssen genau passen - sie bestimmen die Gliederungen!

Kurzanleitung:

  • Abschnitt mit —

  • Kommentar mit #

  • Liste mit Bindestrich - oder in [eins, zwei, drei]

  • Hash mit key: wert oder {name: Joe, nachname: Brandes}

  • Textblock (mit Zeilenumbrüche) mit |

  • Textblock (ohne Zeilenumbrüche) mit >

Beispiel:

Beispiel YAML
# Datei sample.yaml
data:
  list:
    - item1
    - item2
  key1: >
    Dieser Text ist dem
    Schlüssel 'data.key1' zugeordnet.
  key2: |
    code line 1
    code line 2

YAML-Tools:

  • shyaml (ein Python-Script)

  • yq (Parser für jq)

Install via PIP: sudo pip install shyaml - heute eher ein python3 -m pip install shyaml mit einem Python VENV

Beispielaufruf:

  • shyaml get-value data.key1 < sample.yaml

  • oder cat sample.yaml | shyaml get-value data.key1

  • cat docker-compose.yml | yq .services[].volume[]

Compose Beispiel

Docker Compose Beispiel mit WordPress + MariaDB + phpMyAdmin

Docker Compose Beispiel mit WordPress + MariaDB + phpMyAdmin

Im Grunde soll an dieser Stelle einfach ein komplettes und dokumentiertes Beispiel für die Umsetzungen mit Docker Compose dargestellt werden.

Solche Beispiele gibt es dann - oft kurz und knackig - auf diversen Git-Repos oder Entwicklerplattformen für den schnellen Einsatz. Auch bei der Recherche zu verschiedenen Webdienste, Datenbanken oder spätestens bei Content Mangement Systemen findet man diese Anregungen in Form der dargestellten docker-compose.yml Dokumente.

Wir wollen die Drei-Container WordPress Umsetzung aus Abschnitt WordPress: DB+Web+PMA per Docker Compose umsetzen.

 1# Datei wp02/docker-compose.yml
 2# version: '3' is obsolete in newer docker compose plugins
 3
 4services:
 5  mariadb-wp02:
 6    image: mariadb:latest
 7    volumes:
 8      - wp02-db:/var/lib/mysql
 9    environment:
10      # MYSQL_RANDOM_ROOT_PASSWORD: 1
11      MYSQL_ROOT_PASSWORD: rootgeheim
12      MYSQL_DATABASE: wp02
13      MYSQL_USER: wp02user
14      MYSQL_PASSWORD: usergeheim
15    restart: always
16
17  wp02:
18    image: wordpress:latest
19    volumes:
20      - wp02-www:/var/www/html
21    ports:
22      - "8083:80"
23    environment:
24      WORDPRESS_DB_HOST: mariadb-wp02:3306
25      WORDPRESS_DB_USER: wp02user
26      WORDPRESS_DB_NAME: wp02
27      WORDPRESS_DB_PASSWORD: usergeheim
28    restart: always
29
30  pma-wp02:
31    image: phpmyadmin:latest
32    ports:
33      - "8084:80"
34    environment:
35      - PMA_HOST=mariadb-wp02
36
37volumes:
38  wp02-www:
39  wp02-db:

Anmerkungen zum YAML Code:

  • Versionierungen sind obsolet, würden aber wohl auch nicht stören.

    Es kommt aber seit geraumer Zeit in diversen Dockerumgebungen zu Meldungen.

  • Die drei zu erzeugenden Container wurden hervorgehoben.

  • Die ENV Variablen beim MariaDB Container dürfen natürlich auch gerne MARIADB_ROOT_PASSWORD und Co heißen.

Mit dieser Basis kann man in Sekunden eine WordPress Umgebung starten und beenden.

Ein Standardbefehl docker compose down entfernt alle genutzten Container und das Netzwerk. Falls man auch gleich die Volumes entfernen lassen möchte greift man zu docker compose down -v.

Tipp

Als Spezialist für die zentrale Verwaltung von Docker Compose Projekten kann man Dockge ausprobieren - siehe Dockge.

Das obige Beispiel einfach in eine neue Dockge Compose Verwaltung kopiert und schon hat man Docker Compose in einer GUI, die gerne auch noch andere Docker Hosts verwaltet.

Dockge vewaltet das WordPress Projekt

Dockge vewaltet das WordPress Projekt

Die Projekte werden in eigenen Ordnerstrukturen /opt/stacks verwaltet. Und man kann sehen, dass sich Dockge auch gleich selbst verwaltet ;-).

Docker Mini Swarm

Die Docker-eigene Orchestrierung: der Docker Swarm oder auch Stack. Man könnte auch sagen Totgesagte leben länger, denn die Swarm Technik von Docker sollte 2019 schon abgekündigt werden (bis 2021 mit 2-Jahresfrist). Davon ist man aber abgerückt und unterstützt Docker Swarm weiter ohne Limit.

An dieser Stelle nur zum reinschnuppern

Hinweis

Ich habe mich entschieden dieses Kurzkapitel zu Docker Swarm hier zu belassen, obwohl man diese Orchestrierung aktuell (2023) so gut wie nicht mehr einsetzt. Nicht ohne Grund unterstützen auch die Docker Entwicklungen die Kubernetes Orchestrierungen.

Bei vorherigen Übungen mit docker compose (s.o.) inkl. Volumes bitte vorher aufräumen/löschen!

Docker-Schwarm initieren: docker swarm init und dann kann man mit docker stack deploy einen Cluster mit nur einem Docker-Swarm-Mitglied (Mini-Swarm) nutzen.

# Docker Swarm initieren - Docker jetzt in besonderem Modus
docker swarm init                                      # Docker Swarm initieren

# Projektordner
cd test                                                # hier ist das docker-compose.yml
mkdir /var/dc-test-www                                 # Volume Wordpress HTML
mkdir /var/dc-test-db                                  # Volume MariaDB Databases

# wir können direkt mit docker-compose.yml Dateien arbeiten
docker stack deploy -c docker-compose.yml stacktest    # und los geht es...

docker stack rm stacktest                              # alles (bis auf Volumes) löschen!

Das Beispiel zeigt ganz schön die zusätzliche Abstraktionsebene beim Testen und Analysieren der Swarm-Container-Technik.

Testen einer WordPress-Installation im Browser: 172.20.0.2:8082 - das ist ein komplett anderes Subnetz!

Also: die Portumsetzung führt quasi eine Netzwerk-Ebene weiter (siehe GW-Netzwerk)! Die richtige IP (hier im Beispiel: 172.20.0.2) analysiert man mittels docker network ... (siehe inspect) oder natürlich einfach mit ip a s auf Docker Host: siehe GW-Bridge.

Der Docker läuft weiterhin im Swarm Modus! Beenden mit: docker swarm leave --force

Für Docker Swarm gibt es weitere Deploy-Einstellungen:

  • deploy.mode

  • deploy.placement.constraint ; Regeln: node.id, node.hostname, node.role

Wenn man mehrere Nodes (Docker Host Swarm Mitglieder) joint (docker swarm join ...) müssen weitere Vorbereitungen und Konfigurationen beachtet werden: insbesondere die Nutzung von Zeitservice NTP, damit die Nodes genau gleich ticken.

Tipp

Man sollte mal mit dem Docker Swarm spielen und erhält zwei Feedbacks/Erkenntnisse:

Die technische Nähe zu den Docker Compose Direktiven: docker-compose.yml vs. stack.yml

Die zusätzliche Abstraktionsebene wie hier für das Netzwerk. Das bereitet gedanklich gut auf Orchestrierungen wie Kubernetes vor.

Docker Secrets

Secrets in Docker Compose auf docs.docker.com

Secrets in Docker Compose auf docs.docker.com

Wir haben verschiedenste Infos, die wir gerne verbergen / verschlüsseln wollen.

  • Benutzer / Passworte

  • API-Keys

  • SSH-Keys

  • Servernames

Linksammlung zu Secrets:

In Kürze: Secrets funktionieren mit Swarm oder Docker Compose. Allerdings sind nur die Swarm Techniken komplett sicher, da man hier auf dem Swarm Master secure speichert und auf Anfrage eines Swarm Workers die Info verschlüsselt bereitstellt.

Bei der Nutzung von Docker Compose (ohne Swarm) handelt es sich einfach um reguläre Dateien, die clever in den Containern zur Laufzeitumgebung die Infos bereithalten.

Grob gesagt: die reine Docker Compose Lösung ist in Ordnung für eine Entwicklungsumgebung. Im Produktionsumfeld sollte man sich auf verschlüsselte Secrets verlassen und benötigt also Docker Swarm Technik oder gleich andere (Orchestrierungs) Technik.

Docker Compose Beispiel mit Alpine aus Kofler/Öggl (4. Auflage):

Secrets Datei top-secret.txt:

Nobody knows ;-)

Die docker-compose.yml Datei:

# note: does not work with podman-compose
# (tested with Podman 4.5, podman-compose 1.0.6)

services:
  secrettest:
    image: alpine
    secrets:
      - mypassword
    command: ["cat", "/run/secrets/mypassword"]

secrets:
  mypassword:
    file: ./top-secret.txt

Da wir hier keinen laufenden Service haben bitte einfach docker compose up.

Programmierung

Programmieren mit Docker Containern

Programmieren mit Docker Containern

Bei vielen Container Umsetzungen haben wir einfach diverse Storages für die Container-Daten bereitgestellt:

  • Webserver Verzeichnisse für Apache2 oder Nging

  • Datenbank Ordner für DB-Server wie MariaDB/MySQL oder PostgreSQL

Hierfür gab es diverse Lösungen

  • Container-interne Storage (ungeschickt wegen Container als Wegwwerware)

  • Volumes über Docker Host Engine

  • Mount Binds über Host Verzeichnisse des Users oder Systems

Im Falle von Programmierungen müssen diese Storages aber bei geänderter Codebasis neu übersetzt werden. Wenn uns also ein Container mit maßgeschneiderter Programmierumgebung die Arbeit erledigt hat und uns einen Container mit produzierter Software erstellt hat, dann findet der Container die Änderungen des Codes nicht - er läuft ja schon!

Man muss also Techniken implementieren, die möglichst attraktiv diese Container Aktualisierung bei geänderter Codebasis umsetzen.

Hierfür gibt es verschiedenste Ansätze und Umsetzungen. Außerdem sind diese Umsetzungen natürlich auch immer von der Programmierplattform abhängig.

Hinweis

Die Beispiele und Umsetzungen versuchen ohne Spezialwissen der unterschiedlichen Programmierungs- und Skriptsprachen auszukommen.

Daher setzen sie allerdings eben oft auch nur rudimentär Technik um - es geht halt um das Prinzip.

Wir starten mit einem Best Practise Beispiel der Docker Dokumentation für eine kleine Python App.

Python Docker Dev

Python Docker Development Example with Compose and watch

Python Docker Development Example with Compose and watch

Für den Kapitelnamen habe ich mich an der Beschreibung und URLs der Docker Entwickler und dessen Python Beispiel orientiert.

Hinweis

In manchen (folgenden) Abschnitten wird VSCode genutzt. Dieses Beispiel kann mit einem beliebigen Editor für die Python App durchgeführt werden. Die Lösungen mit Docker oder Docker Compose ließen sich aber auch mit VSCode kombinieren.

Beispiel:

Der Git Code wurde von mir geklont (Mai 2024) und aufbereitet, da in der Anleitung auch git init zum Einsatz kommt.

Das Kommando git init nur bei neueren Docker Desktop verfügbar! Das ist im Grunde kein Problem, da die fraglichen Basisdateien schnell erstell bzw. kopiert wären. Hier habe ich das Gesamtgerüst meist für die Trainee komplett in meinem Gitlab Repo Containercodes aufbereitet.

Falls man die Arbeitsschritte auf den Websites Schritt-für-Schritt nachvollziehen möchte (und docker init - also Docker Desktop nutzt) hier eine Kurzanleitung

  • Git Repo mit Python (flask) Code in Projektordner klonen

  • Docker Init ausführen:

    • Python Version (z.B. 3.11.2)

    • Port für Webservice (z.B. 5000)

    • Scriptcommand (z.B. python -m flask –host=0.0.0.0 )

  • Compose Datei anpassen / kontrollieren

  • Secret erstellen

Projekt erstellen mit docker compose up --build

Automatische Container-Updates mit Compose Watch

  • Compose Datei mit watch Direktive ergänzen.

Projekt stets aktuell mit docker compose watch.

Das Testen findet über Manipulation der Main app.py statt. Man sollte für die Web-Request (über Curl oder Browser) ein Sekündchen einplanen.

Python VSCode Debug

Beim Entwickeln von Code - hier Python - stellt sich auch schnell die Frage nach dem Debugging.

Python VSCode Debug by C. Lempa - eine Grundidee

Python VSCode Debug by C. Lempa - eine Grundidee

Wenn unser Python Code in einem Container läuft - wie stellen wir dann das Debugging bereit.

Vorschlag: Visual Studio Code mit den passenden Extensions.

Tutorial: Christian Lempa - Docker VSCode Python Tutorial // Run your App in a Container

Tipp

In VSCode kann man Profile anlegen mit denen man eine komplett eigene Umgebung (Einstellungen, Shortcuts, Snippets, Tasks und Extensions) erstellen kann. Das ist in der Praxis sehr hilfreich und beim Testen eine sehr gute Hilfe.

Extensions installieren:

  • Docker (;-)

über F1 wähle Add Docker Files to Workspace und beantworte die Fragen.

Es werden folgende Dateien erzeugt:

  • .vscode/launch.json und .vscode/tasks.json

  • .dockerignore

  • Dockerfile

  • requirements.txt

Das Dockerfile enthält schon mal viel Schönes für eine Python-Docker-Entwicklungsumgebung.

Jetzt können wir einfach ein Image bauen. Das geht wie gelernt über die Konsole aber natürlich auch über die Docker Extension mit Rechtsklick auf unser Dockerfile.

Dann kann man das gewünschte Ziel aller Bemühungen - einen Container mit der passenden Python Umgebung für unsere App - einfach per docker run imagename ausführen.

Das Debugging funktioniert auf Knopfdruck (oben) in der Run and Debug Abteilung von VSCode.

Jetzt kommen wir zum aktuellen Schwachpunkt dieser Lösung: bei Veränderungen am Code muss man immer wieder Image(s) bauen und neue Container ausführen (run). Das sind eine Menge dangling Images und immer wieder neue Container.

Hinweis

Bei komplexeren Projekten und weiteren beteiligten Skripttechniken wird das Debuggen immer schwieriger. Es wäre schön, wenn die Debug-Technik nicht umständlich vom Host in den Container geleitet werden müsste.

Für das Debuggen finde ich Schleifen jut:

# Initialisiere die Zählvariable
count = 1

# Äußere Schleife für die Zeilenumbrüche
for row in range(1, 11):
    # Innere Schleife für die Ausgabe von 10 Zahlen pro Zeile
    for col in range(1, 11):
        # Gib die aktuelle Zahl aus und erhöhe den Zähler
        print(f"{count:2d}", end=" ")
        count += 1
    # Zeilenumbruch nach 10 Zahlen
    print()

VSCode Dev Container

VSCode Dev Containers

VSCode Dev Containers

Jetzt bauen wir uns noch eine weitere Technikstufe in eine Entwicklungsumgebung: Dev Contiainers.

Hinweis

Man kann diese Entwicklungsumgebung in andere IDE (Entwicklungsplattformen) einbauen: IntelliJ IDEA, Pycharm oder alle VSCodium basierte IDE wie Gitpod oder Theia IDE.

Wir schauen uns die Visual Studio Code Dev Containers an. Wir beginnen mit ein paar Infolinks:

Python Beispiele mit Dev Container Development inkl. Debugging mit Videos auf Youtube und Begleitmaterial auf Git Repo:

Die Dev Container sind eine wahre Freude, weil sie in vielen Fällen wirklich alle nötigen Werkzeuge mitbringen. Da liegt aber auch das Problemchen. Aktuelle frisch erstellte Python Images können leicht (und sehr schnell) 1 GB und größer werden!

Allerdings muss man fairer Weise erkklären, dass diese Werte für die MS-VSCode-seitigen Builds gilt. Die sollen eben auch viele technische Baustellen bedienen.

Man kann die Dev Container auch auf Maß selber bauen und durch eigene Direktiven die letztlich genutzten Umgebungen in Größe und Fähigkeit selbst bestimmen: VSCode - Docs - Create Dev Container.

Die Images selber kann man unter GitHub Dev Containers Images Tree genauer betrachten. Dort gibt es auch die Dockerfile Dateien, mit denen die Standard-Container gebaut sind. Und von da aus kann man selbst loslegen.

Übung mit Python Vorgaben

Ich habe die nötigen Dateien für ein Python Dev Container Image mal heruntergeladen und bei meinen containercodes (GitLab Repo) beigefügt.

Nachdem man in VSCode den Ordner .devcontainer bereitgestellt hat lässt man das neue Image/den Container erstellen:

F1 öffnet >Dev Containers: Reopen in Container

Die Erstellung des gewünschten Containers (mit allen Eigenschaften und Software) wird angeschubst und schon geht sie los die wilde Fahrt.

Das kann dann auch gerne mal dauern

Die Images enhalten neben dem Präfix vsc- desweiteren den Projekt-Namen (Ordnernamen) und eine individuelle Kennung.

Die Ablage der Projekte in Volume Mounts sollte uns an deren Pflege und Sicherung (Backup) erinnern.

Als Königsdisziplin kann man die Projekte auch gleich Remote mit einem Online Git-Repo (GitHub, GitLab, …) verbinden. Das zeige ich selten in den Seminaren, da ich meine Accounts/Kennungen hier nicht gerne benutze und die Trainees meist keine entsprechenden Zugänge parat haben.

Dev Container mit Git Repo als Remote Volume

Dev Container mit Git Repo als Remote Volume

YouTube Video mit Erklärungen: DanCanCode - My Favorite Way To Handle Dev Environments | VS Code Devcontainers

NodeJS Getting-Started

Dieses Beispiel ist sowohl auf dem Docker Hub, der Docker Dokumentation als auch im Docker Desktop die aktuelle Anlaufstelle für Umsetzungen von Programmierumgebungen mit Docker.

Lokale Getting-Started Website basierend auf Image docker/getting-started

Lokale Getting-Started Website basierend auf Image docker/getting-started

Erste Anlaufstelle ist eine Webumgebung, welche die Dokumentation für die Darstellungen enthält.

Die eigentliche NodeJS / JavaScript App ist in der Anleitungs-Website, die man jetzt erhalten hat gleich als downloadbares app.zip integriert.

Die Erstellung des app.zip inklusive der Übertragung in das Image für Getting-Started kann man sehr schön dem Dockerfile mit Multi-Stage-Build entnehmen.

Bitte vor Allem die GitHub Repos sauber auseinanderhalten - die Quelle für die NodeJS-App auf GitHub lautet:

Das irritiert häufig auch die Trainees, weil in der Website, die wir erhalten haben ein Image mit dem Namen getting-started erstellt wird.

Der Name sollte allerdings besser heißen: training/getting-started-app! Bei diesem Namen macht das Image keinen offiziellen Eindruck und durch das angehängte -app hat man die saubere Abtrennung zur Website (s.o.) für den Einstieg in die Thematik.

Hinweis

Natürlich kann man auch nur die getting-started-app klonen und direkt entwickeln.

In diesem Beispiel wird die Live-Aktualisierung des JavaScript Codes für den NodeJS Service ein Kommando für eine Arbeitsumgebung mit dem Standard Image node:18-alpine und Aufruf des Tools yarn install && yarn run dev.

Auf den aktuelleren Websites zur Getting Started App - Bind Mounts sind die Mounts mit ausführlicher Syntax verdrahtet und erläutert.

docker run -dp 127.0.0.1:3000:3000 \
   -w /app --mount type=bind,src="$(pwd)",target=/app \
   node:18-alpine \
   sh -c "yarn install && yarn run dev"

Die kürzere Version verzichtet auf die wörtliche Zuweisung mittels des types über die Signalworte src nd target und die Limitierung auf die Localhost-IP.

docker run -dp 3000:3000 \
   -w /app -v "$(pwd):/app" \
   node:18-alpine \
   sh -c "yarn install && yarn run dev"

Die package.json definiert den Job / das Skript dev mit nodemon src/index.js - und dieser Node-Monitor aktualisiert die Ausgabe bei Webrequests.

Und auch hier wollen wir natürlich nicht dauernd alle möglichen Befehle für die benötigten Containertechniken eingeben sondern komponieren (Docker Compose) bzw. Docker Stack nutzen.

Aktuelle Erklärungen online: Docs Docker - Getting Started App - using Compose

Getting Started App - Compose.yml
services:
  app:
    image: node:18-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 127.0.0.1:3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

Die Festlegung der app: ports: auf - 127.0.0.1:3000:3000 inklusive der IP für Localhost scheinen hier technisch notwendig zu sein. Das liegt wohl an der NodeJS/Alpine Service-Technik.

CMS + DOCS

Content Management Systems (Bild: growtika-yGQmjh2uOTg-unsplash.jpg)

Content Management Systems (Bild: growtika-yGQmjh2uOTg-unsplash.jpg)

Umsetzungen mit Containern für Content Management Systeme und Document Management Systems gibt es viele und ich liste hier nur mal kurz auf.

CMS - Beispiele

Ich wiederhole: Ohne Anspruch auf Vollständigkeit ;-)

  • WordPress - weil es halt alle irgendwie nutzen - nicht meine Idee!

    Hierzu gab es diverse Beispiele in den Unterlagen von Manuellen Container Deployments bis zu Docker Compose Lösungen.

  • Joomla - ein alter Recke der Open Source Community und einer meiner Begleiter im WWW

    Bitte einfach in meinen Containercode stöbern. Und natürlich die Dokumentation auf dem Docker Hub zum Offiziellem Docker Image Joomla studieren.

  • TYPO3 - die Lösung von der Visitenkarte im Web bis zum Enterprise System

    Da gibt es diverse Lösungen zum Ausrollen und für die TYPO3 Entwickler ist eine Kombination aus Docker und DDEV die erste Wahl.

    DDEV is an open source tool for launching local web development environments in minutes. It supports PHP, Node.js, and Python (experimental).

    —DDEV Website

    Links:

  • CMS … to be continued …

DocMgmt - Beispiele

Bei den Dokumenten-Managern findet man viele spannende Vertreter.

Fangen wir mit den Textformaten an:

  • Markdown

  • AsciiDoc

  • reStructuredText / reST (siehe TYPO3 Documentation und dieses Dokument!)

  • LaTeX

Die Umsetzung in fertige Layouts und Formate übernehmen dann Tools wie:

  • Pandoc (eigentlich schönes Beispiel bei Docker - Praxisbuch - aber ohne Fonts)

  • Sphinx (für reSt-Docs)

  • Divers LaTeX Interpreter und Tools

Kommen wir zur Dokumentation einiger praktischer Beispiele.

Weitere Lösungen und Umsetzungen werde ich bei Gelegenheit hier weiter dokumentieren - sofern dass mit Beispielen zuvor nicht schon passiert ist.

TYPO3 Manual Render

TYPO3 Extension Manual Rendering mit Image aus TYPO3-Community

TYPO3 Extension Manual Rendering mit Image aus TYPO3-Community

Die TYPO3 Dokumentation basiert auf Vorlagen in reST Technik. Diese Verzeichnisse müssen mit genau passender Document Management Umgebung übersetzt werden.

Man benötigt die genau passende Sphinx Version inklusive aller Extensions und Abhängigkeiten - Viel Glück.

Und selbst wenn man Alles zusammengebastelt hat verlangt das nächste reST-Projekt andere Umgebungen und Versionen!

Also packen die TYPO3-Entwickler alles in ein Image und los geht es.

Beispielhafte Docker-Lösung für das Erstellen von TYPO3 Dokumentation:

Hugo

Hugo Theme Ananke per Docker Compose aus Git Repo Ordner

Hugo Theme Ananke per Docker Compose aus Git Repo Ordner

Infolinks zu Hugo

Wie immer führen viele Wege zum Ziel. Wir wollen eine Website mit Hugo bauen und hierfür die neueste Hugo Version nutzen. Wir starten mit einem Ubuntu Basis Image und erstellen eine Dockerfile Datei mit allen nötigen Direktiven für den Bau eines solchen Hugo-Ubuntu Images.

Dockerfile für Hugo-Ubuntu Image
# Defines Image for Hugo Service
FROM ubuntu:latest

WORKDIR /data

LABEL maintainer "joe.brandes@gmail.com"
LABEL description "Hugo service with Go and Ubuntu"

ENV TZ="Europe/Berlin" \
    HUGODEBSRC="https://github.com/gohugoio/hugo/releases/download/v0.126.2/hugo_extended_0.126.2_linux-amd64.deb" \
    PROJECT="quickstart"

RUN ln -fs /usr/share/zoneinfo/${TZ} /etc/localtime && \
    echo ${TZ} > /etc/timezone && \
    apt update && \
    apt install -y vim git curl && \
    curl -L ${HUGODEBSRC} -o ./hugo.deb && \
    apt install -y ./hugo.deb

EXPOSE 1313

COPY data/ /data

CMD [ "bash" ]

Wir könnten jetzt einen entsprechenden Container mit docker run ... erzeugen und nutzen.

Wir wollen aber die noch effizientere Docker Compose Lösung umsetzen:

  • Hugo Projekt starten: docker compose up --build -d und

  • Hugo Projekt stoppen: docker compose down.

Docker Compose Datei für die Hugo-Ubuntu Lösung
services:
  hugo:
    build: .
    container_name: hugo-server
    working_dir: /data/quickstart
    command: hugo server --bind=0.0.0.0 -D
    ports:
      - 1313:1313
    volumes:
      - ./data:/data

Für die Erstausstattung habe ich einen vollständigen Projektordner mit einem Hugo-Projekt basierend auf dem Theme Ananke meinem Trainings-Repo joebrandes/containercodes beigelegt.

Hinweis

Ohne config.toml - die Hugo-Projekt-Konfigurationsdatei - mit passenden Daten und Einstellungen kann der Hugo Server leider nicht sauber starten.

Bei der Umsetzung mit Docker Desktop für Windows sollte man statt der Mount-Binds im Compose-File auf die Docker Volumes ausweichen.

Also einfach meinen Repo-Ordner nutzen. Bei der Erstellung des Images werden die nötigen Quickstart Projekt Dateien über die COPY-Direktive erzeugt.

Die beigelegten Dateien und Hilfsskripte zeigen die manuelle Umsetzung.

Die Bearbeitung der Hugo-Dateien kann wieder mit Dev Container Technik im Visual Studio Code durchgeführt werden. Das funktioniert dann ja auch wenn man auf Docker Volumes ausweichen möchte oder muss.

Man kann auch automatisierte Umsetzungen der Hugo Webseiten versuchen:

  • GitHub Actions

  • GitLab Runner

  • Jenkins

Eine Anleitung für Hugo mit dem GitLab Runner findet man in dieser Ausarbeitung bei Hugo GitLab Runner.

LAMP

LAMP steht für Linux + Webserver Apache2 + Datenbank MySQL/MariaDB + PHP und stellt eine Standardumgebung für Internet- und Intranet-Dienste dar.

Webserver und andere Services (Bild: hal-gatewood-tZc3vjPCk-Q-unsplash.jpg)

Webserver und andere Services (Bild: hal-gatewood-tZc3vjPCk-Q-unsplash.jpg)

Hier sind auch die Lösungen für Dashboards (siehe Grafana) oder die folgendenn Lösungen für Übersichtsseiten im Containernetzwerk

  • homepage - Portal gethomepage.dev

  • dashy

  • homer

  • homarr

  • heimdall

Liste(n) natürlich wie immer ohne Anspruch Vollständigkeit.

… to do …

homepage

Das Dashboard homepage ist (aktuell) meine Wahl. Aber das kann sich bei der Technikentwicklung und aufgrund eigenen Spieltriebs auch jederzeit ändern.

Dashboard homepage - gethomepage.dev

Dashboard homepage - gethomepage.dev

Links zum homepage Dashboard:

Die Umsetzung des Dashboard lässt sich natürlich wieder als Container erzeugen.

Hinweis

Wie immer gilt: die folgenden Codes und Kommandos sind ggf. auf Aktualität zu überprüfen.

Alternativen: Heimdall, Homarr, Dashy

Wir starten mit einer Docker Compose Umsetzung.

homepage Dashboard - docker-compose.yml
version: "3.3"
services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    environment:
      PUID: 1000 -- optional, your user id
      PGID: 1000 -- optional, your group id
    ports:
      - 3000:3000
    volumes:
      - /path/to/config:/app/config # Make sure your local config directory exists
      - /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations
    restart: unless-stopped

Und natürlich geht das auch manuell mit einem Docker Run Kommando.

homepage Dashboard mit docker run Kommando
docker run --name homepage \
  -e PUID=1000 \
  -e PGID=1000 \
  -p 3000:3000 \
  -v /path/to/config:/app/config \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  --restart unless-stopped \
  ghcr.io/gethomepage/homepage:latest

Die genaueren Erläuterungen sollte man der aktuellen Dokumentation entnehmen.

Orchestrierungen

Ohne eine vorhandene Containertechnik gibt es keine Orchestrierung. Es stellt sich also (z.B.) nicht die Frage: „Kubernetes oder Docker?“ sondern eher die Frage „Welche Containertechnik für die Orchestrierung unserer Wahl?“.

Wir wollen anfänglich an die Orchestrierung aus dem Hause Docker erinnern. Allerdings so wie Docker vielfach das Synonym für Container ist so ist Googles Kubernetes (K8s) der defacto Standard für Orchestrierungen.

Docker Swarm

Docker Swarm (Mode) auf docs.docker.com

Docker Swarm (Mode) auf docs.docker.com

Erläuterungen auf Docs Docker Hub - Docker Engine - Swarm Mode

Im Rahmen der Betrachtungen rund um Docker Compose habe ich dem Docker Mini Swarm bereits ein wenig Raum gegeben - siehe Kapitel Docker Mini Swarm. Hier lag der Schwerpunkt auf der Umsetzung mittels einer (in Zahlen: 1) Docker Instanz / einem Docker Host, der dann einfach als Master für diesen Mini Swarm fungierte und mit derselben Docker Compose Datei genutzt werden konnte.

Um es also ganz genau zu sein: es handelt sich beim Docker Swarm um einen speziellen Swarm Mode für die Docker Engine.

Docker + Kubernetes

Docker (Inc.) empfiehlt für das Deployment von Orchestrierungen die Nutzung des Kubernetes Features im Docker Desktop. Oder anders gesagt: Docker (die Firma) schlägt vor Kubernetes zu nutzen, aber dabei auf Docker als Container-Dienstleister zu setzen.

Website Docker zum Thema Docker und Kubernetes

Und eine zentrale Rolle spielt hier wieder der Docker Desktop

Dann klappt es - zum Entwickeln - auch mit Kubernetes auf Windows Systemen mit dem Docker Desktop für Windows und aktivierter Kubernetes Unterstützung. Hier kommen die docker context Kommandos und Techniken ins Spiel. Das kubectl Tool sollte direkt verfügbar sein.

Kubernetes Distros

Kubernetes Distro Matrix by Nubenetes.com

Kubernetes Distro Matrix by Nubenetes.com

Jetzt stellen wir uns mal die Frage, ob wir uns die volle K8s Dröhnung geben wollen oder müssen. Denn eine solche Vanilla K8s Installation hat es schon in sich! Das fängt schon damit an, dass wir hier keine Standalone Lösung bekommen können - wir also mehrere Rechner (Bare Metal oder VMs) benötigen.

Für eine Übersicht über K8s Alternativen - sogenannte K8s Distros - können wir diverse Recherchen nutzen.

Der Link „Kubernetes Distributions & Installers Matrix Table“ führt über 40 dieser Tools auf!

Ich konzentriere mich im folgenden nur auf einige Wenige. Dabei müssen diese Distros für eine Seminarumgebung und meine/unsere Seminar-Klienten den bestmöglichen Lernfortschritt und Lernerfolg ermöglichen.

Des Weiteren vermeide ich alle puren Compony Driven Konzepte - meine Entscheidung.

Da ich in vielen kompakten - also sehr kurzen Seminaren - auch häufig mit Windows-Trainings-Systemen auskommen muss (und soll) ist hier auch wieder der Docker Desktop als Lösung reingerutscht. Die Lösung ist eben auch wirklich stark im Leistungsumfang und der technischen Nutzbarkeit gewachsen.

Kubernetes (k8s)

Für weitere Vertiefungen (und Übungen in und außerhalb meiner Seminare) habe ich eine kleine Linksammlung zu K8s erstellt: Links: Kubernetes.

Kubernetes (K8s) - Bild: growtika-GSiEeoHcNTQ-unsplash.jpg

Kubernetes (K8s) - Bild: growtika-GSiEeoHcNTQ-unsplash.jpg

Wenn wir von Kubernetes (K8s) reden, dann sprechen wir manchmal auch von Vanilla K8s - also dem direkten Original inklusive aller Deployments und Installationen aus dem Hause Google bzw. der Cloud Native Computing Foundation und gemäß aller K8s Dokumentationen.

Links zu K8s Webportalinfos:

Kubernetes Components (Website: kubernetes.io/docs/concepts/overview/components/)

Kubernetes Components (Website: kubernetes.io/docs/concepts/overview/components/)

Für Kubernetes nutze ich (noch) alternative digitale Unterlagen und Trainingsmaterialien. Und im Grunde gibt es im Netz auch bereits genügend Quellen für eine Einstimmung und Orientierung mit Kubernetes.

Ich nutze häufig eine minikube / Docker Umgebung für das praktische Erproben von kubectl Befehlen.

Folgende Bemerkungen zu diesem riesigen Technikgebiet sind angebracht:

  • Gute technische Kenntnisse über die grundlegenden Containertechniken sind sehr wichtig.

  • Und wie immer gilt: Kenntnisse bei Netzwerken helfen immer!

Am Besten lernt man die Techniken, wenn man sie einfach mal ausprobieren und praktisch erfahren kann.

minikube

minikube auf k8s.io - Documentation / Get Started

minikube auf k8s.io - Documentation / Get Started

Link zum Einstieg in minikube: minikube Docs - Start

Installation (Debian) und minikube start

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb

Den minikube starten und testen:

minikube start

Da passiert jetzt eine ganze Menge und das kann ein wenig dauern.

minikube start mit Emojis in gnome-terminal

minikube start mit Emojis in gnome-terminal

Bei Fehlern in Richtung ... context "default": context not found: ... bitte mal docker context use default als Lösung versuchen.

Der Kube Controller den wir von minikube nutzen können funktioniert mit einer erweiterten Syntax:

minikube kubectl -- get pods -A

NAMESPACE     NAME                               READY   STATUS    RESTARTS        AGE
kube-system   coredns-7db6d8ff4d-z8k9g           1/1     Running   0               3m14s
kube-system   etcd-minikube                      1/1     Running   0               3m30s
kube-system   kube-apiserver-minikube            1/1     Running   0               3m30s
kube-system   kube-controller-manager-minikube   1/1     Running   0               3m29s
kube-system   kube-proxy-5gpxr                   1/1     Running   0               3m14s
kube-system   kube-scheduler-minikube            1/1     Running   0               3m30s
kube-system   storage-provisioner                1/1     Running   1 (3m14s ago)   3m28s

Man sieht hier die Elemente eines Kubernetes Systems.

Der Aufruf minikube kubectl -- ersetzt in Testumgebungen die Funktionalität des Standard Kube Controller Tools kubectl.

Wenn man auch auf produktive oder echte Kubernetes Technik zugreifen möchte, sollte man auf das native Tool kubectl wechseln und dabei die Versionierungen beachten.

Wichtig

Das richtige Kube Controller Tool kubectl sollte nur um eine Version von unserer minikube Version abweichen - siehe minikube kubectl -- version. Das echte kubectl - bwz. die Installationsanleitung - findet man online: Installation von kubectl on Linux.

Das Lernwerkzeug minikube hat natürlich kleinere Einschränkungen gegenüber dem Vanilla bzw. vollem k8s. Hierzu zählen neben dem Umstand, dass wir immer nur einen Node haben auch Unterschiede bei der Service Komonente: minikube kann die Pod-Services nur über den NodePort veröffentlichen. Eine EXTERNAL-IP (siehe Spaltenüberschrift get service …) ist immer <pending>.

kubectl alias und Shell Completion

Wenn man bei der minikube kubectl Veriante bleibt, dann sollte man die Umgebung mit einem Alias kubectl="minikube kubectl --" erweiteren.

Bei Debian ist die Standard Bash-Completion bereits installiert und verfügbar - siehe Paket bash-completion. Jetzt kann man mittels einer zusätzlichen Bashrc Zeile die kubectl Kommandokomplettierung aktivieren.

echo 'source <(kubectl completion bash)' >>~/.bashrc

minikube Dashboard

Eine grafische Übersicht lässt sich mit minikube dashboard starten.

Hierzu wird mit Hilfe eines minikube AddOns dashboard eine grafische Konsole für die Verwaltung im Browser offeriert.

minikube AddOns

Der minikube bringt Erweiterungen mit, für die man sich eine einfache Übersicht anzeigen lassen kann: minikube addons list.

DevOps - CI/CD

Wikipdia - DevOps Beitrag

Wikipdia - DevOps Beitrag

Diese Begriffe sind aus den heutigen Umgebungen von Softwareentwicklung im Enterprise-Umfeld nicht mehr wegzudenken.

Diese Begriffe stehen auch für die breite Aufstellung von Technik und Lösungen und natürlich finden wir im Bereich der Entwicklung auch die Container wieder. In Kurzform:

Vertiefende Beschäftigungen und Erläuterungen siehe Literatur DevOps Projekte (DevOps Projekte - Autor: Sujeevan Vijayakumaran - Rheinwerk Verlag).

Auch an dieser Stelle will ich eine abgespeckte Liste von DevOps Werkzeugen folgen lassen, die wie immer keinesfalls den Anspruch auf Vollständigkeit erhebt.

  • Jenkins - der Klassiker für Automatisierungen bei der Software Entwicklung

  • Azure DevOps

  • GitHub Actions

  • GitLab Runner - Documentation GitLab Runner

Für das Webseitentool Hugo habe ich im Kapitel Hugo eine beispielhafte manuelle Umsetzung gezeigt.

Im folgenden Abschnitt wollen wir das Hugo-Projekt über einen Job in Form eines GitLab Runner umsetzen lassen.

Hugo GitLab Runner

Hugo GitLab Runner

Hugo GitLab Runner

In einem anderen Programming Abschnitt Hugo haben wir uns die manuelle Erstellung von Webseiten mit Hugo Containern erarbeitet.

Wir können die Hugo-Projektsite über GitLab Repositories verwalten und nutzen eine Vorlage für eine Hugo GitLab Runner.

Eine entsprechende Anleitung findet sich bei den GitLab Documents:

Tutorial: Build, test, and deploy your Hugo site with GitLab

Weiterführende Einführungen in die Thematik der GitLab Runner und Software Deployments inklusive Software Tests:

Tutorial: Create a complex pipeline

Und natürlich sollte man abschließend noch auf die Möglichkeit hinweisen, die GitLab Repo Umgebung selber in der eigenen Infrastruktur zu hosten.

Container Tools

Container Tools - Werkzeuge rund um Container und Co

Container Tools - Werkzeuge rund um Container und Co (Bild: lucas-van-oort-fBZOVyF-96w-unsplash)

Bei den Standardwerkzeugen der Containertechniken hat man hohe und schnelle Entwicklungszyklen. Selbiges gilt für das umgebende Biotop an Zusatzprogrammen.

Ich stelle hier also nur eine winzige und persönliche Übersicht zu Tools und Techniken bereit, die keinerlei Anspruch auf Vollständigkeit oder Aktualität erhebt.

In dieser Technik-Szene gibt es eigentlich immer wieder eine kleinere oder größere Entdeckung zu machen. Das ist ja einerseite auch faszinierend und hält es frisch - andererseits muss man natürlich aufpassen, dass man nicht jeder Technikidee hinterherrennt.

Portainer

Portainer CE Dashboard

Portainer CE Dashboard

Auf portainer.io - oder natürlich über den Docker Hub - kann man eine Container-Oberflächentechnik finden, die sich einfach und schnell als Container nutzen lässt: Portainer.

Wichtig

Das folgende Beispiel ist ggf. nicht mehr aktuell! Bitte immer die aktuellen Anleitungen auf den entsprechenden Dokumentationen (hier: docs.portainer.io) beachten!

Und die Anleitungen unterscheiden sich natürlich auch nach der unterschiedlichen technischen Umgebung für das Ausrollen der Technik: Stand-Alone Linux Docker, Docker Desktop (mit/ohne WSL2), Docker Swarm oder auch anderen Environments wie Kubernetes.

docker volume create portainer_data

docker run -d -p 8000:8000 -p 9443:9443 --name portainer \
   --restart=always \
   -v /var/run/docker.sock:/var/run/docker.sock \
   -v portainer_data:/data portainer/portainer-ce:latest

Die Administrations-Oberfläche lässt sich dann auf dem Dockerhost über Port 9443 über ein selbst ausgestelltes - also ein von Portainer ausgestelltes - Zertifikat erreichen.

Lazydocker

Lazydocker in Action (small footprint)

Lazydocker in Action (small footprint)

Eine einfache Umsetzung per Docker Image in Kombination mit einem Alias könnte z.B. wie folgt umgesetzt werden.

Docker Image Kommando zur Nutzung von Lazydocker
docker run --rm -it \
   -v /var/run/docker.sock:/var/run/docker.sock \
   -v /yourpath:/.config/jesseduffield/lazydocker \
   lazyteam/lazydocker

Am Besten das Ganze Kommando als Alias in die Konfiguration der Shell verpacken (hier Bash).

echo "alias lzd='docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v /yourpath/config:/.config/jesseduffield/lazydocker lazyteam/lazydocker'" >> ~/.bashrc

Bitte daran denken, den entsprechenden Pfad zur LazyDocker Config anzupassen.

Natürlich könnte man LazyDocker auch als Docker Compose Lösung ausrollen:

LazyDocker Compose Datei: https://github.com/jesseduffield/lazydocker/blob/master/docker-compose.yml

version: '3'
services:
  lazydocker:
    build:
      context: https://github.com/jesseduffield/lazydocker.git
      args:
        BASE_IMAGE_BUILDER: golang
        GOARCH: amd64
        GOARM:
    image: lazyteam/lazydocker
    container_name: lazydocker
    stdin_open: true
    tty: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./config:/.config/jesseduffield/lazydocker

LazyDocker Links/Infos:

Dockge

Tool Dockge - URL: dockge.kuma.pet

Tool Dockge - URL: dockge.kuma.pet

Links:

Das Tool Dockge ist ein Spezialist für Docker Compose / Stack Technik. Es kann allerdings auch normale Container-Verwaltung bieten.

(Englische) Features (Liste aus em Github Repo - exkl. Fancy Emojiis)

  • Manage your compose.yaml files * Create/Edit/Start/Stop/Restart/Delete * Update Docker Images

  • Interactive Editor for compose.yaml

  • Interactive Web Terminal

  • (1.4.0 NEW) Multiple agents support - You can manage multiple stacks from different Docker hosts in one single interface

  • Convert docker run ... commands into compose.yaml

  • File based structure - Dockge won’t kidnap your compose files, they are stored on your drive as usual. You can interact with them using normal docker compose command

  • Reactive - Everything is just responsive. Progress (Pull/Up/Down) and terminal output are in real-time

  • Easy-to-use & fancy UI - If you love Uptime Kuma’s UI/UX, you will love this one too

Der Hinweis zu Uptime Kuma bezieht sich auf ein Monitoring Tool aus derselben Entwicklergemeinschaft:

Distrobox

Distrobox - Containerintegrierte Distros (Bild: distrobox.it)

Distrobox - Containerintegrierte Distros (Bild: distrobox.it)

Eine sehr spannende und effiziente Lösung gegen das lästige Distro-Hopping. Warum nicht einfach eine Distro (z.B. Debian) und beliebig interessierende alternative Distros vollständig in Konsole nachbilden. Das Ganze funktioniert sogar für GUI-Software-Installationen in diesen Distro-Containern.!

Originaltext von distrobox.it Entwicklerseite Luca Di Maio (lilipod):

Use any Linux distribution inside your terminal. Enable both backward and forward compatibility with software and freedom to use whatever distribution you’re more comfortable with. Distrobox uses podman, docker or lilipod to create containers using the Linux distribution of your choice.

The created container will be tightly integrated with the host, allowing sharing of the HOME directory of the user, external storage, external USB devices and graphical apps (X11/Wayland), and audio.

—distrobox.it - Luca Di Maio

Die folgende Linksammlung sollte den Einstieg in Distrobox ermöglichen:

Falls ich Einsätze in Seminaren habe und es sich ergibt, werde ich weitere Umsetzungen und Erfahrungen mit Distrobox hier einbauen.

KASM Workspaces

KASM Workspaces - Software und Desktops im Browser

KASM Workspaces - Software und Desktops im Browser

Die Produkte von KASM erlauben die Nutzung von einzelnen Applikationen bis hin zu kompletten Desktops (Linux und Windows) über einen Web-Client (aka Browser).

Zitat von der KASM Website:

Kasm Workspaces - The Workspace Streaming Platform

Stream your workspace directly to your web browser on any device and from any location.

—KASM kasmweb.com

Linksammlung:

Die KASM Images auf dem Docker Hub lassen sich natürlich auch ohne die KASM Workspace Umgebung nutzen. Mit dieser ist die Verwaltung der Workspaces (sprich: Images) allerdings deutlich effizienter und des Weiteren gibt es eine optimierte Grafik-/Multimedia- und Peripherie- Unterstützung.

Falls ich Einsätze in Seminaren habe und es sich ergibt, werde ich weitere Umsetzungen und Erfahrungen mit Distrobox hier einbauen.

JSON

Syntax JSON

Bei der Analyse von Images und Containern hilft das docker [...] inspect Kommando und es ergeben sich JSON Codes. Die Ausgaben entstehen also in Form von JSON Dateien (JSON Link Wikipdia).

Auch die Auflistungen von Images oder Containern kann man in JSON Formaten erzeugen. Es ergeben sich also divers Kontakte mit diesem Datenformat.

JSON Beispiel
{
  "name": "John Doe",
  "age": 30,
  "email": "john.doe@example.com",
  "address": {
    "street": "123 Main St",
    "city": "Anytown",
    "state": "CA",
    "zip": "12345"
  },
  "phoneNumbers": [
    {
      "type": "home",
      "number": "555-555-1234"
    },
    {
      "type": "mobile",
      "number": "555-555-5678"
    }
  ]
}

Bitte denken Sie beim Bearbeiten von JSON-Dateien an folgende Umsetzungen:

  • Kommas und Hochkommas sauber setzen - kein Komma mehr hinter dem letzten Listen- oder Dictionary-Element

  • Saubere eckige, geschweifte Klammern

  • Keine Kommentare

Im Seminar folgen praktische Tests und Empfehlungen für saubere Ausgaben, Formatierungen und Filterungen.

Tool jq und yq

Die Tools müssen ggf. noch nachinstalliert werden: z.B.

sudo apt install jq yq)

Das kann man auch für die verbesserte Ausgabe von manuellen HTTP-RESTful-Api Docker-Test mit Webbrowser curl nutzen:

curl -s --unix-socket /var/run/docker.sock http://localhost/images/json | jq

Anm./Erinnerung: die Nutzung eines Unix-Sockets kann sicherheitstechnisch einen Nachteil darstellen.

Beispiel: (Kurzerläuterung: JSON als Array interpretieren) - zur weiteren Hilfe gerne auch grafische Werkzeuge wie JSONCrack (s.u.)

Image Inspektion - nur Info zum Creation Date/Time ausgeben:

docker image inspect hello-world:latest | jq '.[0].Created'

Links zu Tool jq und yq:

Hinweis

JSON-Dokumente sind eine gültige Untermenge von YAML. Jedes JSON-Dokument ist auch ein gültiges YAML-Dokument.

JSON CRACK

Aktuell (2024) finden sich bei einer Online-Recherche zu Visualisierungstools rund um JSON viele Werkzeuge und da habe ich noch nicht mal die AI-Spielereien bedacht. Ich habe vor Jahren JSON CRACK entdeckt und schätzen gelernt.

Online Editor zu JSON CRACK: https://jsoncrack.com/editor

JSON CRACK Editor - Online oder Offline

JSON CRACK Editor - Online oder Offline

Mittlerweile gibt es auch eine VS Code Extension jsoncrack (VS Code Marketplace Link Jsoncrack).

Go Templates

Die Ausgabe von Docker Kommandos ist auch über Go-Templates möglich und ergeben auf Wunsch JSON Formate.

docker image inspect alpine:latest --format '{{.Config.Cmd}}'
[/bin/sh]

docker image inspect alpine:latest --format '{{json .Config.Env}}' | jq
[
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]

# weitere Beispiele
docker inspect -f "{{.State.Status}}" mariadb-test5
docker inspect -f "{{.State.FinishedAt}}" mariadb-test5

Oder aber wir optimieren die Ausgabetabelle eines Docker-Befehls über formatierte / tabellarische Ausgaben mit Schalter --format:

docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Labels}}"

Besondere Erwähnung neben dem Format table sollte hier das Format json erfahren, was uns wieder zurück zum Tool jq bringt!

Literatur

Die folgenden Docker Bücher liefern die Schwerpunkte zu unserer Seminarpraxis und den Übungen.

Literatur (Unsplash: susan-q-yin-2JIvboGLeho-unsplash.jpg)

Literatur (Unsplash: susan-q-yin-2JIvboGLeho-unsplash.jpg)

Und natürlich liefert auch die Linksammlung viele Quellen für weitere Beschäftigungen.

Hinweis

Texte und Anmerkungen zu den Büchern direkt von den Verlagen und Buchinfoseiten

Docker - Praxisbuch

Autoren: Bernd Öggl und Michael Kofler (Rheinwerk Verlag)

Docker: Das Praxisbuch für Entwickler und DevOps-Teams. Rückseite - Docker: Das Praxisbuch für Entwickler und DevOps-Teams. Docker: 4. Auflage - Das Praxisbuch für Entwickler und DevOps-Teams.

Docker: Das Praxisbuch für Entwickler und DevOps-Teams.

Hinweis

Das Buch wurde 2023 bereits in der 4. Auflage aufgelegt und ist seit 2024 auch in einer englischen Version verfügbar!

Codes: GitHub Repo docker-compendium/docker4-samples

Software-Container verstehen und produktiv einsetzen

Docker ist aus der modernen Softwareentwicklung nicht mehr wegzudenken.

Ob Sie in der Softwareentwicklung zuhause sind oder Systeme administrieren, ob Sie gerade einsteigen oder bereits produktiv mit Containern arbeiten: Dieses Buch zeigt Ihnen nicht nur Docker und die Containerwelt, es lässt Sie auch mit dem Troubleshooting und der Orchestrierung nicht allein.

Mit Best Practices, umfangreichem Werkzeugkasten und vielen Tipps zur Projekt-Migration, Container-Sicherheit, Docker ohne Root, Kubernetes, Podman, dem Docker Desktop und mehr.

  • Schritt für Schritt vom Setup bis zur Orchestrierung

  • Continuous Delivery: Grundlagen, Konzepte und Beispiele

  • Praxiswissen zu Projekt-Migration, Sicherheit, Kubernetes, Podman, Portainer und mehr

Aus dem Inhalt

  • Hello World! Docker einfach und gut einsetzen

  • Konzepte und Grundlagen

  • Docker-Kommandos

  • Docker Compose

  • Docker Desktop

  • Podman: Die Docker-Alternative

  • Werkzeugkasten: Server, Datenbanken, Programmiersprachen, Web-Apps

  • Projektmigration

  • Container-Sicherheit, Docker ohne Root

  • Continuous Integration und Delivery mit Gitlab, Multi-Arch-Builds

  • Docker in der Cloud & Kubernetes

  • Praxisbeispiele: LAMP-Stack im Container, Grafana und mehr

ISBN-Infos

510 Seiten,
4., aktualisierte Auflage 2023, gebunden
Rheinwerk Computing
ISBN 978-3-8362-9646-5
Docker: (1. Auflage) Das Praxisbuch für Entwickler und DevOps-Teams.
Gebundene Ausgabe: 431 Seiten
Verlag: Rheinwerk Computing; Auflage: 1 (24. August 2018)
Sprache: Deutsch
ISBN-10: 3836261766
ISBN-13: 978-3836261760
Größe und/oder Gewicht: 17,2 x 3 x 24,6 cm

Skalierbare Container

Autor: Oliver Liebel (Rheinwerk Verlag)

Skalierbare Container-Infrastrukturen für Ihr Unternehmen Rückseite - Skalierbare Container-Infrastrukturen für Ihr Unternehmen

Skalierbare Container-Infrastrukturen für Ihr Unternehmen

Hinweis

Das Buch wurde 2023 bereits in der 4. Auflage aufgelegt und Oliver Liebel hat noch seit 2023 ein Spezialbuch mit dem Titel „Skalierbare KI/ML-Infrastrukturen Evaluieren, Automatisieren, Praxis“ im Programm!

Die nächste Evolutionsstufe der Virtualisierung ist ein Pflichtthema für jedes Unternehmen, dem sich DevOps-Teams und Administratoren stellen müssen: Hochskalierbare und ausfallsichere Microservice-Umgebungen.

Mit diesem Handbuch verstehen Sie die Konzepte hinter den Technologien und können Container-Infrastrukturen auf Basis von Docker in Verbindung mit Swarm Mode, Kubernetes, Rancher, Mesos und DC/OS planen, aufbauen und orchestrieren. So stellen Sie Software schneller bereit und vereinfachen das Deployment und die Wartung Ihrer Infrastruktur – damit Ihre IT-Landschaft auch zukünftig den Anforderungen an Skalierbarkeit und Planungssicherheit gewachsen ist!

Aus dem Inhalt:

  • Warum Container? DevOps vs. Infrastruktur-Admin. Microservices und Skalierbarkeit

  • Continuous Integration / Continuous Delivery

  • DevOps vs. Infrastruktur-Admin, Microservices und Skalierbarkeit

  • Container Basics: Namespaces, Portierbarkeit, Sicherheit

  • Docker Container: Build, Ship and Run… everywhere? Applikationen im Container, Best Build Practices

  • Fortgeschrittene Verwaltung von Docker Containern: Layer, Storage Backends, Volumes und mehr

  • Trusted Registry, TLS, LDAP-Anbindung

  • Atomic, CoreOS/Container Linux und Rocket

  • World of Tiers – Orchestrierungs-Angelegenheiten

  • Geclusterte Key/Value Stores, Service Registry und Discovery: consul, etcd, zookepper

  • Schwarmintelligenz? Container-Cluster mit Swarm Mode, Docker Data Center

  • Planung, Installation, Administration eines Kubernetes-Clusters

  • Rancher

  • Mesos und DC/OS

  • Ausfallsichere und skalierbare Software Defined Storage-Backends für Container-Cluster: Ceph und Gluster

  • Wohin führt der Weg

Skalierbare Container-Infrastrukturen: Das Handbuch für Administratoren und DevOps-Teams.
Inkl. Container-Orchestrierung mit Docker, Rocket, Kubernetes, Rancher & Co.

Gebundene Ausgabe: 1071 Seiten
Verlag: Rheinwerk Computing; Auflage: 1 (28. April 2017)
Sprache: Deutsch
ISBN-10: 3836243660
ISBN-13: 978-3836243667
Größe und/oder Gewicht: 18,4 x 6,9 x 25,6 cm

Aktuelle Auflage: (Stand 2024)

Verlag: Rheinwerk Computing; Auflage: 4 (2023)
Sprache: Deutsch
ISBN-13: 978-3-8362-9753-0

Linux-Server

Autoren: Diverse (Rheinwerk Verlag)

Linux-Server (2018/2019) Rückseite - Linux-Server (2018/2019)

Linux-Server: Das umfassende Handbuch

Inkl. Samba, Kerberos, Datenbanken, KVM und Docker, Ansible u.v.m. (Ausgabe 2019)

Hinweis

Das Buch wurde 2023 bereits in der 7. Auflage aufgelegt und ist auf über 1300 Seiten gewachsen!

Mit eigenen Kapiteln zu Virtualisierung (Kap. 20) und Docker Containern (Kap. 21).

Auflage: 5 (23. November 2018)

Wie Sie Linux-Server effizient nach den aktuellen Standards administrieren, vermittelt Ihnen dieses Buch. Von Hochverfügbarkeit über Sicherheit bis hin zu Scripting und Virtualisierung: Sie lernen Linux-Server distributionsunabhängig intensiv kennen.

Das Buch bietet Ihnen über benötigtes Hintergrundwissen hinaus zahlreiche Praxisbeispiele zu den häufigsten in Unternehmen eingesetzten Distributionen. Und dank Shell-Programmierung, Python, Ansible sowie den im Buch vorgestellten Tools und Automatisierungsskripten lassen Sie Ihre Rechner für sich arbeiten!

Aus dem Inhalt:

  • Administrationsgrundlagen

  • Devices und Paketmanagement

  • Dateisysteme und Berechtigungen

  • Scripting und Shell-Coding

  • Dienste

  • Web-, Mail-, Proxy-, FTP- und Druckserver

  • Samba, LDAP, Kerberos, NFSv4

  • Infrastruktur und Netze

  • Hochverfügbarkeit

  • Virtualisierung (KVM, Docker)

  • Routing, Bonding, Firewalls

  • DHCP, DNS, OpenSSH

  • Versionskontrolle (VCS)

  • Sicherheit, Monitoring & Co.

  • Backup und Recovery

  • Verschlüsselung

  • Automatisierung

  • Ansible

  • PKI mit OCSP

ISBN-Infos

Linux-Server: Das umfassende Handbuch. Inkl. Samba, Kerberos, Datenbanken, KVM und Docker, Ansible u.v.m. (Ausgabe 2019)

Gebundene Ausgabe: 1270 Seiten
Verlag: Rheinwerk Computing; Auflage: 5 (23. November 2018)
Sprache: Deutsch
ISBN-10: 3836260921
ISBN-13: 978-3836260923
Größe und/oder Gewicht: 22,2 x 7,3 x 24,6 cm

Kubernetes Praxisbuch

Autor: Kevin Welter (Rheinwerk Verlag)

Kubernetes Praxisbuch (Vorderseite) Kubernetes Praxisbuch (Rückseite)

Das Praxisbuch für Entwickler und DevOps-Teams

Hinweis

Die erste Auflage beim Rheinwerk Verlag in 2024 zu Kubernetes.

Modernes Deployment für Container-Infrastrukturen

Kubernetes ist die Grundlage moderner IT-Infrastrukturen und ein unverzichtbares Werkzeug für das schnelle und agile Deployment von Anwendungen. W enn es doch nur nicht so komplex wäre! Die Lernkurve ist steil, die Architektur und das Zusammenspiel der zahlreichen Komponenten muss gut verstanden sein, damit kein Chaos entsteht.

In diesem Praxisbuch gibt Ihnen Kevin Welter eine gründliche Einführung in die Konzepte und Ideen containerisierter Umgebungen. Sie lernen die vielen Bestandteile einer Kubernetes-Installation kennen und erfahren praxisnah, wie Anwendungen deployt werden.

  • Vom Container-Management bis zum Deployment mit Helm

  • Resiliente, skalierbare und zuverlässige Infrastrukturen verwalten

  • Produktionsreife Anwendungen mit Service- und Ingress-Netzwerken, Loadbalancing und Self-Healing entwickeln

Aus dem Inhalt

  • Grundlagen und Konzepte

  • Pod- und Container-Management

  • Ressources as Code

  • Skalierung und Loadbalancing

  • Storage

  • Netzwerke und Sicherheit

  • Monitoring und Fehlersuche

  • Anwendungen für Kubernetes entwickeln

  • Paketmanagement mit Helm

ISBN Infos

427 Seiten, 2024, gebunden
Rheinwerk Computing
ISBN 978-3-8362-9883-4

DevOps Projekte

Autor: Sujeevan Vijayakumaran (Rheinwerk Verlag)

DevOps Projekte (Vorderseite) DevOps Projekte (Rückseite)

Wie IT-Projekte mit einem modernen Toolset und der richtigen Kultur gelingen

Hinweis

Erste Auflage in 2024 beim Rheinwerk Verlag. Der Autor Sujeevan Vijayakumaran hat auch ein sehr gutes Git-Buch geschrieben (MITP Verlag).

Neue Arbeitskultur für bessere Projekte

DevOps bedeutet nicht, dass Entwickler und Admins nun die gleichen Jobs erledigen.

DevOps bedeutet auch nicht, dass man beim Programmieren tägliche neue Tools einsetzen muss, es keine geplanten Deployments mehr gibt und Software nur noch in Containern läuft.

DevOps ist viel größer: Es verspricht eine neue Kultur der Zusammenarbeit sowie bessere Prozesse und Workflows. So liefern Sie Änderungen schneller aus und sorgen für kürzere Feedback-Schleifen zwischen Development und Operations.

In zahlreichen Projekten hat Sujeevan Vijayakumaran gelernt, was in der Entwicklung und im Betrieb moderner Software gut funktioniert. Mit vielen Beispielen und Praxistipps zeigt er Ihnen, wie Sie eine moderne und zeitgemäße Arbeitsumgebung für Ihre IT-Projekte schaffen und die DevOps-Transformation in Ihrem Team gelingt.

  • Effizientes und effektives Teamwork mit schlanken Prozessen

  • Moderne IT-Infrastrukturen aufbauen und Projekte meistern

  • Source Code Management, Continuous Integration, Deployment & Delivery, Observability, Day-2-Operations

Aus dem Inhalt

  • Effizientes Zusammenarbeiten beim Programmieren

  • Schlanke Build-Prozesse

  • Frühe, schnelle und automatisierte Qualitätssicherung

  • Schnellere Releases erstellen und deployen

  • Den Dienst betreiben und überwachen

  • Sicherheit und Compliance unter einen Hut bringen

  • Continuous Integration: Tools richtig einsetzen

  • Continuous Delivery praktisch umsetzen

  • Monitoring und Observability für mehr Durchsicht

  • Mit DevOps-Plattformen die Tool-Landschaft vereinfachen

  • Jenseits von Kultur und Tools

ISBN Infos

459 Seiten
2024
gebunden
Rheinwerk Computing
ISBN 978-3-8362-9099-9

Scripting Praxisbuch

Autor: Michael Kofler (Rheinwerk Verlag)

Scripting Praxisbuch für Admins und DevOps - Kofler Scripting Praxisbuch für Admins und DevOps - Kofler

Scripting - Das Praxisbuch für Administratoren und DevOps-Teams

Hinweis

Das buch ist in erster Auflage in 2023 erschienen und stammt aus der bewährten Feder von Michael Kofler!

Die Kunst, Probleme in 10 Zeilen zu lösen

Scripting ist die Kunst, Probleme in wenigen Zeilen Code zu lösen. Denn viele Aufgaben in der IT erfordern keine komplexen Lösungen in einer Hochsprache – oft reichen ein paar Zeilen Python-, Bash- oder PowerShell-Code.

Michael Kofler zeigt Ihnen in diesem Praxisbuch, wie Sie die Macht der Scripting-Umgebungen nutzen. Anhand zahlreicher Praxisbeispiele erfahren Sie, wie Sie Aufgaben automatisieren und wie Ihnen Shell- oder Pythonscripts viel Arbeit abnehmen können. Mit dabei ist ein Überblick über moderne Shell-Werkzeuge und IDEs: Visual Studio Code, Git, SSH und mehr.

  • Sicher mit Python, der PowerShell und Bash arbeiten

  • Automatisierungslösungen für Backups, Datenbanken, Web-Scraping und die Cloud

  • Tools und Workflows: SSH, Git, REST-APIs, RegExps, Filter und Pipes

Aus dem Inhalt

  • Bash, ZSH und die Linux-Toolbox

  • PowerShell und CmdLets

  • Python und Pip

  • SSH, VSCode, Git, Curl: Werkzeugenkasten für moderne Scripts

  • Scripts automatisch ausführen: Cron und Task Scheduler

  • Backups automatisieren

  • Bilder verarbeiten

  • Monitoring: Logging-Dateien auswerten

  • Web-Scraping und -Mining

  • Scripting in der AWS-Cloud

  • Scripte in Docker-Containern

ISBN-Infos

Auflage 1
492 Seiten, 2023
gebunden
Rheinwerk Computing
ISBN 978-3-8362-9424-9

Hyper-V

Autoren: Nicholas Dille, Marc Grote, Jan Kappen und Nils Kaczenski (Rheinwerk Verlag)

Microsoft Hyper-V Rückseite - Microsoft Hyper-V

Microsoft Hyper-V: Das Handbuch für Administratoren. Aktuell zu Windows Server 2016

Hinweis

Das Buch ist nur noch als E-Book verfügbar.

Wenn Sie mit Hyper-V unter Windows Server 2016 Server oder Desktops virtualisieren und Ihre Infrastruktur noch effizienter verwalten und auslasten möchten, liegen Sie mit diesem Buch goldrichtig.

Nicholas Dille, Marc Grote, Jan Kappen und Nils Kaczenski sind gefragte und in der Community bestens bekannte Hyper-V-Experten. Gemeinsam bieten Ihnen die Autoren neben allen wichtigen Grundlagen und fortgeschrittenen Virtualisierungstechniken vor allem eines: umfangreiches Praxiswissen.

Aus dem Inhalt:

  • Grundlagen Hyper-V

  • Host-Server

  • Storage

  • Netzwerk

  • VMs und Applikationen

  • Container

  • Verfügbarkeit

  • Betrieb, Backup und Recovery

ISBN-Infos

Microsoft Hyper-V: Das Handbuch für Administratoren. Aktuell zu Windows Server 2016

Gebundene Ausgabe: 948 Seiten
Verlag: Rheinwerk Computing; Auflage: 3 (29. Mai 2017)
Sprache: Deutsch
ISBN-10: 383624327X
ISBN-13: 978-3836243278
Größe und/oder Gewicht: 18,4 x 6 x 24,9 cm

Linksammlung

Die folgende Linksammlung natürlich ohne Anspruch auf Vollständigkeit ;-) und mit dem Versuch einer Gliederung.

Linksammlung - eine Unsplash Crop Impression

Linksammlung (Bild Unsplash: jon-tyson-i0LcODk-V1Q-unsplash.jpg)

Bitte den folgenden Tipp beachten!

Tipp

Erst nach dem Seminar stöbern!

Und los geht es…

ReStructuredText

Hier folgen abschließend noch die Meta-Infos zur Dokumentenversionspflege mit Hilfe von restructuredText:

restructuredText

restructuredText auf Wikipedia

Kurzinfo auf Wikipedia zu rST

reStructuredText (kurz ReST, reST oder RST) ist eine vereinfachte Auszeichnungssprache (Markup) mit dem Ziel, in der reinen Textform besonders lesbar zu sein.

Wikipedia - restructuredText

Die reST-Dokumenten lassen sich nahezu beliebig in gewünschte Formate wandeln:

  • ODT - OASIS Open Document Format for Office Applications

    Kurzform: OpenDocument, ODF – engl. Offenes Dokumentformat für Büroanwendungen

  • Textformate wie für LibreOffice, Microsoft Word

  • HTML - diverse HTML-Varianten (Websitestile)

  • LaTex

    professioneller Schriftsatz mit Exportmöglichkeiten nach PostScript und PDF

  • PDF (bzw. PostScript)

  • Epub - Standard für eBooks

Desweiteren lassen sich die Dokumente

  • professionell verlinken (taggen)

  • indizieren und

  • durchsuchen.

Weiter Infos zur verwendeten Sphinx/reStructuredText Technik folgen.

Sphinx Vorlage TYPO3

TYPO3 Sphinx reStructuredText Technik

TYPO3 Sphinx reStructuredText Technik

Für dieses Dokument nutze ich eine modifizierte Sphinx Vorlage aus dem Hause TYPO3:

Leider kann man ohne die Dev-Umgebung für die TYPO3-Dokumentation nicht alle Stilmittel direkt nutzen. Diese Umgebung liegt natürlich auch wieder als Container-Lösung vor!

Bildinfos

Alle Bildmaterialien in dieser Ausarbeitung wurden nach bestem Wissen recherchiert und sind gemäß ihrer geforderten Bedingungen hinsichtlich des Autors kommentiert.

Unsplash.com - Freie Bilder

Unsplash.com - Freie Bilder

Die entsprechenden Bildmaterialien entstammen folgenden Quellen:

  • Eigene Bildmaterialien

    oder Bildkompositionen

  • Wikipedia

    Link zum Wikipedia Bild (inkl. Autorennennung)

Für die Verwendung der freien Unsplash Resourcen folgen noch weitere Erläuterungen.

Unsplash

Aus dieser Quelle werden alle Bildmaterialien mit Bildname attributisiert.

Erklärung zum Bildcode:

Bildcode Unsplash

Info

Inhalt

Bildname

magnet-me-beCkhUB5aIA-unsplash.jpg

Unsplash Autor

magnet-me

Bildcode

beCkhUB5aIA

Aus dem Unsplash-Bild-Code (hier: beCkhUB5aIA) lässt sich der Bildlink zum Unsplash-Portal zusammenbauen:

  • https: // unsplash.com / photos / Bildcode

  • https: // unsplash.com / photos / beCkhUB5aIA

Abweichende Bild-Quellen wurden entsprechend kommentiert/dokumentiert.

Status dieser Unterlage

Status des Git-reStructuredText Projekts in Arbeit (Bild Unsplash: richy-great-MAYEkmn7G6E-unsplash.jpg)

Status des Git-reStructuredText Projekts in Arbeit (Bild Unsplash: richy-great-MAYEkmn7G6E-unsplash.jpg)

Meine inhaltlichen Aufbereitungen zu den Themen unserer Seminarreihe unterliegen ständigen Änderungen und Aktualisierungen.

Bemerkung

Diese Dokument befindet sich in stetiger Überarbeitung. Fehlerbereinigung (Typos) oder eine ggf. noch fehlende Indexierung der Dokumente ist ein Work in Progress und findet auch im Seminar statt.

Fragen Sie also gerne auch einmal später nach einer aktualisierten Variante dieser Ausarbeitung und beziehen sich dabei bitte auf die entsprechende Versionsnummer des Dokuments (oder der angegebenen Versionierung).

Version

Versionierungsmerkmale für die reST-Dokumentstrukturen

Hier folgen jetzt Meta-Infos zur Dokumentenversionspflege:

Version:

2.1-2025

Language:

de

Description:

Unterlagen zu Docker Seminaren Trainer Joe Brandes.

Erstellt mit restructuredText / Sphinx / ReadTheDocs / sphinx_typo3_theme v4.9.0!

Keywords:

Docker, Seminarunterlage, Trainer Joe Brandes

Copyright:

Joe Brandes

Author:

Joe Brandes

License:

GNU General Public License, either version 2 of the License or any later version.

Rendered:

22.03.2025