Java EE, Docker und eine Datenbank

Für die Installation einer Java EE-Anwendung in einem Docker-Container hatte ich immer die Anforderung, dass für die Anbindung einer Datenbank das Image nicht neu erzeugt werden muss. Nur so lässt sich ein Docker-Image in verschiedenen Umgebungen testen. Die Erstellung der Datasource war dabei immer die größte Hürde. Leider gibt es dafür kein einheitliches Vorgehen. Zwar erlaubt Java EE die Definition z.B. über die web.xml oder Annotationen, allerdings kann dabei nicht auf System-Variablen zugegriffen werden.

Wenn es aber (wie in Payara) die Möglichkeit gibt, eine Datasource über die Kommandozeile zu erstellen, ist die gewünschte Portabilität erreicht.

Das folgende Dockerfile basiert auf Payara und fügt den Treiber für PostgreSQL hinzu. Anschließend wird über ein Skript die Datasource erstellt, um danach die Anwendung zu deployen.

Dockerfile
FROM payara/server-full:5.192
RUN wget --no-verbose -O postgresql.jar https://jdbc.postgresql.org/download/postgresql-42.2.5.jar && mv postgresql.jar ${PAYARA_DIR}/glassfish/domains/${DOMAIN_NAME}/lib
COPY init_0_create_datasource.sh ${SCRIPT_DIR}
COPY ui/target/car.war ${DEPLOY_DIR}

Das Skript zum Erzeugen der Datasource erwartet, dass System-Variablen gesetzt wurden und überprüft dies. Sind alle System-Variablen gesetzt, wird die Datasource erzeugt.

init_0_create_datasource.sh
#!/bin/bash

# Check required variables are set
if [ -z $DB_USER ]; then
  echo "Variable DB_USER is not set."
  exit 1
fi
if [ -z $DB_PASSWORD ]; then
  echo "Variable DB_PASSWORD is not set."
  exit 1
fi
if [ -z $DB_NAME ]; then
  echo "Variable DB_NAME is not set."
  exit 1
fi
if [ -z $DB_HOST ]; then
  echo "Variable DB_HOST is not set."
  exit 1
fi
if [ -z $DB_PORT ]; then
  echo "Variable DB_PORT is not set."
  exit 1
fi
if [ -z $POSTBOOT_COMMANDS ]; then
  echo "Variable POSTBOOT_COMMANDS is not set."
  exit 1
fi

# Create post boot command files if it doesn't exist
touch $POSTBOOT_COMMANDS

echo "Adding creation of datasource to post boot commands"
echo "create-jdbc-connection-pool --datasourceclassname org.postgresql.ds.PGConnectionPoolDataSource --restype javax.sql.ConnectionPoolDataSource --property user=${DB_USER}:password=${DB_PASSWORD}:DatabaseName=${DB_NAME}:ServerName=${DB_HOST}:port=${DB_PORT} carPool" >>$POSTBOOT_COMMANDS
echo "ping-connection-pool carPool" >>$POSTBOOT_COMMANDS
echo "create-jdbc-resource --connectionpoolid=carPool jdbc/car" >>$POSTBOOT_COMMANDS
echo "list-jdbc-resources" >>$POSTBOOT_COMMANDS

export DB_PASSWORD=""
echo $DB_USER
echo $DB_PASSWORD

So lässt sich dann zum lokalen Testen eine docker-compose.yml erstellen, über die alle benötigten Daten definiert werden und eine Datenbank mitgestartet werden kann.

Ein Maven-Projekt mit einer Beispiel-Anwendung zeige ich in einem Demo-Video auf YouTube:

Gern erstelle ich auch eine solche Anwendung nach euren Vorgaben. Schaut auf Fiverr vorbei.


Jens Kötterheinrich

javaee

12.02.2020

Kommentare oder Kontakt gern über Twitter oder die anderen Plattformen.