Docker ist ein wichtiger Baustein im Umfeld von DevOps und Continuous Delivery.
Docker ist eine Virtualisierungslösung, die keinen Hypervisor einsetzt, sondern "Operating-system-level Virtualization" mit Linux-Containern verwendet. Diese Container sind unabhängig voneinander, aber verwenden Teile des Linux-Kernels gemeinsam. Dadurch ist die Effizienz wesentlich höher als bei anderen Virtualisierungslösungen.
DevOps propagiert einen Paradigmenwechsel: Softwareentwicklung und Betrieb sollen nicht gegeneinander, sondern miteinander arbeiten. Dabei gewinnt Continuous Delivery zunehmend an Bedeutung.
Continuous Delivery
(kontinuierliche Auslieferung/Übergabe)
bezeichnet in der Softwareentwicklung eine Sammlung von Techniken, Prozessen und Werkzeugen,
welche kurze Entwicklungszyklen mit häufigen Softwareupdates bis hin zum produktiven System ermöglicht.
Dies wird ermöglicht durch eine weitgehend automatisierte "Deployment Pipeline" / "Delivery Pipeline" mit
automatisierten Build-Prozessen, Auslieferungen, Installationen, Tests (Continuous Integration) und Deployments.
Um eine
Continuous Deployment Pipeline / Continuous Delivery Pipeline
zu ermöglichen, werden häufig Virtualisierungslösungen eingesetzt.
Es gibt zwei grundsätzliche Kategorien von Virtualisierungslösungen, die sich in der eingesetzten Technik unterscheiden:
Docker ist eine Virtualisierungslösung, die keinen Hypervisor einsetzt, sondern "Operating-system-level Virtualization" (= "Betriebssystemvirtualisierung") verwendet. Anders als die VM/Hypervisor-Lösungen zur Virtualisierung bietet Docker keine vollständige Virtualisierung in virtuellen Maschinen (VMs), sondern stattdessen Linux-Container (per LXC oder Libcontainer, sowie chroot, Namespaces, Cgroups). Diese Container sind unabhängig voneinander, aber verwenden Teile des Linux-Kernels gemeinsam. Dadurch ist die Effizienz wesentlich höher als bei anderen Virtualisierungslösungen. Auf einer Hardware können wesentlich mehr Docker-Container betrieben werden als VMs.
Anders als VM/Hypervisor-Lösungen war Docker bis April 2016 auf Linux als Host-Basis angewiesen.
Auf Windows und Mac OS X konnte es nur mit einem zusätzlichen Linux-Layer installiert werden,
z.B. per Docker Toolbox
(enthält Boot2Docker und
Oracle VirtualBox).
Ähnliches gilt für das Gast-Betriebssystem: Nur Linux ist möglich. Der Gast verwendet den Linux-Kernel des Hosts.
Seit April 2016 gibt es Beta-Versionen von Docker for Mac and Docker for Windows, die als native Anwendungen laufen und ohne VirtualBox auskommen. Die Docker-Engine läuft unter einem Alpine-Linux auf einer virtuellen Maschine (Hyper-V bei Windows und xhyve in OS X).
Vorteile von Docker sind (teilweise ähnlich wie für VMs):
Wichtige Elemente von Docker sind:
Die Cloud Native Computing Foundation (CNCF) fördert die Enwicklung gemeinsamer Standards zur Infrastruktur von nativen Cloud-Anwendungen. Damit sind verteilte Anwendungen gemeint, die aus Microservices zusammengesetzt sind, die in Container verpackt sind (z.B. Docker-Container), welche dynamisch in der Cloud verteilt und ausgeführt werden. CNCF fokussiert auf drei Schichten bzw. Service-Ebenen:
Statt Anwendungen als schwer wartbare Monolithen zu bauen, werden Sie gerne in kleinere Einheiten gegliedert, die fachlich in sich geschlossen sind, und die einzeln unabhängig voneinander entwickelt, deployt, skaliert, upgedatet und ausgetauscht werden können. Dies ist mit den Stichworten Microservices bzw. Self-contained Systems (SCS) gemeint. Microservices sind in der Regel kleiner geschnitten als SCS-Module, weshalb bei SCS das Management, das Monitoring und der Betrieb etwas weniger komplex sein können. Sowohl Microservices als auch Self-contained Systems werden ideal durch Docker-Container unterstützt.
Zu Self-contained Systems (SCS) siehe: Self-contained Systems (Wikipedia), Self-contained Systems (scs-architecture.org), SCS vs. Microservices (scs-architecture.org), Self-contained Systems – ein Architekturstil stellt sich vor (Eberhard Wolff), Self-Contained Systems and ROCA, Spring Boot, Thymeleaf and Bootstrap (Tobias Flohre),
Zu Microservices siehe: Microservices im Zusammenspiel mit Continuous Delivery (Eberhard Wolff), Microservices (Martin Fowler), Microservices: Decomposing Applications for Deployability and Scalability (Chris Richardson), Microservices Architecture (Chris Richardson), Microservices Primer (Eberhard Wolff), Buch: Microservices, Grundlagen flexibler Softwarearchitekturen (Eberhard Wolff), Microservices (Javamagazin 5.16).
Zur Kombination von Microservices mit Docker siehe: Micro-Services mit Docker (Phillip Ghadir), Web-Apps in Docker-Umgebungen (Phillip Ghadir), Docker Microservice Basis mit Apache Tomcat (Peter Roßbach + Andreas Schmidt).
Das Erzeugen von Cloud-geeigneten autarken Microservices wird optimal unterstützt durch:
Zu Spring Boot siehe: Spring-Boot.html, Buch: Spring Boot in Action (Craig Walls), Buch: Spring Boot Cookbook (Alex Antonov).
Amazon bietet Dienste an, die Docker unterstützen:
Weiter unten finden Sie einfache Einsteigerbeispiele, die beispielsweise auch unter Windows ausgeführt werden können, und bei denen per Docker Toolbox und Docker mit wenigen Skriptzeilen ein Docker-Container mit Linux, Java und beispielsweise einem Tomcat- oder WebLogic-Server eingerichtet und gestartet wird, in dem beispielsweise eine einfache Hello-World-Webanwendung deployt und ausgeführt wird, die vom Host aus erreichbar ist.
Siehe auch: Docker-Homepage, Docker-Tutorial, Docker User Guide, Understanding Docker, Docker bei Wikipedia, XWiki zu Docker, Docker Toolbox, Anwendungen mit Docker transportabel machen (Golo Roden), Mit Docker automatisiert Anwendungscontainer erstellen (Golo Roden), Renaissance der Container-Virtualisierung mit Docker (Martin Loschwitz), Docker: die Linux-Basics unter der Container-Haube (Brunk + Albert + Magnus), Getting to know Docker – a better way to do virtualization? (Mark Nelson), Buch: Skalierbare Container-Infrastrukturen (Oliver Liebel, 2017), Buch: Docker Praxiseinstieg (Karl Matthias + Sean P. Kane, 2016), Buch: Docker: Software entwickeln und deployen mit Containern (Adrian Mouat, 2016), Buch: Kubernetes: Eine kompakte Einführung (Kelsey Hightower + Brendan Burns + Joe Beda, 2018), Container-Orchestrator Kubernetes: Einstieg für Docker-Kenner (Jan Mahn und Merlin Schumacher, 2019), Cloud native Java-Anwendungen mit Quarkus (Michael Vitz, 2019), Images für Java-Anwendungen bauen (Michael Vitz, 2020).
Es gibt vier Varianten, wie Docker-Container unter Windows betrieben werden können:
Produkt: | Docker Toolbox von Docker Inc. |
Docker for Windows von Docker Inc. |
Windows Containers von Microsoft |
Windows Containers von Microsoft |
||||
---|---|---|---|---|---|---|---|---|
betreibt: |
Linux- Anwendungs-Image |
Linux- Anwendungs-Image |
Windows- Anwendungs-Image |
Windows- Anwendungs-Image |
||||
basiert auf: | Boot2Docker-Linux |
Container-OS-Image Alpine Linux |
Container-OS-Image Windows Server 2016 Core oder Nano |
Container-OS-Image Windows Server 2016 Core oder Nano |
||||
verwendet: | VirtualBox VM | Hyper-V VM MobyLinuxVM | Windows Server Container |
Hyper-V-Container VMMP mit Mini-Windows-Kernel |
||||
läuft unter: |
ab Windows 7 und ab Windows Server 2008 |
Windows 10 Professional, Enterprise und Education (mit installiertem Hyper-V) |
Windows Server 2016 |
Windows 10 und Windows Server 2016 |
In allen vier Varianten können dieselben Kommandozeilenwerkzeuge zur Steuerung der Docker-Container eingesetzt werden, welche das Docker Remote API verwenden.
Von diesen vier Varianten können allerdings nur die linken beiden Linux-Anwendungs-Images betreiben. Die rechten beiden betreiben Windows-Anwendungs-Images.
Auf dieser Webseite wird fast ausschließlich die linkeste Variante mit der Docker Toolbox betrachtet.
Die Docker Engine, welche die Docker-Container ausführt, konnte im bisherigen WSL 1 (Windows-Subsystem für Linux) nicht ausgeführt werden. Nur der Docker-Client konnte im WSL ausgeführt werden. Siehe hierzu: WSL Interoperability with Docker.
Mit WSL 2 soll sich das ändern, siehe hierzu: WSL 2: Windows erhält einen echten Linux-Kernel.
Bevor konkrete Beispiele vorgeführt werden, wird wegen der grundsätzlichen Bedeutung in diesem Kapitel auf die verschiedenen Möglichkeiten zur Übertragung von Docker-Images eingegangen. Um dies nachvollziehen zu können, ist eine konkrete Installation von Docker erforderlich, was erst im darauf folgenden Kapitel beschrieben wird, gefolgt von vielen konkreten Docker-Beispielen. Die Bedeutung einiger der verwendeten Begriffe wird wahrscheinlich erst in den späteren Beispielen verständlich werden.
Es gibt verschiedene Wege, um ein Docker-Image (oder den Inhalt eines Docker-Containers) beispielsweise auf einen anderen PC zu übertragen und dort zu verwenden. Voraussetzung ist, dass sowohl auf dem "Anbieter-PC" als auch auf dem "Empfänger-PC" Docker installiert ist.
Per Dockerfile:
Falls Sie nicht den genauen aktuellen Stand eines Docker-Images oder -Containers weitergeben wollen, sondern stattdessen das ursprüngliche "Konstruktions-Skript" eines Docker-Images in Form des Dockerfile: Das Dockerfile ist eine simple Textdatei die am leichtesten weitergegeben werden kann. Wenn Sie nach "dockerfile" auf GitHub suchen oder sich das Dockerfile Project auf GitHub ansehen, finden Sie eine Unmenge an Beispielen. Mit "docker build ..." erzeugen Sie aus einem Dockerfile ein Docker-Image.
Den Inhalt eines Docker-Containers können Sie in ein Docker-Image in Ihrem lokalen Repository speichern:
docker commit <CONTAINER-ID> <mein-neuer-image-name>
Docker-Images in Ihrem lokalen Repository können Sie in tar-Dateien speichern und weitergeben:
docker save -o mein-image-save.tar <mein-image-name> speichert das Image in eine tar-Datei (auf dem "Anbieter-PC").
docker load -i mein-image-save.tar liest das Image aus der tar-Datei in das lokale Repository (auf dem "Empfänger-PC").
Den Inhalt eines Docker-Containers können Sie in eine tar-Datei speichern und weitergeben:
docker export -o mein-container-export.tar <CONTAINER-ID> speichert den Inhalt des Containers in eine tar-Datei.
cat mein-container-export.tar | docker import - mein-import-image-name liest den Container-Export in ein Image im lokalen Repository (auf dem "Empfänger-PC").
Während beim save die "Image-Historie" inklusive Metadaten und "Layer-Chain" erhalten bleibt, geht sie beim export verloren. Dafür sind export-Dateien etwas kleiner und zeigen entpackt (z.B. mit 7-Zip) die Dateisystemstruktur. Eine ausführlichere Erläuterung zum Unterschied zwischen save und export finden Sie unter Difference between save and export.
Per push und pull per "Public Registry" (z.B. Docker Hub Registry):
Falls Sie bei einer Public Registry einen Account eingerichtet haben, können Sie Ihr Image veröffentlichen:
docker push <mein-account-name>/<image-name>:<image-tag> lädt das Image hoch.
docker pull <mein-account-name>/<image-name>:<image-tag> lädt das Image herunter (auf dem "Empfänger-PC").
Per push und pull per "Private Registry" (z.B. Docker Registry 2.0):
Falls Sie Ihre Docker-Images nicht in eine öffentliche Docker-Registry hochladen wollen, können Sie eine eigene Registry einrichten. Dies wird häufig in Firmen-Intranets genutzt. Hierzu folgt weiter unten das Beispiel Eigene Docker-Registry ("Private Registry").
Nachdem Sie eine Private Registry installiert haben, können Sie Ihr Image weitergeben:
docker push <registry-host>:5000/<image-name>:<image-tag> lädt das Image hoch.
docker pull <registry-host>:5000/<image-name>:<image-tag> lädt das Image herunter.
Übersichtsgrafik zu den verschiedenen Austauschwegen:
Eine Beschreibung zur Installation von Docker unter Ubuntu-Linux finden Sie unter: Installation von Docker unter Ubuntu.
Docker benötigt eine Linux-Basis. Um Docker mit Windows oder Mac OS X zu betreiben, muss ein Linux-Layer installiert werden. Dazu gibt es verschiedene Verfahren. Weiter unten wird gezeigt, wie dies mit Vagrant möglich ist. Einfacher ist es mit Docker Toolbox (enthält Boot2Docker), was im Folgenden beschrieben wird. Zukünftig wird es auch ein Docker for Windows and Docker for Mac geben.
Für die folgenden unter Windows ausführbaren einfachen Einsteigerbeispiele wird eine einmalige Installation von Docker und Docker Toolbox benötigt (mit kleinen Anpassungen können die Beispiele auch unter Mac OS X oder Linux ausgeführt werden).
Die Beispiele wurden getestet mit:
Führen Sie folgende Schritte durch:
Ein aktuelles
Java SE JDK,
Maven und ein
Git-Client
müssen installiert sein, letzteres damit ssh.exe zur Verfügung steht.
Stellen Sie sicher, dass nicht nur der cmd-Pfad zu git.exe, sondern auch der bin-Pfad zu ssh.exe
in der PATH-Environmentvariable eingetragen ist.
Überprüfen Sie:
java -version
javac -version
mvn -v
git --version
ssh
Sie können VirtualBox gemeinsam mit der Docker Toolbox installieren.
Empfehlenswerter ist jedoch, VirtualBox separat vorher zu installieren.
Downloaden Sie
VirtualBox 5.0.22 for Windows hosts (x86/amd64)
und führen Sie VirtualBox-5.0.22-108108-Win.exe aus.
Sehen Sie sich das VirtualBox User Manual an.
Überprüfen Sie:
"C:\Program Files\Oracle\VirtualBox\VBoxManage" -v
"C:\Program Files\Oracle\VirtualBox\VirtualBox"
Downloaden Sie die Windows-Variante der
Docker Toolbox,
z.B. in Version 1.11.2.
Führen Sie DockerToolbox-1.11.2.exe aus, und deaktivieren Sie während der Installation die beiden Installationsoptionen VirtualBox und Git.
Sehen Sie sich an: Docker-Toolbox-Installation.
Überprüfen Sie:
docker-machine
docker
docker-machine -v
docker-compose -v
docker -v
Überprüfen Sie, ob die VM "docker-vm" bereits existiert:
docker-machine ls
Falls sie noch nicht existiert, erzeugen Sie für Docker die VM "docker-vm":
docker-machine create -d virtualbox docker-vm
docker-machine ls
docker-machine stop docker-vm
dir "C:\Users\%USERNAME%\.docker\machine\machines"
dir "C:\Users\%USERNAME%\VirtualBox VMs"
Falls Sie folgende Fehlermeldung erhalten:
Unable to start the VM: C:\Program Files\Oracle\VirtualBox\VBoxManage.exe startvm docker-vm --type headless failed:
VBoxManage.exe: error: Failed to open/create the internal network 'HostInterfaceNetworking-VirtualBox Host-Only Ethernet Adapter #...' (VERR_INTNET_FLT_IF_NOT_FOUND).
VBoxManage.exe: error: Failed to attach the network LUN (VERR_INTNET_FLT_IF_NOT_FOUND)
VBoxManage.exe: error: Details: code E_FAIL (0x80004005), component ConsoleWrap, interface IConsole
Details: 00:00:03.210592 Power up failed (vrc=VERR_INTNET_FLT_IF_NOT_FOUND, rc=E_FAIL (0X80004005))
Dann führen Sie aus:
Win+X (Windows-Taste und X) | Netzwerkverbindungen | VirtualBox Host-Only Network #... (#... wie in Fehlermeldung) |
rechte Maustaste: Eigenschaften | Aktivieren: VirtualBox NDIS6 Bridged Networking Driver.
Starten Sie erneut mit: "docker-machine start docker-vm" und beenden Sie mit "docker-machine stop docker-vm".
Erzeugen Sie zum Starten und Stoppen der Docker Machine möglichst im Verzeichnis \MeinWorkspace\MeinDockerMachine folgende zwei Batchdateien:
docker-machine-start.bat
docker-machine ls docker-machine start docker-vm docker-machine env --shell cmd docker-vm | find "DOCKER_" > docker-machine-env.bat call docker-machine-env.bat set DOCKER docker images docker ps -a
docker-machine-stop.bat
docker-machine ls docker-machine stop docker-vm docker-machine ls
Als minimales Demobeispiel wird im Folgenden gezeigt, wie eine einfache "Hello World"-Java-Webanwendung in einem Docker-Container deployt und ausgeführt werden kann.
Das Beispiel geht davon aus, dass als Host-Betriebssystem Windows verwendet wird. Es ist aber leicht an Mac OS X und Linux anpassbar.
Verwendet werden:
Führen Sie folgende Schritte durch:
Voraussetzung ist die erfolgreiche Installation von Java, Maven, Git und Docker Toolbox wie oben beschrieben wurde.
Testen Sie, ob der benötigte Port noch nicht anderweitig belegt ist:
netstat -an | find ":18080"
Damit vom Windows-Host aus auf die Webseite zugegriffen werden kann, wird per VBoxManage controlvm ein Port Forwarding vom VirtualBox-Linux-Layer zum Windows-Host für den Port 18080 konfiguriert. Rufen Sie auf:
docker-machine start docker-vm
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "Tmct-18080,tcp,127.0.0.1,18080,,18080"
docker-machine stop docker-vm
Kontrollieren Sie das Ergebnis im GUI:
"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe"
Klicken Sie links auf "docker-vm", oben auf "Ändern", dann auf "Netzwerk", "Erweitert" und "Port-Weiterleitung".
Wenn Sie nach "tomcat" in der Docker Hub Registry und nach "docker tomcat" auf GitHub suchen, erhalten Sie sehr viele Treffer sowohl für Dockerfiles als auch für Docker-Images. Im Folgenden wird das tomcat-9-Docker-Image aus dem so genannten "official Repo" aus der Docker Hub Registry verwendet.
Sehen Sie sich hierzu die Doku zum Tomcat:9-jre8-alpine-Docker-Image und das dazugehörende Tomcat:9-jre8-alpine-Dockerfile an.
In diesem Beispiel wird das tomcat-Docker-Image direkt verwendet, ohne zusätzliches Dockerfile.
Im anschließenden Beispiel wird das tomcat-Docker-Image zusammen mit einem eigenen Dockerfile verwendet.
Starten Sie Docker Machine mit der oben erstellten Batchdatei:
cd \MeinWorkspace\MeinDockerMachine
docker-machine-start.bat
Starten Sie den Tomcat-Docker-Container (falls das Image noch nicht lokal vorhanden ist, wird es automatisch herunter geladen):
docker run -it --rm -p 18080:8080 tomcat:9-jre8-alpine
Zu den docker-run-Kommandozeilenparametern siehe Docker-run-Options.
Warten Sie bis
"INFO [main] org.apache.catalina.startup.Catalina.start Server startup"
gemeldet wird, und sehen Sie sich die Tomcat-Basis-Webseite an:
start http://localhost:18080
Sie können eine beliebige Webanwendungs-WAR-Datei deployen. Für dieses simple Beispiel öffnen Sie ein zweites Kommandozeilenfenster, wechseln in ein beliebiges Projekte-Workspace-Verzeichnis (z.B. \MeinWorkspace) und erzeugen folgendermaßen mit Maven eine "Hello World"-WAR:
cd \MeinWorkspace
mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=de.meinefirma.meinprojekt -DartifactId=MeinDockerTomcat
cd MeinDockerTomcat
mvn package
Initialisieren Sie auch im zweiten Kommandozeilenfenster die Docker-Umgebungsvariablen mit der oben erstellten Batchdatei:
\MeinWorkspace\MeinDockerMachine\docker-machine-start.bat
Ermitteln Sie mit docker ps die 12-stellige Container-ID des laufenden Tomcat-Containers, ersetzen Sie damit im folgenden Kommando den Platzhalter <CONTAINER-ID>, und kopieren Sie die eben erzeugte WAR-Datei in den Docker-Container:
docker ps
docker cp target\MeinDockerTomcat.war <CONTAINER-ID>:/usr/local/tomcat/webapps/
Warten Sie einen Moment, bis das Deployment fertig ist, und rufen Sie im Webbrowser Ihre deployte Webanwendung auf:
start http://localhost:18080/MeinDockerTomcat
--> Sie erhalten die gewünschte "Hello World"-Webseite:
Hello World!
Sehen Sie sich die Erläuterungen im nächsten Kapitel an.
Kurzes Resümee:
Als einfaches Demobeispiel wird im Folgenden gezeigt, wie mit sehr wenigen Skriptzeilen ein neues Image erzeugt werden kann, indem ein vorhandes Image per Dockerfile um eigene Anweisungen erweitert wird. Es wird wieder die einfache "Hello World"-Java-Webanwendung in den Docker-Container deployt und gestartet.
Führen Sie folgende Schritte durch:
Voraussetzung ist die erfolgreiche Durchführung des vorherigen Beispiels MeinDockerTomcat.
Wechseln Sie in das MeinDockerTomcat-Projektverzeichnis und führen Sie aus:
cd \MeinWorkspace\MeinDockerTomcat
md dockerDirectory
copy /B target\MeinDockerTomcat.war dockerDirectory\MeinDockerTomcat.war
Anders als im letzten Beispiel soll diesmal mit einem Dockerfile ein neues Image erzeugt werden, abgeleitet vom Tomcat:9-jre8-alpine-Docker-Image. Erzeugen Sie im Unterverzeichnis dockerDirectory die Datei: Dockerfile
FROM tomcat:9-jre8-alpine MAINTAINER Mein Name <meine@email.adresse> ADD MeinDockerTomcat.war /usr/local/tomcat/webapps/ CMD ["catalina.sh", "run"]
Sehen Sie sich hierzu die Dockerfile Reference an.
Sehen Sie sich die Verzeichnisstruktur an:
tree /F
Sie erhalten:
[\MeinWorkspace\MeinDockerMachine] '- docker-machine-start.bat [\MeinWorkspace\MeinDockerTomcat] |- [dockerDirectory] | |- Dockerfile | '- MeinDockerTomcat.war |- [src] | '- [main] | '- [webapp] | |- [WEB-INF] | | '- web.xml | '- index.jsp |- [target] | |- MeinDockerTomcat.war | '- ... '- pom.xml
Wechseln Sie ins MeinDockerTomcat-Projektverzeichnis und starten Sie Docker Machine mit der oben erstellten Batchdatei:
cd \MeinWorkspace\MeinDockerTomcat
..\MeinDockerMachine\docker-machine-start.bat
Bauen Sie das neue Docker-Image meintomcatimage und starten Sie damit einen neuen Docker-Container:
docker build -t meintomcatimage dockerDirectory
docker run -it --rm -p 18080:8080 meintomcatimage
Zu den docker-Kommandozeilenparametern siehe docker build Usage, docker build Options und docker run Options.
Achten Sie darauf, dass zwischendurch
"INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive /usr/local/tomcat/webapps/MeinDockerTomcat.war"
angezeigt wird. Warten Sie bis
"INFO [main] org.apache.catalina.startup.Catalina.start Server startup"
gemeldet wird,
und sehen Sie sich an:
start http://localhost:18080
start http://localhost:18080/MeinDockerTomcat
--> Sie erhalten wieder die gewünschte "Hello World"-Webseite:
Hello World!
Öffnen Sie ein weiteres Kommandozeilenfenster, führen Sie darin die generierte docker-machine-env.bat aus,
und testen Sie bei laufendem Container
docker-Kommandos und
docker-machine-Kommandos
(siehe auch Migrate from Boot2Docker to Docker Machine),
beispielsweise:
docker zur Anzeige der Docker-Kommandos.
docker info zur Anzeige von Docker-relevanten Systeminformationen.
docker images zur Anzeige der Docker-Images im lokalen Repository (inklusive der IMAGE-IDs).
docker ps -a zur Anzeige der Docker-Container (inklusive der CONTAINER-IDs).
docker diff <CONTAINER-ID> zur Anzeige von Unterschieden.
docker logs <CONTAINER-ID> zur Anzeige von Logs (z.B. von Daemons).
docker stats <CONTAINER-ID> zur Anzeige des CPU- und Memory-Verbrauchs.
docker stop <CONTAINER-ID> zum Beenden eines laufenden Docker-Containers.
docker rm <CONTAINER-ID> zum Löschen von nicht mehr benötigten Containern.
docker rmi <IMAGE-ID> zum Löschen von nicht mehr benötigten Images im lokalen Repository.
docker run -v ... zum Anbinden eines Volumes als "Shared Folder".
docker run -d ... zum Betreiben der Anwendung im Hintergrund als "Daemon".
docker cp Quelldatei <CONTAINER-ID>:/Zielpfad/Zieldateiname zum Kopieren einer Datei in den Container.
docker exec <CONTAINER-ID> ... zum Ausführen von Kommandos im Container.
docker exec -it <CONTAINER-ID> bash für ein Kommandozeilenfenster zum Container.
docker-machine zur Anzeige der docker-machine-Kommandos.
docker-machine ls zur Anzeige der Docker Machines und ihrer Stati.
docker-machine ssh docker-vm für SSH-Zugang zum VirtualBox-Linux-Layer.
Sie können dem "docker run ..."-Kommando hinter dem Image-Namen auch ein Kommando übergeben.
Dann wird das im Dockerfile in der letzten Zeile unter "CMD ..." angegebene Kommando nicht ausgeführt,
sondern stattdessen das von Ihnen per Kommandozeile übergebene Kommando.
So können Sie beispielsweise per "/bin/bash" zu einem bash-Terminal (Shell-Fenster / Kommandozeilenfenster)
im Container gelangen:
docker run -it --rm -p 18080:8080 meintomcatimage /bin/bash
Jetzt können Sie beliebige Linux-Shell-Kommandos im Container ausführen. Z.B. können Sie so den Tomcat auch manuell starten:
catalina.sh run
Sie können beim "docker run ..."-Kommando mit der -v-Option auch einen "Shared Folder" einrichten, also ein Verzeichnis, welches sowohl innerhalb des Containers als auch im Linux-Host erreichbar ist. Damit der Shared Folder auch im Windows-Host erreichbar ist, müssen Sie entweder einen Shared Folder in VirtualBox einrichten (siehe VBoxManage sharedfolder) oder ein Unterverzeichnis zu C:\Users\%USERNAME% verwenden. Letzteres macht folgende Kommandozeile (achten Sie genau auf Groß-/Kleinschreibung):
docker run -it --rm -v /c/Users/%USERNAME%/docker-shared:/home/docker/docker-shared -p 18080:8080 meintomcatimage /bin/bash
Beispielsweise können Sie in dem so gestarteten Container-Shell-Terminal im Shared Folder Dateien erzeugen:
cd /home/docker/docker-shared
echo yy > y.txt
ls -l
Gleichzeitig können Sie von einem Windows-Kommandozeilenfenster aus in dem Shared Folder Dateien erzeugen:
cd /D C:\Users\%USERNAME%\docker-shared
echo xx > x.txt
dir
Kurzes Resümee:
Um das vorherige Beispiel möglichst simple zu halten, wurde die aus dem Maven-Build resultierende WAR-Datei per copy-Kommando vom target- in das dockerDirectory-Verzeichnis kopiert und anschließend wurde per docker build das Docker-Image erstellt. Diese beiden Schritte müssten während der Entwicklung immer wieder wiederholt werden, was bei aufwändigeren Projekten mit vielen Artefakten zu umständlich wäre.
Auf GitHub finden Sie verschiedene docker-maven-plugins (z.B. alexec, rhuss, spotify, wouterd), welche eine Docker-Build-Integration für Maven bieten. Einige bieten darüber hinaus auch das Management von Docker-Containern. docker-maven-plugins sind insbesondere während der Entwicklung und für Integrationstests hilfreich.
In diesem Beispiel wird das spotify docker-maven-plugin verwendet. Im danach folgenden Beispiel wird das rhuss docker-maven-plugin verwendet.
Mit folgenden Schritten erweitern Sie das vorherige Beispiel um das spotify docker-maven-plugin:
Sehen Sie sich das spotify-docker-maven-plugin-Readme an und lassen Sie sich die möglichen Kommandos anzeigen über:
mvn com.spotify:docker-maven-plugin:0.4.9:help -Ddetail=true
Ersetzen Sie im MeinDockerTomcat-Projektverzeichnis den Inhalt der pom.xml durch:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.meinefirma.meinprojekt</groupId> <artifactId>MeinDockerTomcat</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>MeinDockerTomcat</name> <build> <finalName>MeinDockerTomcat</finalName> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.9</version> <configuration> <imageName>meintomcatimage</imageName> <dockerDirectory>dockerDirectory</dockerDirectory> <resources> <resource> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.war</include> </resource> </resources> </configuration> </plugin> </plugins> </build> </project>
Wechseln Sie ins MeinDockerTomcat-Projektverzeichnis und starten Sie Docker Machine mit der oben erstellten Batchdatei:
cd \MeinWorkspace\MeinDockerTomcat
..\MeinDockerMachine\docker-machine-start.bat
Entfernen Sie Reste vorheriger Testläufe:
docker images
docker rmi meintomcatimage
docker images
del dockerDirectory\MeinDockerTomcat.war
Führen Sie im MeinDockerTomcat-Projektverzeichnis den Maven-Build aus, starten Sie den Docker-Container und sehen Sie sich das Ergebnis an:
mvn clean package docker:build
docker run -it --rm -p 18080:8080 meintomcatimage
start http://localhost:18080/MeinDockerTomcat
--> Sie erhalten die gewünschte "Hello World"-Webseite:
Hello World!
Falls Sie targetPath verwenden und unter Windows eine Fehlermeldung erhalten ähnlich zu:
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:0.4.9:build (default-cli) on project ...: Exception caught: UNC path is missing sharename: /\...
Dann versuchen Sie ohne den targetPath-Eintrag auszukommen.
Das rhuss/jolokia-docker-maven-plugin bietet eine Docker-Build-Integration für Maven und unterstützt das Management von Docker-Images und Docker-Containern. Dies ist insbesondere während der Entwicklung und für Integrationstests hilfreich.
Es unterstützt folgende Schritte per Maven-Kommando:
Siehe auch: rhuss docker-maven-plugin bei GitHub, User Manual, Roland Huß Blog.
Roland Huß hat eine Beispielanwendung zum rhuss/jolokia-docker-maven-plugin zusammengestellt und veröffentlicht, die Folgendes demonstriert:
Mit den folgenden Schritten laden Sie das Beispiel und führen es aus (z.B. unter Windows):
Voraussetzung ist die erfolgreiche Installation von Java, Maven, Git und Docker Toolbox wie oben beschrieben wurde.
Kopieren Sie folgendermaßen die rhuss-docker-maven-plugin-Beispielanwendung docker-maven-sample von GitHub und sehen Sie sich das README.md an:
cd \MeinWorkspace
git clone http://github.com/rhuss/docker-maven-sample
cd docker-maven-sample
type README.md
Starten Sie Docker Machine mit der oben erstellten Batchdatei:
..\MeinDockerMachine\docker-machine-start.bat
Führen Sie den Integrationstest aus:
mvn clean install
Sie erhalten u.a.:
... [INFO] Building docker-maven-sample 0.0.1 ... [INFO] --- maven-shade-plugin:2.3:shade (default) @ docker-maven-sample --- ... [INFO] --- docker-maven-plugin:0.13.8:build (start) @ docker-maven-sample --- ... [INFO] DOCKER> [jolokia/docker-maven-sample:0.0.1] "service": Built image ... ... [INFO] --- docker-maven-plugin:0.13.8:start (start) @ docker-maven-sample --- [INFO] DOCKER> [postgres:8] "db": Start container ... ... [INFO] DOCKER> [jolokia/docker-maven-sample:0.0.1] "service": Start container ... ... ... org.flywaydb.core.internal.dbsupport.DbSupportFactory createDbSupport ... INFO: Database: jdbc:postgresql://db:5432/postgres (PostgreSQL 8.4) ... ... INFO: Starting Servlet Engine: Apache Tomcat/7.0.55 ... [INFO] --- maven-failsafe-plugin:2.17:integration-test (integration-test) @ docker-maven-sample --- ... Running org.jolokia.docker.maven.sample.jolokia.LogServiceIT ... [INFO] --- docker-maven-plugin:0.13.8:stop (stop) @ docker-maven-sample --- [INFO] DOCKER> [jolokia/docker-maven-sample:0.0.1] "service": Stop and remove container ... ... [INFO] DOCKER> [postgres:8] "db": Stop and remove container ... ... [INFO] BUILD SUCCESS
Beachten Sie den Host-Eintrag "db" in der PostgreSQL-URL jdbc:postgresql://db:5432/postgres, der auf Grund des --link-Aliaseintrags durch Docker auf die PostgreSQL-Datenbank im anderen Docker-Container umgeleitet wird.
MySQL ist eine beliebte leistungsfähige relationale Open-Source-Datenbank.
Wenn Sie nach "mysql" in der Docker Hub Registry und nach "docker mysql" auf GitHub suchen, erhalten Sie sehr viele Treffer sowohl für Dockerfiles als auch für Docker-Images.
Im Folgenden wird das mysql-Docker-Image aus dem so genannten "official Repo" aus der Docker Hub Registry verwendet, siehe https://hub.docker.com/_/mysql und mysql/5.7/Dockerfile.
Erstellen Sie ein Projektverzeichnis für Batchdateien zur MySQL-DB:
md \MeinWorkspace\MeinDockerMySql
cd \MeinWorkspace\MeinDockerMySql
Starten Sie Docker Machine mit der oben erstellten Batchdatei:
..\MeinDockerMachine\docker-machine-start.bat
Sie können die MySQL-Datenbank entweder nur für andere Docker-Container verwenden oder zusätzlich auch den Zugriff vom Windows-Host aus ermöglichen. Falls Sie letzteres wünschen, prüfen Sie, ob der gewünschte Port noch frei ist, und richten Sie Port Forwarding ein:
netstat -an | find ":3306"
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "MySQL-3306,tcp,127.0.0.1,3306,,3306"
Wir können direkt beim "docker run"-Kommando einfach das noch nicht heruntergeladene Docker-Image in der Docker Hub Registry angeben, dann würde es automatisch implizit heruntergeladen. Im Folgenden soll dies jedoch als expliziter Schritt erfolgen:
docker pull mysql:5.7
docker images
Jetzt können Sie die MySQL-Datenbank starten. Erzeugen Sie dabei per --cidfile eine Datei mit der Container-ID und vergeben Sie per --name einen Namen, damit die DB später von anderen Docker-Containern verwendet werden kann:
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysqlpwd --cidfile=meine-mysql-db.cid --name meine-mysql-db mysql:5.7
Damit Sie die Datenbank bequem starten und stoppen können, sollten Sie folgendermaßen Batchdateien erstellen:
set /P _MYSQL_DB_CID=<meine-mysql-db.cid
@echo docker start %_MYSQL_DB_CID% > meine-mysql-db-start.bat
@echo docker stop %_MYSQL_DB_CID% > meine-mysql-db-stop.bat
del meine-mysql-db.cid
Die Verzeichnisstruktur sieht jetzt so aus:
[\MeinWorkspace\MeinDockerMachine] '- docker-machine-start.bat [\MeinWorkspace\MeinDockerMySql] |- meine-mysql-db-start.bat '- meine-mysql-db-stop.bat
Falls Sie Port Forwarding zum Windows-Host eingerichtet haben, können Sie jetzt mit normalen Windows-DB-Tools wie beispielsweise SQuirreL auf die DB zugreifen (per jdbc:mysql://localhost:3306, root, mysqlpwd). Tipps zu ersten Gehversuchen wie die Anlage einer Database und weitere Tipps finden Sie unter MySQL.
Das folgende Beispiel zeigt, wie die soeben eingerichtete MySQL-DB von einem WebLogic Application Server verwendet werden kann.
Falls Sie den Java EE Application Server Oracle WebLogic 12.1.3
in einem Docker-Container betreiben wollen, sehen Sie sich an:
Oracle WebLogic Server on Docker Containers,
Oracle WebLogic on Docker,
Docker Images from Oracle,
Docker, Java EE 7, and Maven with WebLogic 12.1.3 (Bruno Borges),
Getting to know Docker – a better way to do virtualization? (Mark Nelson),
WebLogic on Docker auf GitHub,
WebLogic-Images bei Docker Hub Registry.
Die Installationsbeschreibungen auf den genannten Webseiten setzen in der Regel voraus, dass ausgehend von Linux installiert wird. Mit Docker Toolbox ist die Installation auch unter Windows möglich, was für Entwicklertests auf lokalen PCs sinnvoll sein kann. Dies wird im Folgenden beschrieben.
Die im Folgenden verwendeten Skripte sind gekürzte und angepasste Varianten der auf den oben genannten Webseiten gezeigten Skripte. Bitte sehen Sie sich hierzu in den Originalskripten die Dokumentation an. Beachten Sie die Lizenzbestimmungen in den Originalskripten und auf den Webseiten.
In diesem Kapitel wird die Installation von WebLogic 12.1.3 beschrieben. Im anschließend folgenden Kapitel wird auf WebLogic 12.2.1 eingegangen.
Führen Sie folgende Schritte aus:
Voraussetzung ist die Installation von Java, Maven, Git und Docker Toolbox, wie
oben beschrieben wurde.
Außerdem wird das Kommandozeilentool curl benötigt.
Falls Sie es noch nicht installiert haben: Downloaden Sie z.B.
Win64 - Generic, Win64 ia64 zip 7.33.0 binary, ohne SSL (curl-7.33.0-win64-nossl.zip),
entzippen Sie die Datei und kopieren Sie die resultierende curl.exe entweder in ein Verzeichnis, welches sich im PATH befindet,
oder in Ihr Projektverzeichnis.
Sehen Sie sich das curl-Manual und
mit "curl --help" die Kommandozeilenoptionen an.
Testen Sie, ob der benötigte Port noch nicht anderweitig belegt ist:
netstat -an | find ":17001"
Damit vom Windows-Host aus auf die Webseite zugegriffen werden kann, wird per VBoxManage controlvm ein Port Forwarding vom Docker-Toolbox-VirtualBox-Linux-Layer zum Windows-Host konfiguriert. Rufen Sie auf:
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "WL-17001,tcp,127.0.0.1,17001,,17001"
Sie können eine beliebige Webanwendungs-WAR-Datei deployen. Für dieses simple Beispiel wechseln Sie in ein beliebiges Projekte-Workspace-Verzeichnis (z.B. \MeinWorkspace) und erzeugen folgendermaßen mit Maven eine "Hello World"-WAR und zwei benötigte Unterverzeichnisse:
cd \MeinWorkspace
mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=de.meinefirma.meinprojekt -DartifactId=MeinDockerWebLogic
cd MeinDockerWebLogic
mvn package
md dockerDirectory1
md dockerDirectory2
Downloaden Sie die Java-Version jdk-8u74-linux-x64.rpm in das dockerDirectory1-Unterverzeichnis.
Downloaden Sie die WebLogic-Developer-Version "Zip distribution Update 2 for Mac OSX, Windows, and Linux" (wls1213_dev_update2.zip) in das dockerDirectory1-Unterverzeichnis.
Erstellen Sie im dockerDirectory1-Unterverzeichnis folgende Docker-Skriptdatei: Dockerfile
FROM oraclelinux:7 ENV JAVA_RPM jdk-8u74-linux-x64.rpm ENV WLS_PKG wls1213_dev_update2.zip ENV JAVA_HOME /usr/java/default ENV MW_HOME /u01/oracle/wls12130 RUN mkdir /u01 && chmod a+xr /u01 && \ useradd -b /u01 -m -s /bin/bash oracle COPY $WLS_PKG /u01/ COPY $JAVA_RPM /u01/ RUN rpm -i /u01/$JAVA_RPM && \ rm /u01/$JAVA_RPM RUN cd /usr/java/default/jre/lib/security && \ mv java.security java.security.old && \ sed "s/securerandom.source=file:\/dev\/random/securerandom.source=file:\/dev\/.\/urandom/" java.security.old > java.security WORKDIR /u01/oracle/ RUN chown oracle:oracle -R /u01 USER oracle RUN jar xf /u01/$WLS_PKG && \ ln -s /u01/oracle/wls12130 /u01/oracle/weblogic WORKDIR /u01/oracle/weblogic RUN sh configure.sh -silent && \ find /u01/oracle/wls12130 -name "*.sh" -exec chmod a+x {} \; && \ rm /u01/$WLS_PKG WORKDIR /u01/oracle ENV PATH $PATH:/u01/oracle/weblogic/oracle_common/common/bin CMD ["bash"]
Das sed-Kommando ersetzt im Java-Unterverzeichnis /usr/java/default/jre/lib/security in der Datei java.security die Zeile
securerandom.source=file:/dev/random
durch
securerandom.source=file:/dev/./urandom
Sehen Sie sich hierzu an: JDK-6521844 : SecureRandom hangs on Linux Systems, How To Improve Weblogic Servers Startup Time, Random number generation in Unix, Avoiding JVM Delays Caused by Random Number Generation.
Erstellen Sie im dockerDirectory2-Unterverzeichnis folgende Docker-Skriptdatei: Dockerfile
FROM weblogic-dev-jdk8-urandom:12.1.3 ENV ADMIN_PORT 8001 ENV NM_PORT 5556 ENV MS_PORT 7001 ENV USER_MEM_ARGS -Xms256m -Xmx1024m -XX:MaxPermSize=2048m COPY WLST12-Domain-DataSource.properties /u01/oracle/weblogic/ COPY WLST12-Domain-DataSource.py /u01/oracle/weblogic/ USER root RUN echo ". /u01/oracle/weblogic/user_projects/domains/MeineDomain/bin/setDomainEnv.sh" >> /root/.bashrc && \ echo "export PATH=$PATH:/u01/oracle/weblogic/wlserver/common/bin:/u01/oracle/weblogic/user_projects/domains/MeineDomain/bin" >> /root/.bashrc USER oracle WORKDIR /u01/oracle/weblogic RUN /u01/oracle/weblogic/wlserver/common/bin/wlst.sh -skipWLSModuleScanning /u01/oracle/weblogic/WLST12-Domain-DataSource.py EXPOSE $NM_PORT $ADMIN_PORT $MS_PORT ENV PATH $PATH:/u01/oracle/weblogic/wlserver/common/bin:/u01/oracle/weblogic/user_projects/domains/MeineDomain/bin:/u01/oracle CMD ["startWebLogic.sh"]
Erstellen Sie im dockerDirectory2-Unterverzeichnis folgende Properties-Datei:
WLST12-Domain-DataSource.properties
_WL_ADMIN_PORT= 8001 _WL_BASIS_DIR= /u01/oracle/weblogic _WL_HOME= /u01/oracle/weblogic/wlserver _WL_START_TEMPL= /u01/oracle/weblogic/wlserver/common/templates/wls/wls.jar _WL_ADMIN_USER= weblogic _WL_ADMIN_PASSWORD= weblogic0 _WL_DOMAIN_NAME= MeineDomain _DB_DS_JNDI= jdbc/MeinDatasourceJndiName _DB_DS_NAME= MeinMySqlDataSourceName _DB_DRV= com.mysql.jdbc.Driver _DB_URL= jdbc:mysql://mysql-db:3306/mysql _DB_USR= root _DB_PWD= mysqlpwd _DB_SQL= SQL SELECT 1 _DB_GLOB_TX_PROT= None
Beachten Sie den Host-Eintrag "mysql-db" in der MySQL-URL jdbc:mysql://mysql-db:3306/mysql, der mit Hilfe eines --link-Aliaseintrags durch Docker auf die MySQL-Datenbank im anderen Docker-Container umgeleitet wird.
Erstellen Sie im dockerDirectory2-Unterverzeichnis folgende WLST-Skriptdatei:
WLST12-Domain-DataSource.py
#===================================================================================== # WLST-Skript zur Konfiguration einer Domain und DataSource im WebLogic. # Parameter werden in Properties-Datei gesetzt: # WLST12-Domain-DataSource.properties #===================================================================================== def _createDatasource( _db_ds_name, _db_ds_jndi, _db_drv, _db_url, _db_usr, _db_pwd, _db_sql, _db_glob_tx_prot ): _datasource_cd_cmo = "/JDBCSystemResource/" + _db_ds_name + "/JdbcResource/" + _db_ds_name cd( "/" ) create( _db_ds_name, "JDBCSystemResource" ) cd( _datasource_cd_cmo ) create( "myJdbcDriverParams", "JDBCDriverParams" ) cd( "JDBCDriverParams/NO_NAME_0" ) set( "DriverName", _db_drv ) set( "URL", _db_url ) set( "PasswordEncrypted", _db_pwd ) create( "myProps", "Properties" ) cd( "Properties/NO_NAME_0" ) create( "user", "Property" ) cd( "Property/user" ) cmo.setValue( _db_usr ) cd( _datasource_cd_cmo ) create( "myJdbcDataSourceParams", "JDBCDataSourceParams" ) cd( "JDBCDataSourceParams/NO_NAME_0" ) set( "JNDIName", java.lang.String( _db_ds_jndi ) ) set( "GlobalTransactionsProtocol", _db_glob_tx_prot ) cd( _datasource_cd_cmo ) create( "myJdbcConnectionPoolParams", "JDBCConnectionPoolParams" ) cd( "JDBCConnectionPoolParams/NO_NAME_0" ) set( "TestTableName", _db_sql ) set( "LoginDelaySeconds", 1 ) cd( "/" ) assign( "JDBCSystemResource", _db_ds_name, "Target", "AdminServer" ) print "---- Datasource '" + _db_ds_name + "' mit JNDI-Namen '" + _db_ds_jndi + "' erstellt." loadProperties( "WLST12-Domain-DataSource.properties" ) readTemplate( _WL_START_TEMPL ) cd( "Servers/AdminServer" ) set( "ListenAddress", "" ) set( "ListenPort", int( _WL_ADMIN_PORT ) ) create( "AdminServer", "SSL" ) cd( "SSL/AdminServer" ) set( "Enabled", "True" ) set( "ListenPort", 7002 ) cd( "/" ) cd( "Security/base_domain/User/" + _WL_ADMIN_USER ) cmo.setPassword( _WL_ADMIN_PASSWORD ) print "---- AdminServer mit Port " + _WL_ADMIN_PORT + ", SSL-Port 7002 und Admin-User '" + _WL_ADMIN_USER + "' angelegt." _createDatasource( _DB_DS_NAME, _DB_DS_JNDI, _DB_DRV, _DB_URL, _DB_USR, _DB_PWD, _DB_SQL, _DB_GLOB_TX_PROT ) cd( "/" ) setOption( "OverwriteDomain", "true" ) _domain_dir = _WL_BASIS_DIR + "/user_projects/domains/" + _WL_DOMAIN_NAME writeDomain( _domain_dir ) print "---- Fertig: Domain '" + _WL_DOMAIN_NAME + "' im Verzeichnis '" + _domain_dir + "' angelegt." closeTemplate() exit()
Infos zu WLST ("WebLogic Scripting Tool") finden Sie unter: Silent-Konfiguration mit WLST.
Erstellen Sie im MeinDockerWebLogic-Projektverzeichnis folgende Batchdatei (alles in einer Zeile),
damit für Testzwecke einfach deployt werden kann:
deploy-mit-curl.bat
curl -v --user weblogic:weblogic0 -H X-Requested-By:TestForRest -H Accept:application/json -H Content-Type:multipart/form-data -F "model={ name: 'MeinDockerWebLogic', targets: [ 'AdminServer' ] }" -F "deployment=@target/MeinDockerWebLogic.war" -X POST http://localhost:17001/management/wls/latest/deployments/application
Infos hierzu finden Sie unter: Deploying remotely with WebLogic REST (Buttso) und REST Reference for WebLogic, POST Method.
Die Verzeichnisstruktur sieht jetzt so aus:
tree /F
[\MeinWorkspace\MeinDockerMachine] '- docker-machine-start.bat [\MeinWorkspace\MeinDockerWebLogic] |- [dockerDirectory1] | |- Dockerfile | |- jdk-8u74-linux-x64.rpm | '- wls1213_dev_update2.zip |- [dockerDirectory2] | |- Dockerfile | |- WLST12-Domain-DataSource.properties | '- WLST12-Domain-DataSource.py |- [src] | '- [main] | '- [webapp] | |- [WEB-INF] | | '- web.xml | '- index.jsp |- [target] | |- MeinDockerWebLogic.war | '- ... |- deploy-mit-curl.bat '- pom.xml
Wechseln Sie ins MeinDockerWebLogic-Projektverzeichnis und starten Sie Docker Machine mit der oben erstellten Batchdatei:
cd \MeinWorkspace\MeinDockerWebLogic
..\MeinDockerMachine\docker-machine-start.bat
Erzeugen Sie das WebLogic-Basis-Image "weblogic-dev-jdk8-urandom:12.1.3" (noch ohne Domain):
docker build --force-rm=true --no-cache=true --rm=true -t weblogic-dev-jdk8-urandom:12.1.3 dockerDirectory1
docker images
Der Aufruf kann mehrere Minuten dauern. Zuletzt erscheint "Successfully built ..." und das neue Docker-Image "weblogic-dev-jdk8-urandom:12.1.3" wird aufgelistet.
Erzeugen Sie das WebLogic-Image "meinweblogicimage" (inklusive Domain und DataSource):
docker build -t meinweblogicimage dockerDirectory2
docker images
Es wird wieder "Successfully built ..." gemeldet und das neue Docker-Image "meinweblogicimage" wird aufgelistet.
Sie können einen WebLogic-Docker-Container mit dem neuen WebLogic-Docker-Image auf dreierlei Arten starten:
Falls Sie wie oben beschrieben eine MySQL-Datenbank eingerichtet haben, und der Docker-Container dazu installiert ist, aber noch nicht gestartet wurde, starten Sie ihn per "docker start ..."-Batchdatei. Anschließend starten Sie den WebLogic mit einem --link-Verweis darauf:
docker ps -a
..\MeinDockerMySql\meine-mysql-db-start.bat
docker run -it -p 17001:8001 --link=meine-mysql-db:mysql-db --cidfile=mein-weblogic.cid meinweblogicimage
Falls Sie das Docker-Image zur MySQL-Datenbank eingerichtet haben, aber von diesem Image noch keinen Docker-Container installiert haben, starten Sie die DB per "docker run ..."-Kommando. Anschließend starten Sie den WebLogic mit einem --link-Verweis darauf:
docker ps -a
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=mysqlpwd --cidfile=meine-mysql-db.cid --name meine-mysql-db mysql:5.7
docker run -it -p 17001:8001 --link=meine-mysql-db:mysql-db --cidfile=mein-weblogic.cid meinweblogicimage
Falls Sie keine MySQL-Datenbank eingerichtet haben, starten Sie WebLogic ohne --link-Verweis:
docker run -it -p 17001:8001 --cidfile=mein-weblogic.cid meinweblogicimage
In diesem Fall erhalten Sie folgende Fehlermeldung, die Sie ignorieren können:
Failed to initialize the application "MeinMySqlDataSourceName" ... Communications link failure
Sie erhalten u.a.:
... starting weblogic with Java version: java version "1.8.0_74" ... ... <Version: WebLogic Server 12.1.3.0.0 ...> ... ... is now listening on 0:0:0:0:0:0:0:1:8001 for protocols iiop, t3, ldap, snmp, http.> ... ... is now listening on 127.0.0.1:8001 for protocols iiop, t3, ldap, snmp, http.> ... ... <Started the WebLogic Server Administration Server "AdminServer" for domain "MeineDomain" running in development mode.> ... ... <Server state changed to RUNNING.>
Damit Sie den WebLogic bequem starten und stoppen können, erstellen Sie folgendermaßen Batchdateien:
set /P _WEBLOGIC_CID=<mein-weblogic.cid
@echo docker start %_WEBLOGIC_CID% > mein-weblogic-start.bat
@echo docker stop %_WEBLOGIC_CID% > mein-weblogic-stop.bat
del mein-weblogic.cid
Rufen Sie die WebLogic-Console auf und melden Sie sich mit weblogic/weblogic0 an:
start http://localhost:17001/console
Falls dieser Aufruf sehr lange dauert: Dann hat die Ersetzung von "securerandom.source=file:/dev/random" in dockerDirectory1\Dockerfile nicht funktioniert.
Aktivieren Sie die WebLogic-RESTful-Management-Services, indem Sie in der WebLogic-Console Folgendes anklicken:
im "Domainstruktur"-Fenster oben links auf den Domain-Namen klicken | in der Mitte auf: Konfiguration | direkt darunter auf: Allgemein | ganz unten auf: Erweitert |
fast ganz unten auf: RESTful Management-Services aktivieren (= Enable RESTful Management Services) | Speichern.
Je nach Installationsart müssen Sie eventuell vorher ganz oben links auf "Sperren und bearbeiten" klicken.
Die WebLogic-Console meldet:
"Alle Änderungen wurden aktiviert. Allerdings ist ein Neustart für 1 Element(e) erforderlich, damit die Änderungen wirksam werden.".
Beenden Sie den WebLogic-Docker-Container mit Strg+C und starten Sie ihn neu mit:
mein-weblogic-start.bat
Für Applikations-Images, die Weitergabe von Anwendungsartefakten (z.B. WAR) und das Deployment gibt es verschiedene Verfahren.
Weiter oben in den Tomcat-Beispielen
Tomcat,
spotify und
rhuss
wurden "merged Images" verwendet. Dabei ist das Anwendungsartefakt ein Bestandteil des erzeugten Docker-Images.
Diese Variante wird häufig mit "Fat-Jars" für "Microservices" eingesetzt.
Alternativ kann man reine "Daten-Container" anlegen, welche die Anwendungsartefakte enthalten,
und die von den Applikationsserver-Containern referenziert werden.
Während der Entwicklung kann es praktisch sein, die WAR-Datei direkt in den Applikationsserver im Applikationsserver-Container
zu deployen. Dabei werden gerne Applikationsserver-spezifische Techniken eingesetzt.
Für dieses Beispiel soll der Einfachheit halber das Deployment per RESTful-Management-Service erfolgen. Deployen Sie die WAR-Datei MeinDockerWebLogic.war mit der Batchdatei deploy-mit-curl.bat, warten Sie einen Moment, und rufen Sie die Webseite der Webanwendung auf:
deploy-mit-curl.bat
start http://localhost:17001/MeinDockerWebLogic
--> Sie erhalten die gewünschte "Hello World"-Webseite:
Hello World!
Das curl-Deploy-Kommando hat returniert:
... * Connected to localhost (127.0.0.1) port 17001 (#0) ... > POST /management/wls/latest/deployments/application HTTP/1.1 ... < Location: http://localhost:17001/management/wls/latest/deployments/application/id/MeinDockerWebLogic ... { "messages": [{ "message": "Deployed the application 'MeinDockerWebLogic'.", "severity": "SUCCESS" ... "status": "completed", ... "deploymentName": "MeinDockerWebLogic", "operation": "deploy", ... }
Wenn Sie bei laufendem MySQL-Container den WebLogic-Container stoppen und mit folgender Kommandozeile neu starten:
mein-weblogic-stop.bat
docker run -it --rm -p 17001:8001 --link=meine-mysql-db:mysql-db meinweblogicimage /bin/bash
Dann können Sie sich ansehen, was die link-Option bewirkt. Sehen Sie sich beispielsweise den Inhalt der /etc/hosts und einiger Umgebungsvariablen an:
cat /etc/hosts
172.17.0.2 mysql-db ... meine-mysql-db
env | grep DB_
DB_PORT_3306_TCP=tcp://172.17.0.2:3306 DB_PORT_3306_TCP_ADDR=172.17.0.2 DB_PORT_3306_TCP_PORT=3306 DB_PORT_3306_TCP_PROTO=tcp
Sehen Sie sich für ein tieferes Verständnis an: Docker entschlüsselt: Netzwerk (Peter Roßbach).
Der Java EE Application Server Oracle WebLogic 12.2.1 ist zertifiziert für den Betrieb im Docker-Container. Falls Sie WebLogic 12.2.1 in einem Docker-Container betreiben wollen, sehen Sie sich an: Oracle WebLogic Server 12.2.1 on Docker, docker-images / OracleWebLogic und WebLogic 12.2.1 on Docker (Andreas Koop).
Für eine Installation unter Ubuntu-Linux führen Sie folgende Schritte aus:
Voraussetzung ist eine aktuelle Ubuntu-Version und ein installiertes Docker. Folgende Kommandos müssen fehlerfrei funktionieren:
sudo docker version
sudo docker images
sudo docker ps -a
Oracle bietet zwei verschiedene WebLogic-Installationsdateien an:
Für Entwickler genügt normalerweise die Developer-Version, es sei denn, Sie wollen die RESTful Management Services benutzen. Im Folgenden werden beide Installationsarten beschrieben.
Downloaden Sie in Ihr ~/Downloads-Verzeichnis von http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html als WebLogic-Installationsdatei:
Führen Sie im Ubuntu-Terminal aus:
cd ~/Downloads
wget --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u92-b14/server-jre-8u92-linux-x64.tar.gz
git clone https://github.com/oracle/docker-images
mkdir ~/MeinWorkspace/MeinDockerWebLogic1221
cd ~/MeinWorkspace/MeinDockerWebLogic1221
mv ~/Downloads/docker-images/OracleWebLogic .
mv ~/Downloads/docker-images/OracleJDK .
rm -r ~/Downloads/docker-images
cd OracleJDK/java-8
mv ~/Downloads/server-jre-8u92-linux-x64.tar.gz .
sudo sh build.sh
cd ../../OracleWebLogic/dockerfiles
mv ~/Downloads/fmw_12.2.1.0.0_wls_quick_Disk1_1of1.zip 12.2.1/
sudo ./buildDockerImage.sh -v 12.2.1 -d -s
mv ~/Downloads/fmw_12.2.1.0.0_wls_Disk1_1of1.zip 12.2.1/
sudo ./buildDockerImage.sh -v 12.2.1 -g -s
sudo docker images
cd ../samples/1221-domain
sed -i "s|weblogic:12.2.1-developer|weblogic:12.2.1-generic|" Dockerfile
sudo docker build -t 1221-domain --build-arg ADMIN_PASSWORD=weblogic0 .
sudo docker run -d -p 8001:8001 --name 1221-domain 1221-domain
sudo docker images
sudo docker ps -a
Der WebLogic mit installierter Beispiel-Domain läuft jetzt. Kontrollieren Sie das über die WebLogic-Admin-Konsole (weblogic / weblogic0):
Für ein erstes Test-Deployment einer Webanwendung können Sie entweder ein kleines Webprojekt aufsetzen, beispielsweise wie beschrieben unter MvnWebApp, oder Sie downloaden das fertige Ergebnis:
cd ~/Downloads
wget http://www.torsten-horn.de/proj/MvnWebApp.zip
unzip MvnWebApp.zip
Developer-Version:
Ermitteln Sie die WebLogic-Container-ID, ersetzen Sie damit im folgenden Kommando <CONTAINER-ID>, und kopieren Sie die WAR-Datei in den Docker-Container:
sudo docker ps -a
sudo docker cp ~/Downloads/MvnWebApp/target/MvnWebApp.war <CONTAINER-ID>:/u01/oracle/user_projects/domains/base_domain/
Deployen Sie die Webanwendung über die WebLogic-Admin-Konsole über "Lock & Edit | Deployments | Install | ..."
Sie können wahlweise wie gerade für die Developer-Version beschrieben deployen, oder alternativ die WebLogic RESTful Management Services verwenden, mit folgendem curl-Kommando (beim curl-Kommando alles in einer Zeile):
cd ~/Downloads/MvnWebApp
curl -v -u weblogic:weblogic0 -H X-Requested-By:TestForRest -H Accept:application/json -H Content-Type:multipart/form-data -F "model={ name: 'MvnWebApp', targets: [ 'AdminServer' ] }" -F "deployment=@target/MvnWebApp.war" -X POST http://localhost:8001/management/wls/latest/deployments/application
Testen Sie weitere REST-Kommandos, beispielsweise:
curl -i -u weblogic:weblogic0 http://localhost:8001/management/wls/latest
curl -i -u weblogic:weblogic0 http://localhost:8001/management/wls/latest/servers
curl -i -u weblogic:weblogic0 http://localhost:8001/management/wls/latest/deployments
Falls Sie Probleme mit den WebLogic-REST-Services haben, sehen Sie sich an: Probleme mit WebLogic RESTful Management Services.
Anschließend können Sie die Webanwendung aufrufen:
http://localhost:8001/MvnWebApp
Sie erhalten:
Hello World!
Falls Sie bei der Verwendung der WebLogic RESTful Management Services eine der folgenden Fehlermeldungen erhalten:
Failed to receive SOCKS4 connect request ack
Internal Server Error
REST encountered the following error: org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class weblogic.management.rest.wls.model.LegacyRestCollectionResponseBody, genericType=org.glassfish.admin.rest.model.RestCollectionResponseBody<weblogic.management.rest.wls.model.Deployment>
Dann versuchen Sie wahrscheinlich die WebLogic RESTful Management Services in der Developer-Version zu verwenden. Sie benötigen aber hierfür die Generic-Version.
Atlassian JIRA
ist eine kommerzielle webbasierte Anwendung zur Fehlerverwaltung, Problembehandlung und zu operativem Projektmanagement.
Atlassian Confluence
ist eine kommerzielle Wiki-Software, die als Enterprise Wiki hauptsächlich für die Kommunikation und den Wissensaustausch
in Unternehmen und Organisationen verwendet wird.
Das folgende Beispiel realisiert Folgendes (im Beispiel unter Windows):
Führen Sie hierzu folgende Schritte aus (beachten Sie die Atlassian-Lizenzbedingungen und beachten Sie, dass für eine produktiv verwendete Installation weitere Schritte benötigt werden):
Sie benötigen einen ID-Account bei Atlassian. Für eine begrenzte Zeit können Sie eine kostenlose Testphase nutzen.
VirtualBox und Docker Toolbox müssen installiert sein.
Stoppen Sie die VirtualBox-Docker-VM, falls sie läuft:
docker-machine ls
docker-machine stop docker-vm
Starten Sie das VirtualBox-GUI:
"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe"
Klicken Sie links auf "docker-vm", oben auf "Ändern", dann auf "System" und "Hauptplatine", und stellen Sie bei "Haupspeicher" den gewünschten Wert ein, für JIRA und Confluence mindestens 4096 MByte.
Starten Sie die Docker Machine mit der oben erzeugten Batchdatei:
\MeinWorkspace\MeinDockerMachine\docker-machine-start.bat
Suchen Sie zwei freie Ports (aber besser nicht 8080 und 8090, weil diese Ports von anderen Anwendungen belegt werden), und richten Sie hierfür Port Forwarding in der Docker-VM ein:
netstat -an | find ":28080"
netstat -an | find ":28090"
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "Jira-28080,tcp,127.0.0.1,28080,,28080"
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "Cnfl-28090,tcp,127.0.0.1,28090,,28090"
Sie finden auf Docker Hub und GitHub viele verschiedene Dockerfiles und Docker-Images für Atlassian JIRA und Confluence. Im Folgenden werden die cptactionhank-Docker-Images verwendet, siehe cptactionhank/atlassian-jira und cptactionhank/atlassian-confluence.
Downloaden Sie die beiden cptactionhank-Docker-Images:
docker pull cptactionhank/atlassian-jira
docker pull cptactionhank/atlassian-confluence
docker images
Erzeugen Sie die beiden Docker-Container und legen Sie Batchdateien zum bequemen Start und Stopp an:
docker run --detach --publish 28080:8080 --cidfile=mein-jira.cid cptactionhank/atlassian-jira:latest
set /P _JIRA_CID=<mein-jira.cid
@echo docker stop %_JIRA_CID% > mein-jira-stop.bat
@echo docker start %_JIRA_CID% > mein-jira-start.bat
@echo start http://localhost:28080 >> mein-jira-start.bat
del mein-jira.cid
docker ps
docker run --detach --publish 28090:8090 --cidfile=mein-confluence.cid cptactionhank/atlassian-confluence:latest
set /P _CONFLUENCE_CID=<mein-confluence.cid
@echo docker stop %_CONFLUENCE_CID% > mein-confluence-stop.bat
@echo docker start %_CONFLUENCE_CID% > mein-confluence-start.bat
@echo start http://localhost:28090 >> mein-confluence-start.bat
docker ps
Stoppen und starten Sie den JIRA-Docker-Container und konfigurieren Sie JIRA über die JIRA-Applikationsseite (der Start von JIRA dauert minutenlang, klicken Sie nach einer Wartezeit erneut auf den JIRA-Link):
mein-jira-stop.bat
mein-jira-start.bat
Für Softwareentwickler ist meistens die Installationsoption "JIRA for software development" (inkl. JIRA Agile) am interessantesten.
Stoppen und starten Sie den Confluence-Docker-Container und konfigurieren Sie Confluence über die Confluence-Applikationsseite (der Start von Confluence dauert minutenlang, klicken Sie nach einer Wartezeit erneut auf den Confluence-Link):
mein-confluence-stop.bat
mein-confluence-start.bat
Für einen ersten einfachen Test genügt die "Trial Installation" ohne externe Datenbank (mit embedded H2 Database). In diesem Fall können Sie diesen Absatz überspringen und mit dem nächsten Punkt ("Configure User Management") fortfahren.
Für einen ernsthaften Betrieb müssen Sie "Production Installation" wählen und eine externe Datenbank verwenden.
Beachten Sie hierzu die Hinweise unter
Database Configuration.
Im Folgenden soll die oben installierte MySQL-Datenbank verwendet werden.
Starten Sie die MySQL-DB. Richten Sie darin eine MySQL-Database mit dem Namen "confluence" ein,
entweder mit dem Kommando "CREATE DATABASE confluence;"
oder mit einem DB-Tool, beispielsweise mit SQuirreL.
Richten Sie auch einen Benutzer für die confluence-Database ein.
Confluence benötigt einen zur gewählten DB passenden JDBC-Treiber, für MySQL ist dies
entweder "mysql-connector-java-5.1.36.jar"
oder "mysql-connector-java-5.1.36-bin.jar".
Ersteren können Sie aus dem Maven-Repository
http://central.maven.org/maven2/mysql/mysql-connector-java
downloaden.
Den anderen erhalten Sie, wenn Sie von
http://dev.mysql.com/downloads/connector/j/
"mysql-connector-java-5.1.36.zip" downloaden und entzippen.
Diesen JDBC-Treiber müssen Sie in den Confluence-Docker-Container in das Tomcat-WEB-INF/lib-Verzeichnis kopieren.
Laden Sie die ID des Confluence-Docker-Containers in die Environmentvariable _CONFLUENCE_CID,
ermitteln Sie den Pfad zum Tomcat-WEB-INF/lib-Verzeichnis, kopieren Sie mit "docker cp" den JDBC-Treiber,
und kontrollieren Sie das Ergebnis:
set /P _CONFLUENCE_CID=<mein-confluence.cid
docker exec -it %_CONFLUENCE_CID% bash
find / -name 'WEB-INF'
exit
docker cp mysql-connector-java-5.1.36-bin.jar %_CONFLUENCE_CID%:/opt/atlassian/confluence/confluence/WEB-INF/lib/mysql-connector-java-5.1.36-bin.jar
docker exec -it %_CONFLUENCE_CID% bash
ls /opt/atlassian/confluence/confluence/WEB-INF/lib/mysql*
exit
Stoppen und starten Sie Confluence, damit der JDBC-Treiber registriert wird:
mein-confluence-stop.bat
mein-confluence-start.bat
Ermitteln Sie die IP-Adresse der Docker-VM (beispielsweise 192.168.99.100):
docker-machine ip docker-vm
Setzen Sie die Konfiguration über die Confluence-Applikationsseite fort.
Wählen Sie im Dialog "Choose a Database Configuration" bei "External Database": MySQL.
Wählen Sie im Dialog "Configure Database" die Option "Direct JDBC Connection" und
anschließend (passen Sie die IP-Adresse der Docker-VM an):
Driver Class Name: com.mysql.jdbc.Driver
Database URL: jdbc:mysql://192.168.99.100/confluence?ENGINE=InnoDB&useUnicode=true&characterEncoding=utf8
Ergänzen Sie die Account-Einträge.
Beim Dialog "Configure User Management" wählen Sie "Manage Users and Groups with JIRA" / "Connect to JIRA".
Im Dialog "Connect to JIRA" werden Sie nach zwei URLs gefragt, nämlich von Confluence aus zu JIRA und von JIRA aus zu Confluence.
Achtung: Hier dürfen Sie nicht die von Windows aus verwendeten URLs
http://localhost:28080 und
http://localhost:28090 eintragen,
sondern die URLs innerhalb der Docker-VM.
Ermitteln Sie zuerst die IP-Adresse der Docker-VM:
docker-machine ip docker-vm
Die so ermittelte IP-Adresse ergänzen Sie um die internen in der Docker-VM verwendeten Port-Nummern, in diesem Fall also um 28080 und 28090.
Falls die IP-Adresse beispielsweise 192.168.99.100 lautet, müsste für die beiden angefragten URLs eingetragen werden:
http://192.168.99.100:28080 bei "JIRA Server Location" / "JIRA Base URL" und
http://192.168.99.100:28090 bei "Confluence Base URL".
Ergänzen Sie die Account-Einträge.
Überprüfen Sie die Ergebnisse in Confluence unter: Oben rechts: Administration-Zahnrad-Icon | Allgemeine Konfiguration:
- links unter Administration: Systeminformationen | Databankinformationen,
- links unter Benutzer & Sicherheit: Benutzerverzeichnisse,
- links unter Benutzer & Sicherheit: Whitelist.
Marcel Birkner hat im JavaSPEKTRUM 02/2016 einen Continuous-Integration-Stack vorgestellt, der die wichtigsten üblichen CI-Tools in 10 Docker-Containern installiert, welche durch Docker Compose orchestriert werden und nach der Erstinstallation durch ein einfaches "docker-compose up" gestartet werden. Das Demo-Projekt kann von GitHub heruntergeladen werden.
Siehe hierzu die Erläuterungen und Screenshots unter:
Der Continuous-Integration-Stack besteht im Wesentlichen aus folgenden Komponenten:
Normalerweise wird eine solche Continuous-Integration-Umgebung unter Linux oder Unix installiert, worauf auch die Installationsbeschreibung auf der GitHub-Seite fokussiert. Im Folgenden finden Sie Hinweise, falls Sie den CI-Stack unter Windows testen wollen.
Überprüfen Sie, ob Ihre Docker-Installation ausreichend aktuel ist. Docker Machine wird in mindestens Version 0.3.0 benötigt und Docker Compose in mindestens Version 1.6:
docker-machine version
docker-compose version
Es empfiehlt sich, nicht die Default-Docker-VirtualBox-VM zu verwenden, sondern stattdessen eine separate VirtualBox-VM aufzusetzen, um die Übersicht zu behalten. Diese VM benötigt mindestens 6 GByte RAM:
docker-machine create -d virtualbox --virtualbox-memory "6000" docker-ci-tool-stack-vm
docker-machine stop docker-ci-tool-stack-vm
docker-machine ls
Clonen Sie das CI-Tools-Docker-Projekt von GitHub:
cd \MeinWorkspace
git clone https://github.com/marcelbirkner/docker-ci-tool-stack
cd docker-ci-tool-stack
tree /F
Legen Sie im docker-ci-tool-stack-Verzeichnis drei Batchdateien an: eine für den Start, eine zum Beenden und eine zum Starten der Web-GUIs:
start-docker-ci-tool-stack.bat
cd \MeinWorkspace\docker-ci-tool-stack docker-machine ls docker-machine start docker-ci-tool-stack-vm docker-machine env --shell cmd docker-ci-tool-stack-vm | find "DOCKER_" > docker-machine-env-docker-ci-tool-stack.bat call docker-machine-env-docker-ci-tool-stack.bat docker-compose up
stop-docker-ci-tool-stack.bat
cd \MeinWorkspace\docker-ci-tool-stack call docker-machine-env-docker-ci-tool-stack.bat docker-compose stop docker-machine stop docker-ci-tool-stack-vm del docker-machine-env-docker-ci-tool-stack.bat
start-ci-web-guis.bat
cd \MeinWorkspace\docker-ci-tool-stack call docker-machine-env-docker-ci-tool-stack.bat docker-machine ip docker-ci-tool-stack-vm > _ci_docker_ip.txt set /P _CI_DOCKER_IP=<_ci_docker_ip.txt del _ci_docker_ip.txt start http://%_CI_DOCKER_IP%:18080/ start http://%_CI_DOCKER_IP%:19000/ start http://%_CI_DOCKER_IP%:18081/nexus start http://%_CI_DOCKER_IP%:10080/ start http://%_CI_DOCKER_IP%:4444/grid/console
Starten Sie mit der Start-Batchdatei die VirtualBox-VM, den Docker-Server und die CI-Docker-Container. Achtung: Der erstmalige Aufruf dauert sehr lange, da viele Downloads benötigt werden. Je nach PC und Internetanbindung kann es länger als 30 Minuten dauern:
start-docker-ci-tool-stack.bat
Öffnen Sie ein zweites Kommandozeilenfenster, setzen Sie mit der env-Batchdatei die benötigten Environment-Variablen, und sehen Sie sich das Installations-Ergebnis an:
cd \MeinWorkspace\docker-ci-tool-stack
docker-machine-env-docker-ci-tool-stack.bat
set DOCKER
docker-machine ls
docker images
docker ps -a
Warten Sie, bis alle Docker-Container laufen. Dann starten Sie die fünf Web-GUIs der CI-Tools. Die Accountdaten zum Einloggen finden Sie auf der GitHub-Seite.
start-ci-web-guis.bat
Sehen Sie sich die Erläuterungen und Screenshots an unter den obigen URLs. Sehen Sie sich vor allem die Docker-Compose-Konfiguration in der Datei docker-compose.yml an.
Falls Sie beim "git clone ..."-Aufruf folgende Fehlermeldung erhalten:
Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
Dann überprüfen Sie, ob Ihr "git clone ..."-Aufruf exakt mit dem oben gezeigten übereinstimmt.
Falls Sie beim "docker-compose up"-Aufruf folgende Fehlermeldung erhalten:
ERROR: In file '.\docker-compose.yml' service 'version' doesn't have any configuration options. All top level keys in your docker-compose.yml must map to a dictionary of configuration options.
Dann müssen Sie Docker Compose auf mindestens Version 1.6 upgraden.
Wenn Sie den Ressourcen-Verbrauch der Docker-Container nicht mit Linux- und Docker-Kommandos (z.B. docker stats ...) beobachten wollen, sondern hierfür eine grafische Alternative suchen, sehen Sie sich Google cAdvisor an, siehe google/cadvisor bei Doker Hub und GitHub.
Installieren und starten Sie cAdvisor folgendermaßen:
Starten Sie die Docker Machine mit der oben erzeugten Batchdatei:
\MeinWorkspace\MeinDockerMachine\docker-machine-start.bat
Suchen Sie einen freien Port (aber besser nicht 8080, weil dieser Port von anderen Anwendungen belegt wird), und richten Sie hierfür Port Forwarding in der Docker-VM ein:
netstat -an | find ":58080"
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "cAdv-58080,tcp,127.0.0.1,58080,,58080"
Downloaden Sie das cAdvisor-Docker-Image:
docker pull google/cadvisor
docker images
Starten Sie cAdvisor und erzeugen Sie Batchdateien zum bequemen Start und Stopp:
docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:rw --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=58080:8080 --detach=true --cidfile=cAdvisor.cid --name=cadvisor google/cadvisor
set /P _CADVISOR_CID=<cAdvisor.cid
@echo docker stop %_CADVISOR_CID% > cAdvisor-stop.bat
@echo docker start %_CADVISOR_CID% > cAdvisor-start.bat
@echo @ping -n 2 127.0.0.1 ^>nul >> cAdvisor-start.bat
@echo start http://localhost:58080 >> cAdvisor-start.bat
del cAdvisor.cid
Stoppen und starten Sie cAdvisor und sehen Sie sich die cAdvisor-Webseite an:
cAdvisor-stop.bat
cAdvisor-start.bat
Starten Sie weitere Docker-Container, damit cAdvisor etwas zu monitoren hat. Sie erhalten Tachos, Listen und diverse Kurvendiagramme:
Fertig eingerichtete und angepasste Docker-Images werden üblicherweise nicht nur im lokalen Repository auf dem lokalen PC gespeichert, sondern auch in eine Registry auf einem Server hochgeladen. Dann stehen sie für die Wiederverwendung zur Verfügung, beispielsweise für späteren erneuten Gebrauch, für weitere Testumgebungen oder für andere Benutzer.
Falls Sie Ihre Docker-Images nicht in eine öffentliche Docker-Registry (wie z.B. Docker Hub Registry) hochladen wollen, können Sie eine eigene Registry einrichten ("Private Registry"). Dies wird häufig in Firmen-Intranets genutzt.
Wechseln Sie zu dem Server-PC, auf dem die Docker-Registry installiert werden soll (testweise können Sie auch auf Ihrer Workstation bleiben).
Bereiten Sie die Installation einer eigenen Registry vor. Falls Sie unter Windows installieren wollen: Testen Sie, ob der gewünschte Port frei ist, richten Sie Port Forwarding ein und starten Sie Docker Machine:
netstat -an | find ":5000"
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "Reg-5000,tcp,127.0.0.1,5000,,5000"
\MeinWorkspace\MeinDockerMachine\docker-machine-start.bat
Es gibt viele Angebote für Dockerfiles und fertig eingerichtete Docker-Registry-Images, siehe "Registry" in der Docker Hub Registry und "Docker Registry" auf GitHub. Im Folgenden wird die neue Version 2 vom registry-Image aus dem "official Repo" verwendet, siehe registry und Deploying a Registry Server. Downloaden Sie das Docker-Registry-Image:
docker pull registry:2
docker images
Starten Sie einen Docker-Container mit dem Docker-Registry-Image:
docker run -p 5000:5000 --name registry-server registry:2
docker ps -a
Wechseln Sie zu dem Workstation-PC, auf dem sich das hochzuladende Docker-Image befindet
(testweise kann dies derselbe PC wie der Server-PC der neuen Docker-Registry sein).
Der Server-PC mit der Docker-Registry wird im Folgenden mit "<registry-host>" referenziert
(falls beides auf demselben PC läuft, ersetzen Sie <registry-host> durch localhost).
Taggen Sie das fürs Hochladen ausgewählte Image mit der Registry-Host-Adresse inklusive der Portnummer, führen Sie das "docker push"-Kommando zum Hochladen aus, und lassen Sie sich das gespeicherte Image anzeigen (ersetzen Sie alle "<...>"-Ausdrücke):
docker images
docker tag <image-name>:<image-tag> <registry-host>:5000/<image-name>:<image-tag>
docker images
docker push <registry-host>:5000/<image-name>:<image-tag>
curl http://<registry-host>:5000/v2/<image-name>/tags/list
Um die Kommandos konkreter zeigen zu können, soll als Beispiel das weiter oben erstellte Docker-Image meintomcatimage in der neuen Docker-Registry gespeichert werden, und es soll von localhost als Registry-Server ausgegangen werden:
docker images
docker tag meintomcatimage:latest localhost:5000/meintomcatimage:latest
docker images
docker push localhost:5000/meintomcatimage:latest
curl http://localhost:5000/v2/meintomcatimage/tags/list
Um zu zeigen, dass das Image abgerufen werden kann, müssen Sie entweder auf einen anderen PC wechseln oder auf Ihrem Workstation-PC zuerst das Image im lokalen Repository löschen, um es anschließend herunter zu laden:
docker images
docker rmi meintomcatimage
docker rmi localhost:5000/meintomcatimage
docker images
docker pull localhost:5000/meintomcatimage
docker images
Sehen Sie sich Making Docker's official registry image production ready an, um eine Authentifizierung einzurichten.
Sehen Sie sich z.B. unter Setting up a private docker repository (Nick Randell) an, wie Sie die eigene Docker-Registry auf einem Linux-Server als automatisch startenden Systemd-Service einrichten.
Sie können auch Anwendungen mit grafischer Benutzeroberfläche im Docker-Container betreiben. Um das GUI vom Host aus sehen zu können, gibt es verschiedene Verfahren. Im Folgenden wird ein sehr einfaches Verfahren vorgestellt, welches noVNC verwendet.
Starten Sie Docker Machine mit der oben erstellten docker-machine-start.bat-Batchdatei, prüfen Sie, ob der gewünschte Port noch frei ist, und richten Sie Port Forwarding ein:
\MeinWorkspace\MeinDockerMachine\docker-machine-start.bat
netstat -an | find ":6080"
"C:\Program Files\Oracle\VirtualBox\VBoxManage.exe" controlvm docker-vm natpf1 "Vnc-6080,tcp,127.0.0.1,6080,,6080"
Downloaden Sie das Docker-Image dorowu/ubuntu-desktop-lxde-vnc (und sehen Sie sich das Dockerfile und das Git-Repo fcwu/docker-ubuntu-vnc-desktop an):
docker pull dorowu/ubuntu-desktop-lxde-vnc
docker images
Starten Sie einen Docker-Container mit dem Image:
docker run -i -t -p 6080:6080 --cidfile=mein-ubuntu-desktop.cid dorowu/ubuntu-desktop-lxde-vnc
Warten Sie bis "INFO success: novnc entered RUNNING state" erscheint.
Öffnen Sie im Windows-Host folgende URL:
Sie erhalten einen Ubuntu-14.04-Desktop mit LXDE-Oberfläche ("Lightweight X11 Desktop Environment"). Einige wenige Programme wie beispielsweise LibreOffice, Firefox, PCManFM, Leafpad und LXTerminal sind vorinstalliert. Beliebige weitere können nachinstalliert werden.
Damit Sie den Ubuntu-Desktop bequem starten und stoppen können, erstellen Sie folgendermaßen Batchdateien:
set /P _UBUNTU_DESKTOP_CID=<mein-ubuntu-desktop.cid
@echo docker start %_UBUNTU_DESKTOP_CID% > mein-ubuntu-desktop-start.bat
@echo docker stop %_UBUNTU_DESKTOP_CID% > mein-ubuntu-desktop-stop.bat
del mein-ubuntu-desktop.cid
Für den nächsten Start genügt dann:
\MeinWorkspace\MeinDockerMachine\docker-machine-start.bat
mein-ubuntu-desktop-start.bat
Sehen Sie sich grundsätzliche Infos zu Ubuntu an:
Ubuntu,
Canonical Ubuntu,
ubuntuusers-Wiki.
Erforschen Sie die Linux-Installation. Öffnen Sie ein bash-Terminal (Shell-Fenster / Kommandozeilenfenster, z.B. über unten links Start | Accessories | LXTerminal) und beginnen Sie beispielsweise mit folgenden Kommandos:
whoami
ubuntu
groups
ubuntu adm sudo
id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),27(sudo)
uname -a
Linux ... 4.4.12-boot2docker ... x86_64 GNU/Linux
ls /proc
cat /proc/version
Linux ... 4.4.12-boot2docker ... (Debian 4.9.2-10) ...
cat /etc/issue
Ubuntu 14.04.3 LTS \n \l
Mit folgenden Kommandos erlangen Sie root-Rechte (Passwort: ubuntu) und schalten wieder zurück:
sudo su
...
exit
Als Beispiel wie Programme installiert werden können, soll wget installiert werden:
sudo apt-get install wget
wget --help
Sehen Sie sich an:
Wichtige Linux-Kommandos,
Weitere speziellere Linux-Kommandos,
Besonderheiten der bash und
Weitere Informationen zu Ubuntu.
Alle bisher gezeigten Docker-Beispiele verwenden Docker Toolbox, um unter Windows (bzw. Mac OS X) betrieben werden zu können. Docker Toolbox vereinfacht dies, aber ist nicht zwingend notwendig. Das folgende Beispiel zeigt, wie ohne Verwendung von Docker Toolbox mit Vagrant eine Linux-VM eingerichtet wird, in der Docker installiert wird, um beispielsweise Tomcat im Docker-Container verwenden zu können.
Die Konfiguration der Docker-Container über Vagrant statt Docker Toolbox hat zwei Vorteile:
Vergleichen Sie die rechts gezeigte Grafik zur oben für Docker Toolbox gezeigte Grafik: Ein auffälliger Unterschied ist, dass der Docker-Client nicht mehr von Windows aus verwendet wird, sondern vom Linux-Layer aus (z.B. per SSH).
Das Beispiel geht davon aus, dass als Host-Betriebssystem Windows verwendet wird. Es ist aber leicht an Mac OS X anpassbar. Es wurde getestet mit Windows 10 Pro (64 Bit), Vagrant 1.7.4, VirtualBox 5.0.16, Ubuntu 14.04.3 LTS und Tomcat 8.
Führen Sie folgende Schritte durch:
Ein aktuelles Java SE JDK, Maven und ein Git-Client müssen installiert sein, letzteres damit ssh.exe zur Verfügung steht. Stellen Sie sicher, dass nicht nur der cmd-Pfad zu git.exe, sondern auch der bin-Pfad zu ssh.exe in der PATH-Environmentvariable eingetragen ist.
Installieren Sie VirtualBox und Vagrant, wie in den ersten Schritten unter Hello-World-Webanwendung mit Vagrant, VirtualBox, Ubuntu und Tomcat erläutert ist.
Testen Sie, ob der benötigte Port noch nicht anderweitig belegt ist:
netstat -an | find ":18080"
Auch in diesem Beispiel soll wieder Tomcat mit einer Webanwendung im Docker-Container installiert werden. Sie können eine beliebige Webanwendungs-WAR-Datei deployen. Für dieses simple Beispiel wechseln Sie in ein beliebiges Projekte-Workspace-Verzeichnis (z.B. \MeinWorkspace) und erzeugen folgendermaßen mit Maven eine "Hello World"-WAR:
cd \MeinWorkspace
mvn archetype:generate -DinteractiveMode=false -DarchetypeArtifactId=maven-archetype-webapp -DgroupId=de.meinefirma.meinprojekt -DartifactId=MeinDockerMitVagrant
cd MeinDockerMitVagrant
mvn package
md vagrantDirectory\dockerDirectory
Erzeugen Sie im MeinDockerMitVagrant-Projektverzeichnis folgende Batchdatei: run.bat
cd vagrantDirectory vagrant up cd ..
Erzeugen Sie im vagrantDirectory-Unterverzeichnis folgende Vagrant-Datei: Vagrantfile
Vagrant.configure("2") do |config| config.vm.box = "ubuntu/trusty64" config.vm.synced_folder "../tomcat-logs", "/tomcat-logs", create: true config.vm.synced_folder "../tomcat-webapps", "/tomcat-webapps", create: true config.vm.network "forwarded_port", guest: 8080, host: 18080 config.vm.provision "docker" do |d| d.build_image "/vagrant/dockerDirectory", args: "-t meindockermitvagrantimage" d.run "meindockermitvagrantimage", args: "-p 8080:8080 -v /tomcat-webapps:/usr/local/tomcat/webapps -v /tomcat-logs:/usr/local/tomcat/logs" end end
Sehen Sie sich hierzu die Vagrantfile-Doku, die config.vm-Settings und den Vagrant-Docker-Provisioner an. Weitere Erläuterungen folgen weiter unten.
Erzeugen Sie im vagrantDirectory/dockerDirectory-Unterverzeichnis folgende Docker-Datei: Dockerfile
FROM tomcat:8 CMD ["catalina.sh", "run"]
Eigentlich ist dieses Dockerfile unnötig, weil das tomcat:8-Docker-Image genauso gut direkt verwendet werden könnte. Es wird nur eingesetzt, um zu zeigen, wie ein Dockerfile eingebunden und ausgeführt wird. Doku finden Sie unter: Dockerfile Reference, Doku zum tomcat-Docker-Image und Dockerfile.
Sehen Sie sich die Verzeichnisstruktur an:
tree /F
[\MeinWorkspace\MeinDockerMitVagrant] |- [src] | '- [main] | '- [webapp] | |- [WEB-INF] | | '- web.xml | '- index.jsp |- [target] | |- MeinDockerMitVagrant.war | '- ... |- [vagrantDirectory] | |- [dockerDirectory] | | '- Dockerfile | '- Vagrantfile |- pom.xml '- run.bat
Führen Sie im MeinDockerMitVagrant-Projektverzeichnis aus (der erstmalige Aufruf kann sehr lange dauern):
cd \MeinWorkspace\MeinDockerMitVagrant
run.bat
Achten Sie darauf, dass zwischendurch angezeigt wird:
Bringing machine 'default' up with 'virtualbox' provider... ==> default: Importing base box 'ubuntu/trusty64'... ... ==> default: Forwarding ports... default: 8080 => 18080 (adapter 1) default: 22 => 2222 (adapter 1) ... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant ... ==> default: Mounting shared folders... default: /vagrant => D:/MeinWorkspace/MeinDockerMitVagrant/vagrantDirectory default: /tomcat-logs => D:/MeinWorkspace/MeinDockerMitVagrant/tomcat-logs default: /tomcat-webapps => D:/MeinWorkspace/MeinDockerMitVagrant/tomcat-webapps ==> default: Running provisioner: docker... default: Installing Docker (latest) onto machine... ==> default: Building Docker images... ==> default: -- Path: /vagrant/dockerDirectory ... ==> default: Sending build context to Docker daemon 2.048 kB ... ==> default: Step 1 : FROM tomcat:8 ... ==> default: Step 2 : CMD catalina.sh run ... ==> default: Successfully built ... ==> default: Starting Docker containers... ==> default: -- Container: meindockermitvagrantimage
Führen Sie aus (warten Sie nach dem ersten Kommando etwas, bis das Deployment fertig ist):
copy /B target\MeinDockerMitVagrant.war tomcat-webapps\MeinDockerMitVagrant.war
type tomcat-logs\catalina*.log
start http://localhost:18080/MeinDockerMitVagrant
--> Sie erhalten die gewünschte "Hello World"-Webseite:
Hello World!
Sehen Sie sich die resultierenden Verzeichnisstruktur-Ausschnitte in den drei Schichten und die "shared Folders" an:
Windows-Host | Vagrant-VirtualBox-VM- Linux-Layer |
Docker-Container | ||
[\MeinWorkspace\MeinDockerMitVagrant] |- [src] | '- [main] | '- [webapp] | |- [WEB-INF] | | '- web.xml | '- index.jsp |- [target] | |- MeinDockerMitVagrant.war | '- ... |- [tomcat-logs] | |- catalina...log | '- ... |- [tomcat-webapps] | |- MeinDockerMitVagrant.war | '- ... |- [vagrantDirectory] | |- [.vagrant] | | '- ... | |- [dockerDirectory] | | '- Dockerfile | '- Vagrantfile |- pom.xml '- run.bat |
[/tomcat-logs] |- catalina...log '- ... [/tomcat-webapps] |- MeinDockerMitVagrant.war '- ... [/vagrant] |- [.vagrant] | '- ... |- [dockerDirectory] | '- Dockerfile '- Vagrantfile |
[/usr/local/tomcat/logs] |- catalina...log '- ... [/usr/local/tomcat/webapps] |- MeinDockerMitVagrant.war '- ... |
Sehen Sie sich an, wie im Vagrantfile die "shared Folders" und die Port-Weiterleitung definiert wurde.
Diese drei Zeilen definieren, wie Verzeichnisse und Ports vom "Vagrant-VirtualBox-VM-Linux-Layer" mit dem Windows-Host geteilt werden:
... config.vm.synced_folder "../tomcat-logs", "/tomcat-logs", create: true config.vm.synced_folder "../tomcat-webapps", "/tomcat-webapps", create: true config.vm.network "forwarded_port", guest: 8080, host: 18080 ...
Und diese Zeile definiert, wie Verzeichnisse und Ports vom Docker-Container mit dem "Vagrant-VirtualBox-VM-Linux-Layer" geteilt werden:
... d.run "meindockermitvagrantimage", args: "-p 8080:8080 -v /tomcat-webapps:/usr/local/tomcat/webapps -v /tomcat-logs:/usr/local/tomcat/logs" ...
Loggen Sie sich per SSH in den Vagrant-VirtualBox-VM-Linux-Layer ein, sehen Sie sich Dateien an und führen Sie
docker-Kommandos aus:
cd vagrantDirectory zum Wechseln in das Vagrant-Verzeichnis, um SSH starten zu können.
vagrant ssh für SSH-Zugang zum Vagrant-Linux-Layer.
ls -al /tomcat-logs "Shared Folder" für Tomcat-Logdateien.
ls -al /tomcat-webapps "Shared Folder" für Tomcat-Webapplikationen.
ls -al /vagrant "Shared Folder" für Vagrant.
docker info zur Anzeige von Docker-relevanten Systeminformationen.
docker images zur Anzeige der Docker-Images im lokalen Repository.
docker ps -a zur Anzeige der Docker-Container.
exit zum Beenden der SSH-Session.
dir "C:\Users\%USERNAME%\.vagrant.d\boxes" zur Anzeige der "Vagrant-Boxen".
dir "C:\Users\%USERNAME%\VirtualBox VMs" zur Anzeige der "VirtualBox-VM-Boxen".
vagrant destroy falls Sie die "VirtualBox-VM-Box" komplett löschen wollen.