Szenario
- Applikation: Geohierarchy Projekt (siehe 2.)
- Abhängigkeit zu neo4j
- Abhängigkeit zu Java 8
Ziel
Ich möchte ein funktionsähiges docker-Image bauen, das die Applikation beherbergt und dessen Container mit einem neo4j-Container kommunizieren kann.
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
- Spring Boot: external configuration
- github: GeohierarchyGraph project
- docker – network
- docker hub: neo4j