Docker mit Spring Boot: wie baue ich ein Image?

Szenario

Ziel

Ich möchte ein funktionsähiges docker-Image bauen, das die Applikation beherbergt und dessen Container mit einem neo4j-Container kommunizieren kann.

application-wo-docker docker-application

Voraussetzungen

Ich arbeite auf einem Linux-System (Ubuntu 14.0 LTS), auf dem docker 1.9.1 läuft. Um die Platformvoraussetzungen zu erfüllen, lade ich die entsprechenden Images:

docker pull neo4j
docker pull java:8

Damit wäre die Pakete, die ich brauche, schon mal auf meinem Rechner.

Einrichtung von Java

Das Java-8-Image ist die Basis für das Applikations-Image. Daher möchte ich dieses in meiner privaten Registry speichern.

docker pull java:8

Mit dem Tag ‚java8‘ kann ich dann später die Applikation aufsetzen.

Einrichtung von neo4j

Neo4j bietet einen Container an, der die eigentlichen Nutzdaten außerhalb des Containers speichert. Um dieses Feature zu nutzen, mache ich die folgenden Schritte (als root, mit kurzem Wechsel zu einem neuen Nutzer namens neo4j):

useradd -U -m neo4j
sudo su - neo4j
mkdir geohierarchy
exit

Den Container starte ich als root mit diesem Kommando:

docker run --detach --restart=always --name=neo4j --publish=7474:7474 --volume=/home/neo4j/geohierarchy:/data neo4j

Erklärungen: der Prozess soll im Hintergrund gestartet werden (–detach) und auch dann neu starten, wenn er gestoppt wurde (–restart=…). Die Einführung des Namens ist notwendig, um später aus der Applikation heraus die Datenbank ansprechen zu können. Im Verzeichnis /home/neo4j/geohierarchy wird die eigentliche Datenbank abgelegt. Diese wird in gemounteten Verzeichnis gespeichert und bleibt auch dann erhalten, wenn der Container gelöscht wird.

Der einfachste Test der Funktionalität: im Browser http://localhost:7474 eingeben und ggf. einrichten (z.B. Passwort setzen).

Applikation

docker gibt einiges an Infrastruktur vor, das jetzt in Zusammenarbeit mit Spring Boot in Einklang gebracht werden muss. Das ist der Überblick:

  • neo4j erhält einen eigenen Container mit einem eindeutigen Namen: ’neo4j‘
  • der Spring-App-Container erhält den Namen ‚web‘
  • ‚web‘ wird mit dem Container ’neo4j‘ verlinkt (siehe 3.), dadurch kann die Server-Adresse automatisiert abgefragt werden (siehe 4.)
  • ‚web‘ benötigt außerdem noch eine Konfiguration für die Credentials. Dies wird über ein separat gemountetes Konfigurations-Directory erledigt (siehe unten).

Dockerfile aufsetzen

Hier zunächst der Link zum Dockerfile. Dies sind die zentralen Elemente, auf die ich mich beziehe:

FROM java:8 
ADD geographicalHierarchy-0.0.1-SNAPSHOT.jar app.jar 
RUN bash -c 'touch /app.jar' 
RUN mkdir /config 
VOLUME /config 
ENTRYPOINT ["java","-jar","/app.jar", "--neo4j.serverUrl=http://${NEO4J_PORT_7474_TCP_ADDR}:7474"]

Zeile 1: das Basispaket ist java:8 (siehe oben)

Zeile 2: die Applikation wird in app.jar umbenannt und später im ENTRYPOINT gestartet.

Zeile 4 und 5 legen ein Directory config/ an, das später automatisch von Spring Boot zur Konfiguration der App eingelesen wird. Dieses Directory kann von außen gemountet werden, um Konfigurationen einzuspielen (siehe 1).

Zeile 6 ist der Befehl, der ausgeführt wird, wenn der Container gestart wird. Man sieht, dass hier auch ein Parameter namens neo4j.serverUrl gesetzt wird. Die dort befindliche Variable NEO4J_PORT_7474_TCP_ADDR wird später vom Neo4j-Container bereitgestellt, wenn dieser mit der App verbunden wird. Hier erfolgt zunächst nur die Annahme, dass dies der Fall ist.

docker image bauen

Zum Bauen des Containers sollte eigentlich das Target buildDocker genügen. Im Hintergrund passiert folgendes: das Application-Jar und das docker-File wird in ein Verzeichnis kopiert (build/docker). Dort kann man dann den folgenden Befehl ausgeführen:

docker build -t localhost:5000/ollihoo/geohierarchy:0.5 .

Das Label 0.5 sollte entsprechend gesetzt werden. Als Ergebnis steht nun  ein docker-Image namens   localhost:5000/ollihoo/geohierarchy:0.5 zur Verfügung.

 

Konfiguration zur Verfügung stellen

Wie im Readme des Projektes beschrieben, sollte nun ein Konfigurationsverzeichnis mit einer application.properties angelegt werden. Diese Konfiguration ist dazu gedacht, die Credentials setzen zu können. Im Beispiel wird dieses Verzeichnis hier abgelegt: /opt/geoHierarchyConfig

 

Den Container zum Laufen bringen

Nun muss nur noch alles verbunden werden:

docker run -p 8080:8080 --link=neo4j -d --volume=/opt/geoHierarchyConfig:/config localhost:5000/ollihoo/geohierarchy:0.5

Erläuterungen:

Durch -p wird der Port 8080 nach außen verfügbar gemacht. –link=neo4j zeigt an, dass der Container neo4j verfügbar sein muss. Ist dies der Fall, exponiert er Variablen, die von der App benutzt werden (siehe oben). -d lässt der Prozess im Hintergrund laufen. —volume sorgt dafür, dass die Konfiguration zur Verfügung steht.

Das war’s. Die Applikation sollte laufen.

Feedback?

Was ist noch unklar? Was fehlt? Was ist falsch oder kann besser gemacht werden? Schreibt mir 🙂

 

Links

  1. Spring Boot: external configuration
  2. github: GeohierarchyGraph project
  3. docker – network
  4. docker hub: neo4j

 

Schreibe einen Kommentar