Meecrowave deployen mit Docker

Björn Berg
Cofinpro
Published in
4 min readSep 7, 2020

Im letzten Blogbeitrag zu Meecrowave ging es darum, wie einfach mit Meecrowave ein Microservice erstellt werden kann. Heute wollen wir diesen in ein Docker-Image verpacken, und als Container zu starten.

Hierfür bauen wir auf dem Beispiel-Projekt aus dem vorherigen Beitrag auf. Den Code hierzu gibt es auch auf GitHub.

Für das Docker-Experiment verwenden wir Maven mit diesem beiden Plugins:

  • Meecrowave Maven Plugin: Mit diesem Plugin lässt sich nicht nur ein Meecrowave-Projekt mittels Maven starten, sondern über den Befehl mvn meecrowave:bundle eine Distribution von Meecrowave erstellen, die alle notwendigen Bibliotheken sowie Skripte zum Starten und Stoppen des Servers mitliefert.
  • Docker Maven Plugin: Das von Fabric8 bereitgestellte Plugin kann aus einem Dockerfile und ein wenig Konfiguration in Maven ein Docker-Image erzeugen. Dabei kann die Konfiguration des Docker-Images komplett über Maven oder ein natives Dockerfile vorgenommen werden.

Mit diesen zusätzlichen Plugins wird das Modul person-server ausgestattet.

Dockerfile bereitstellen

Um den Build einfach zu halten, reizen wir nicht direkt alle Funktionen des Docker-Maven-Plugins aus, sondern greifen auf ein eigenständiges Dockerfile zurück. Das hat den Vorteil, dass sich das Image nicht nur mit Maven, sondern auch über docker build bauen lässt.

Das Dockerfile kommt in das Root-Verzeichnis des Projekts. Es basiert auf dem OpenJDK 8-Image von AdoptOpenJDK:

Dockerfile für den Meecrowave-Microservice

Mit dem Meecrowave-Maven-Plugin lässt sich eine Distribution erzeugen, die in verschiedenen Unterverzeichnissen alle notwendigen Dateien enthält, um Meecrowave auf einem Unix- oder Windows-System zu starten.

Damit die Distribution automatisch durch den Befehl ADD entpackt wird (Zeile 8), muss sie als tar.gz vorliegen. ZIP-Dateien, wie sie Meecrowave normalerweise erzeugt, erkennt Docker nicht als komprimiertes Archiv. Die Dateien werden in das Arbeitsverzeichnis /opt (als Ordner person-server) entpackt.

Das Meecrowave Start-Skript erlaubt es, verschiedene Parameter mitzugeben, sodass der Server entweder im Vorder- oder Hintergrund gestartet wird. Der Parameter run sorgt für den Start im Vordergrund und somit dafür, dass der Docker-Container nach dem Start nicht direkt wieder beendet wird.

Leider erkennt es das von docker stop gesendete Signal nicht, weshalb der Server nicht sauber beendet, sondern nach einem Timeout per SIGKILL unsanft abgebrochen wird.

Mit diesem Dockerfile sind wir soweit, mit mvn clean package meecrowave:build und einem anschließenden docker build . ein Image zu erzeugen, welches den Meecrowave-Service startet. Das reicht aber noch nicht: Das Modul person-server soll bei einem mvn clean package vollständig und inklusive Docker-Image gebaut werden.

Maven anpassen und Paketierung automatisieren

Hierfür wird über das Meecrowave-Maven-Plugin die Erzeugung der Distribution angepasst. Standardmäßig erzeugt das Plugin eine Distribution im Format ZIP mit dem Verzeichnis person-server-distribution. Der Verzeichnisname für das zu entpackende Archiv setzt sich dabei immer aus ${project.artifactId}-distribution zusammen.

Durch die Definition der Formate (Zeile 6–9) wird je eine Distribution als ZIP-Archiv und als Tar-GZ erzeugt. Letzteres verwenden wir, um das Docker-Image zu erzeugen.

Mit rootName (Zeile 10) wird der Name des gepackten Verzeichnisses beeinflusst. Statt person-server-distribution heißt das gepackte Verzeichnis nun nur noch wie unser Modul person-server.

Mit der executions-Passage koppeln wir die Distributionserstellung automatisch an den Maven-Lebenszyklus package.

Fehlt nur noch der automatische Bau des Docker-Images.

Docker-Image mit Maven automatisieren

Um Docker-Images reproduzierbar und automatisch über den Build-Prozess erzeugen zu können, gibt es das Docker Maven-Plugin. Mit einem Dockerfile ist das Plugin schnell konfiguriert. Doch damit sich das Docker-Image sowohl mit Maven, als auch mit docker build erstellen lässt, sind einige Dinge zu beachten.

Das Plugin ist ziemlich mächtig und bietet viele Optionen — wir wollen hier nur auf die wichtigsten eingehen. Ansonsten hilft die sehr ausführliche Dokumentation des Projekts weiter.

  • name und alias (Zeile 7/8) sorgen dafür, dass das erzeugte Image sich eindeutig in den lokalen Docker-Images wiederfinden lässt.
  • contextDir gibt an, wo das Dockerfile gespeichert ist. In diesem Fall im Root-Verzeichnis des Moduls.
  • name (Zeile 12) ist eine Besonderheit, um die Kompatibilität zu docker build aufrecht zu erhalten. Standardmäßig legt das Plugin alle für das Image notwendigen Dateien unter build/maven relativ zu seinem eigenen Arbeitsverzeichnis ab. Durch das Überschreiben des Namens werden die Dateien unter build/target erzeugt und sowohl docker build, als auch das Maven Plugin können mit dem gleichen Dockerfile arbeiten.
  • fileSet (Zeile 14–20) sorgt dafür, dass Maven Assembly genutzt um unsere Distribution in das Docker-Image zu übertragen.

Hier das Ergebnis: Das Plugin erzeugt ein Unterverzeichnis unterhalb von build namens target und kopiert die Tarball-Distribution dorthin.

Die Konfiguration unter executions sorgt dafür, dass das Docker-Image bereits in der Phase package erstellt wird.

Nun sind wir in der Lage, mit mvn clean package die Anwendung inkl. Docker-Image zu erstellen. Anschließend können wir den Container starten:

docker run -d -p 8080:8080 person-server

Über curl http://localhost:8080/person lässt sich prüfen, ob der Microservice korrekt arbeitet.

Zusammenfassung

Mit dem Meecrowave- und dem Docker-Maven-Plugin lässt sich der Build-Prozess eines Microservices auf Basis von Apache Meecrowave soweit automatisieren, dass am Ende ein fertiges Docker-Image für das Deployment zur Verfügung steht.

Die notwendigen Änderungen in einem bestehenden Projekt sind schnell gemacht, und es bleibt trotzdem die Möglichkeit, das Image auch über die Docker-eignen Tools zu erstellen.

--

--