Manchmal möchte ich schnell mal etwas testen. Da ich regelmäßig mit Softwarelösungen arbeite, die hauptsächlich unter Linux laufen, setze ich mir für Testzwecke eine virtuelle Maschine auf. Das geht, ist aber recht Ressourcen-hungrig. Egal, ob unter Hyper-V oder Virtual Box. Irgendwann hat mein Rechner möchte ich mehr als zwei Maschinen gleichzeitig laufen lassen, halt keinen Speicher mehr. Also muss ich mir etwas anderes einfallen lassen.
Die beste Lösung hierfür ist ohne Zweifel ein Docker-Setup. Bei Docker handelt es sich um eine Containerlösung. Vereinfacht gesagt bedeutet das, dass auf dem Host ein Dockerservice installiert wird. Nach der Installation können beliebig viele (je nachdem was der Rechner/Server so hergibt) Web-/Mailserver, Datenbanken, Wordpressinstanzen, etc. gestartet und gemanaged werden. Eine Übersicht über die möglichen Container, die unter Docker laufen, ist auf Docker Hubs zu finden.
Das Schöne daran ist: die meiste Software ist direkt ohne weitere Programmierkenntnisse einsetzbar, z.b. Apache, MySQL oder Neo4J. Die Container werden sozusagen runtergeladen, individuell konfiguriert und in der Dockerumgebung gestartet. Klingt einfach? Ist es auch. Wer mir nicht glaubt, kann das hier direkt mal nachlesen.
Docker compose - dein Freund und Helfer
Inwiefern ist das also auch für die Digital Humanities interessant? In etlichen Bereichen werden NoSQL Datenbanken, wie eXist-db oder BaseX eingesetzt. Diese Datenbanken sind ebenfalls bereits als vorbereitete Dockerimages zu haben.
Möchte man solch eine Konfiguration öfters mal testen, tut man sich gut daran eine sogenannte docker-compose Datei zu schreiben. Hierbei handelt es sich um eine Art Beschreibung, welches Image Docker laden soll und wie dieses zu konfigurieren und zu starten ist.
Im Juni wurde eine neue NoSQL-Datenbank mit dem Namen FusionDB veröffentlicht. Zu Testzwecken habe ich hierfür eine docker-compose Datei erstellt, die ich im Folgenden präsentieren möchte:
version "3"
services:
fusiondb:
image: fusiondb
build:
context: ./conf
dockerfile: ./Dockerfile
args:
PASSWORD: ${PASSWORD}
INIT_MEMORY: ${INIT_MEMORY:-256}
MAX_MEMORY: ${MAX_MEMORY:-2048}
CACHE_SIZE: ${CACHE_SIZE:-256}
COLLECTION_CACHE: ${COLLECTION_CACHE:-256}
LUCENE_BUFFER: ${LUCENE_BUFFER:-256}
HTTP_PORT: ${HTTP_PORT:-4059}
HTTPS_PORT: ${HTTPS_PORT:-5059}
SERVER_NAME: ${SERVER_NAME:-localhost}
volumes:
- data:/opt/fusiondb/fusiondb-server-1.0.0-ALPHA1/data
ports:
- 4059:4059
- 5059:5059
container_name: fusiondb
restart: always
networks:
- www
labels:
- "traefik.backend=fusiondb-backend"
- "traefik.docker.network=www"
- "traefik.frontend.rule=Host:fusiondb.stephan-makowski.de"
volumes:
data: {}
networks:
www:
external:
name: ${TRAEFIK_NETWORK:-www}
In dieser Datei soll ein Dienst mit dem Namen fusiondb
erstellt werden. Hierfür gibt es (noch) kein fertiges Image, sodass dieses vorab erstellt werden muss. Die Anweisungen was und wie die Erstellung vorgenommen wird, befinden sich in der Datei "Dockerfile", die im weiteren Verlauf dieses Beitrages ebenfalls besprochen werden soll.
Ein wichtiger Vorteil von Docker ist, dass diese über sogenannte Volumes verfügen können. Hierbei handelt es sich um (permanente) Verzeichnisse, die zur Laufzeit innerhalb des Containers gemounted werden sollen. Es sind sozusagen Ordner, die an einer bestimmten Stelle eingehangen werden sollen. An dieser Stelle soll das Volume data
an das Verzeichnis /opt/fusiondb/fusiondb-server-1.0.0-ALPHA1/data
angehangen werden. Wieso wird dieses gemacht? Die Volumes können vom Host her gesichert werden. Außerdem sorgt dieses dafür, dass die Daten persistent vorgehalten werden. Ohne solch ein Volume, würde bei jedem Start wieder der Ursprungszustand des Images wiederhergestellt werden. Das ist bei Datenbanken etwas unpraktisch.
Die meisten Dienste im Internet sind per sogenannte Portangaben zu erreichen. Für die Internetseiten ist es meist der Port 80
, der als Standard für alle eingehenden Http-Anfragen genutzt wird. Der Service fusiondb
soll allerdings auf eingehende Anfragen auf den Port 4059 (http) sowie 5059 (https) lauschen. Die Angaben können hier ganz leicht gesetzt werden. Oft kommt es aber vor, dass zwei unterschiedliche Dienste den selben Port nutzen. In diesem Fall kann in der Datei eine Zuweisung vorgenommen werden, welcher Port alternativ abgehört werden soll. Die Notation hierfür ist:
-ports:
Es ist also eine Art Weiterleitung und kann für jeden Dockercontainer genutzt werden.
- externer Port: interner Port
Die folgenden Definitionen geben schließlich noch an wie der Service heißt, welches interne Routingnetzwerk genutzt werden soll und, ob ergänzende Informationen benötigt werden. In meinem Fall habe ich noch die Angaben für den Routerservice Traefik angegeben. Abschließend folgen die Definitionen der Netzwerke sowie der Volumen. An dieser Stelle sei auf die gute Dokumentation von Docker verwiesen.
Wenn man kein Image hat, baut man sich halt eines
Wie bereits erwähnt, gibt es derzeit für fusiondb
noch kein Dockerimage. Da ich aber dieses aber gern testen wollte und für zukünftige Updates bereits vorbereitet sein möchte, erstelle ich mir das Image halt selbst.
Im Grunde folgt die Datei dem Aufbau:
- welche Basis soll benutzt werden
- was soll innerhalb der Basis gemacht werden
- wie ist das Image ansprechbar und wie soll Docker die Inhalte ansprechen
ARG BASE_CONTAINER=ubuntu:latest
FROM $BASE_CONTAINER
LABEL maintainer="Stephan Makowski <[email protected]>"
USER root
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF-8"
ARG PASSWORD
ARG INIT_MEMORY=256
ARG MAX_MEMORY=2048
ARG CACHE_SIZE=256
ARG COLLECTION_CACHE=256
ARG LUCENE_BUFFER=256
ARG HTTP_PORT=8080
ARG HTTPS_PORT=8443
ARG SERVER_NAME='localhost'
RUN apt-get update && apt-get -yq dist-upgrade &&\
apt-get install -yq --no-install-recommends \
sudo \
curl \
htop \
default-jdk \
unzip \
vim \
wget &&\
rm -rf /var/lib/apt/lists/*
WORKDIR /opt/fusiondb
RUN wget http://www.fusiondb.com/download/fusiondb-server-1.0.0-ALPHA1-unix.tar.bz2
RUN tar xjf ./fusiondb-server-1.0.0-ALPHA1-unix.tar.bz2
WORKDIR /opt/fusiondb/fusiondb-server-1.0.0-ALPHA1
VOLUME /opt/fusiondb/fusiondb-server-1.0.0-ALPHA1/data
RUN echo '#!/bin/bash' >> /usr/local/bin/docker-entrypoint.sh &&\
echo 'set -e' >> /usr/local/bin/docker-entrypoint.sh &&\
echo 'cd /opt/fusiondb/fusiondb-server-1.0.0-ALPHA1' >> /usr/local/bin/docker-entrypoint.sh &&\
echo 'sudo bin/startup.sh' >> /usr/local/bin/docker-entrypoint.sh &&\
chmod +x /usr/local/bin/docker-entrypoint.sh
EXPOSE ${HTTP_PORT} ${HTTPS_PORT}
HEALTHCHECK --interval=1m --timeout=3s \
CMD curl -f http://localhost:4059/ || exit 1
ENTRYPOINT ["docker-entrypoint.sh"]
Kurz zusammengefasst, soll das Image für die Datenbank das letzte verfügbare Ubuntu als Ursprungsbetriebssystem nutzen. Anschließend erfolgt eine Aktualisierung als auch die Installation benötigter Komponenten, wie Java. Im folgenden Arbeitsschritt lädt Docker dann die Datenbank herunter, entpackt diese und kopiert das Startskript, damit dieses von Docker ausgeführt werden kann.
Mir ist klar, dass es sicherlich nicht die eleganteste Lösung ist und wollte noch weitere Verarbeitungsschritte einarbeiten. Deshalb sind noch einige etwas kryptische Argumente enthalten. Aber es ist soweit lauffähig. Und das erlaubt mir schon mal vorab fleißig zu testen. Sollte in naher Zukunft eine aktualisierte Version heraus kommen, bin ich vorbereitet.
Die Skripts können vollständig aus meinem Gitlab heruntergeladen werden.
Ausblick
Ob eine kleine NoSQL-Datenbank zum testen, eine Wordpressinstanz als Projektseite oder ein Cluster, der über mehrere Server Ausfallsicherheit bietet. All das kann Docker, und noch mehr. Und das Wichtigste: Das System ist kostenfrei erhältlich und nutzbar. Die Zeiten, in denen in langwierigen Verfahren an Rechenzentren Server beantragt werden mussten, sind vorbei. Denn Docker ist ein wunderbares Werkzeug und erleichtert einem massiv die Arbeit. Für einen Austausch zu dem Thema, stehe ich gern zur Verfügung.