Docker

+ andere TechDocs
+ Continuous Delivery
+ Red Hat OpenShift
+ Google App Engine
+


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.



Inhalt

  1. Was ist Docker?
    Umfeld und Einsatzgebiet, Virtualisierungslösungen und Alternativen, Prinzip von Docker, Vorteile von Docker, Elemente von Docker, Cloud Native Computing Foundation (CNCF), Microservices und Self-contained Systems (SCS), Spring Boot und Spring Cloud mit Netflix OSS, AWS, EC2, ECS, Einsteigerbeispiele und Infos
  2. Docker-Container unter Windows
  3. Docker-Image übertragen und weitergeben
  4. Installation von Docker unter Linux
  5. Installation von Docker und Docker Toolbox unter Windows
  6. Hello-World-Webanwendung mit Docker, Docker Toolbox und Tomcat, Teil 1
  7. Hello-World-Webanwendung mit Docker, Docker Toolbox und Tomcat, Teil 2
  8. Docker-Image mit Maven erzeugen mit dem spotify docker-maven-plugin
  9. Docker mit Maven steuern mit dem rhuss docker-maven-plugin
  10. MySQL-Datenbank im Docker-Container
  11. WebLogic 12.1.3 im Docker-Container unter Windows
  12. WebLogic 12.2.1 im Docker-Container unter Ubuntu-Linux
  13. Atlassian JIRA und Confluence in Docker-Containern
  14. Docker-CI-Stack mit Jenkins, Nexus, GitLab, SonarQube, Selenium Grid
  15. Monitoring mit cAdvisor
  16. Eigene Docker-Registry ("Private Registry")
  17. Ubuntu-Desktop mit grafischer Oberfläche im Docker-Container
  18. Docker mit Vagrant statt mit Docker Toolbox



Was ist Docker?

Umfeld und Einsatzgebiet

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.

Kategorien von Virtualisierungslösungen und Alternativen zu Docker

Es gibt zwei grundsätzliche Kategorien von Virtualisierungslösungen, die sich in der eingesetzten Technik unterscheiden:

Prinzip von Docker

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

Vorteile von Docker sind (teilweise ähnlich wie für VMs):

Wichtige Elemente von Docker

Wichtige Elemente von Docker sind:

Cloud Native Computing Foundation (CNCF)

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:

  1. Der "Cluster Scheduler" (z.B. "Mesos" oder "Docker Swarm") allokiert Ressourcen und steuert die Ausführung der einzelnen Container.
  2. Der "Cluster Orchestrator" (z.B. "Kubernetes" oder "Docker Compose") steuert und überwacht die Ausführung aller Container einer Anwendung inklusive Roll-out, Upgrade, Skalierung und Umgang mit Fehlersituationen.
  3. Das "Microservices Framework" (z.B. "Spring Cloud mit Netflix OSS") bietet eine technische Infrastruktur für Microservices, beispielsweise für Konfiguration, Authentifizierung, Service Discovery, Load Balancing, Skalierbarkeit, Fehlertoleranz, Logging, Metriken etc.

Microservices und Self-contained Systems (SCS)

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).

Spring Boot und Spring Cloud mit Netflix OSS

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).

AWS, EC2, ECS

Amazon bietet Dienste an, die Docker unterstützen:

Einfache Einsteigerbeispiele und weitere Infos

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: Docker - Up and Running (Karl Matthias + Sean P. Kane).



Docker-Container unter Windows

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.



Docker-Image übertragen und weitergeben

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.



Installation von Docker unter Linux

Eine Beschreibung zur Installation von Docker unter Ubuntu-Linux finden Sie unter: Installation von Docker unter Ubuntu.



Installation von Docker und Docker Toolbox unter Windows

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:

  1. 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

  2. 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"

  3. 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

  4. Ü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"

  5. 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".

  6. 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
    


Hello-World-Webanwendung mit Docker, Docker Toolbox und Tomcat, Teil 1

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:

  1. Voraussetzung ist die erfolgreiche Installation von Java, Maven, Git und Docker Toolbox wie oben beschrieben wurde.

  2. Testen Sie, ob der benötigte Port noch nicht anderweitig belegt ist:

    netstat -an | find ":18080"

  3. 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".

  4. 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.

  5. 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

  6. 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

  7. 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/

  8. 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!
    
  9. Sehen Sie sich die Erläuterungen im nächsten Kapitel an.

Kurzes Resümee:



Hello-World-Webanwendung mit Docker, Docker Toolbox und Tomcat, Teil 2

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:

  1. Voraussetzung ist die erfolgreiche Durchführung des vorherigen Beispiels MeinDockerTomcat.

  2. Wechseln Sie in das MeinDockerTomcat-Projektverzeichnis und führen Sie aus:

    cd \MeinWorkspace\MeinDockerTomcat

    md dockerDirectory

    copy /B target\MeinDockerTomcat.war dockerDirectory\MeinDockerTomcat.war

  3. 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.

  4. 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
    
  5. 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!
    
  6. Ö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.

  7. 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

  8. 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:



Docker-Image mit Maven erzeugen mit dem spotify docker-maven-plugin

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:

  1. 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

  2. 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>
    
  3. 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

  4. 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!
    
  5. 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.



Docker mit Maven steuern mit dem rhuss docker-maven-plugin

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):

  1. Voraussetzung ist die erfolgreiche Installation von Java, Maven, Git und Docker Toolbox wie oben beschrieben wurde.

  2. 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

  3. 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-Datenbank im Docker-Container

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.

  1. Erstellen Sie ein Projektverzeichnis für Batchdateien zur MySQL-DB:

    md \MeinWorkspace\MeinDockerMySql

    cd \MeinWorkspace\MeinDockerMySql

  2. Starten Sie Docker Machine mit der oben erstellten Batchdatei:

    ..\MeinDockerMachine\docker-machine-start.bat

  3. 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"

  4. 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

  5. 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

  6. 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

  7. Die Verzeichnisstruktur sieht jetzt so aus:

    [\MeinWorkspace\MeinDockerMachine]
     '- docker-machine-start.bat
    [\MeinWorkspace\MeinDockerMySql]
     |- meine-mysql-db-start.bat
     '- meine-mysql-db-stop.bat
    
  8. 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.

  9. Das folgende Beispiel zeigt, wie die soeben eingerichtete MySQL-DB von einem WebLogic Application Server verwendet werden kann.



WebLogic 12.1.3 im Docker-Container unter Windows

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:

  1. 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.

  2. Testen Sie, ob der benötigte Port noch nicht anderweitig belegt ist:

    netstat -an | find ":17001"

  3. 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"

  4. 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

  5. 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.

  6. 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.

  7. 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"]
    
  8. 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.

  9. 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.

  10. 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.

  11. 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
    
  12. 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.

  13. 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.

  14. Sie können einen WebLogic-Docker-Container mit dem neuen WebLogic-Docker-Image auf dreierlei Arten starten:

  15. 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.>
    
  16. 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

  17. 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.

  18. 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.".

  19. Beenden Sie den WebLogic-Docker-Container mit Strg+C und starten Sie ihn neu mit:

    mein-weblogic-start.bat

  20. 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.

  21. 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!
    
  22. 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",
    ...
    }
    
  23. 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).



WebLogic 12.2.1 im Docker-Container unter Ubuntu-Linux

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:

  1. 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

  2. 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.

  3. Downloaden Sie in Ihr ~/Downloads-Verzeichnis von http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html als WebLogic-Installationsdatei:

  4. 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

    sudo docker images

    cd ../samples/1221-domain

    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

  5. Der WebLogic mit installierter Beispiel-Domain läuft jetzt. Kontrollieren Sie das über die WebLogic-Admin-Konsole (weblogic / weblogic0):

    http://localhost:8001/console

  6. 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

  7. Deployen Sie die WAR-Datei, beispielsweise so:
  8. Anschließend können Sie die Webanwendung aufrufen:

    http://localhost:8001/MvnWebApp

    Sie erhalten:

    Hello World!
    
  9. 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 und Confluence in Docker-Containern

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):

  1. Sie benötigen einen ID-Account bei Atlassian. Für eine begrenzte Zeit können Sie eine kostenlose Testphase nutzen.

  2. VirtualBox und Docker Toolbox müssen installiert sein.

  3. 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.

  4. Starten Sie die Docker Machine mit der oben erzeugten Batchdatei:

    \MeinWorkspace\MeinDockerMachine\docker-machine-start.bat

  5. 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"

  6. 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

  7. 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

  8. 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.

  9. 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

  10. 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.

  11. 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.

  12. Ü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.



Docker-CI-Stack mit Jenkins, Nexus, GitLab, SonarQube, Selenium Grid

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.

  1. Ü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

  2. 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

  3. 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

  4. 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
    
  5. 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

  6. Ö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

  7. 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

  8. 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.

  9. 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.

  10. 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.



Monitoring mit cAdvisor

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:

  1. Starten Sie die Docker Machine mit der oben erzeugten Batchdatei:

    \MeinWorkspace\MeinDockerMachine\docker-machine-start.bat

  2. 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"

  3. Downloaden Sie das cAdvisor-Docker-Image:

    docker pull google/cadvisor

    docker images

  4. 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

  5. Stoppen und starten Sie cAdvisor und sehen Sie sich die cAdvisor-Webseite an:

    cAdvisor-stop.bat

    cAdvisor-start.bat

  6. Starten Sie weitere Docker-Container, damit cAdvisor etwas zu monitoren hat. Sie erhalten Tachos, Listen und diverse Kurvendiagramme:



Eigene Docker-Registry ("Private Registry")

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.

  1. Wechseln Sie zu dem Server-PC, auf dem die Docker-Registry installiert werden soll (testweise können Sie auch auf Ihrer Workstation bleiben).

  2. 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

  3. 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

  4. Starten Sie einen Docker-Container mit dem Docker-Registry-Image:

    docker run -p 5000:5000 --name registry-server registry:2

    docker ps -a

  5. 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).

  6. 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

  7. 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

  8. 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

  9. 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.



Ubuntu-Desktop mit grafischer Oberfläche im Docker-Container

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.

Installation und erster Start

  1. 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"

  2. 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

  3. 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.

  4. Öffnen Sie im Windows-Host folgende URL:

    start http://127.0.0.1:6080/vnc.html

  5. 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.

  6. 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

Erneuter Start

Linux-Basics



Docker mit Vagrant statt mit Docker Toolbox

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:

  1. 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.

  2. Installieren Sie VirtualBox und Vagrant, wie in den ersten Schritten unter Hello-World-Webanwendung mit Vagrant, VirtualBox, Ubuntu und Tomcat erläutert ist.

  3. Testen Sie, ob der benötigte Port noch nicht anderweitig belegt ist:

    netstat -an | find ":18080"

  4. 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

  5. Erzeugen Sie im MeinDockerMitVagrant-Projektverzeichnis folgende Batchdatei: run.bat

    cd vagrantDirectory
    vagrant up
    cd ..
    
  6. 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.

  7. 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.

  8. 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
    
  9. 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
    
  10. 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!
    
  11. 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
     '- ...
    
    
    
    
    
    
    
    
    
  12. 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"
    ...
    
  13. 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.





Weitere Themen: andere TechDocs | Continuous Delivery | Red Hat OpenShift Cloud | Google App Engine (GAE/J) | Maven
© 2015-2016 Torsten Horn, Aachen