Anwendungsfall für MSSQL in Docker unter Linux

Wie in einem meiner letzten Beiträge beschrieben, kann man mittlerweile einen MSSQL-Server auch unter Linux in Docker laufen lassen. Nun gilt es noch die berechtigte Frage zu klären: Weshalb sollte man sowas tun? Gibt es für dieses Konstrukt überhaupt sinnvolle Anwendungsfälle? Für alle die es eilig haben: Ja die gibt es. Wer es im Detail wissen will sollte weiter lesen.

Der Anwendungsfall für mich hängt indirekt auch mit der Jahreszeit zusammen, wie in jedem Jahr fällt mir als Schriftführer unseres Sportvereins die Aufgabe zu, mich um den Versand der Jahreszeitschrift zu kümmern. Man könnte es auch eine Alternative zu Weihnachtskarten nennen. Für die Verwaltung des Vereins haben wir eine fertige Software die leider nicht open source ist, geschweige denn dass sie nativ unter Linux laufen würde. Aus Sicht eines Anwendungsentwicklers ist die Software nicht gerade optimal, aber sie ist nunmal da und die anderen Mitglieder des Vorstands sind damit vertraut. Mal eben etwas zu ändern ist an dieser Stelle nicht drin.

Zwar gibt es verschiedene Export-Funktionen aus dem Programm auch in gängige Tabellenformate wie CSV oder auch Excel in verschiedenen Varianten. Diese sind aber (wahrscheinlich mit Absicht) derart gestaltet, dass man im Zweifel nur denormalisierte Daten bekommt, einige Attribute bzw. Relationen kann man gar nicht exportieren. Leider auch gerade solche die für den Versand interessant sind. Denn aus Kosten- und Umweltschutzgründen soll jeder Haushalt nur eine Zeitschrift erhalten. Dafür gibt es die Möglichkeit Mitglieder in “Familien” zu organisieren, aber genau diese Relation kann man nicht exportieren. Zudem ist es mühsam aus einer Excel-Datei wieder eine Datenbank zu machen. Man könnte nun auch einfach Serienbriefe auf Excel-Basis verwenden, allerdings wird es dann mit dem Filtern nach weiteren Kriterien schwierig – wer beruflich mit Datenbanken arbeitet weiß die Mächtigkeit von SQL-Befehlen einfach zu schätzen, zumal wenn dann auch noch programmatisch anhand bestimmter Kriterien unterschiedliche Ausgaben benötigt werden. So hatten wir alleine drei verschiedene Versandmethoden zu berücksichtigen: Selbst austragen (nur für einen Stadtteil, der sich seine Postleitzahl aber noch mit anderen Stadtteilen teilt …), Versand als Infopost (ging nur bis Ende 2019, seit 2020 geht per Infopost nur noch Werbung) und Versand als regulärer Brief. Insgesamt ein doch recht komplexes Regelwerk, das man nicht ohne Not in einer Office-Suite umsetzen will.

Die letzten Jahre habe ich eben in den sauren Apfel gebissen und den Excel-Export wieder normalisiert in ein eigenes Datenmodell überführt. Zeitaufwändig und natürlich immer nur ein Schnappschuss der Datenbank zu einem bestimmten Zeitpunkt. Für die zwei Mal im Jahr die man es braucht (neben der Vereinszeitschrift gibt es ein ähnliches Prozedere für die Einladung zur Mitgliederversammlung): Lästig aber ok. In diesem Jahr mussten wir aber die Mitgliederversammlung absagen und verschieben (COVID-19 macht auch vor dem Vereinsleben nicht halt). Dazu kam diesmal noch die Information für Absage und Verschiebung per e-mail (wobei ein Versand aus einem Mailprogramm aufgrund von Restriktionen beim Hoster nicht direkt möglich ist, Stichtwort Rate-Limit – immerhin nicht so eng wie die 100 Mails pro Tag beim Magenta-Riesen mit dem großen T…). Das hat bei mir dann den Ausschlag gegeben der Vereinsverwaltung einmal näher auf den Zahn zu fühlen.

Mir war von Anfang an klar: eine Software dieser Art benötigt irgendeine Form von strukturierter Datenhaltung. Die Zeiten in denen man derartige Formate selbst entworfen hat sind schon lange Geschichte. Es hätte mich gewundert wenn man für ein derartiges Nischenprodukt den Aufwand einer eigenständigen Lösung betrieben hätte – allenfalls bei sehr alten, gewachsenen Strukturen wäre dies noch denkbar gewesen.

Einen ersten Anhaltspunkt lieferte das Handbuch bzw. die Installationsroutine: Dort wird ein SQLExpress-Server mit installiert, alternativ besteht die Möglichkeit einen bereits installierten MSSQL-Server zu nutzen. Um es einfach zu machen verlässt sich das Programm auch noch auf die ohnehin vorhandene Windows-Authentifizierung. Startet man das Programm wird im Hintergrund der SQL-Express-Prozess gestartet und das eigentliche Programm ist dann nur noch ein Frontend, welches per SQL-Befehlen dem Backend Daten abtrotzt oder darin neue Inhalte ablegt. Mit dem bereits bekannten SQL Server Management Studio (SSMS) kann man aber parallel ohne großen Aufwand in die Datenbank schauen. Schreibenden Zugriff sollte man sich bei derartigen Analysen erst einmal verkneifen, denn man weiß ja nicht was die Applikation vornedran ggf. erwartet. Zudem wollte ich für etwaige erste Schritte eine abgesicherte Umgebung benutzen die ich im Zweifel jederzeit wieder in einen bekannten Zustand zurück versetzen kann. Extra einen MSSQL-Server hierfür zu besorgen war mir aber zu viel Aufwand, geschweige denn dass ich adhoc einen Windows-Rechner für derartige Zwecke greifbar gehabt hätte.

Genau an diesem Punkt bin ich auf die Option mit Docker gestoßen – wenn auch erst mal sehr skeptisch aber einen Versuch war es allemal wert. Wie bereits im letzten Artikel beschrieben kann man das recht gut aufsetzen und es ist auch recht gut dokumentiert. Mit einem SQL-Dump (in SSMS-Jargon “Datenbank-Script”) konnte ich auch recht schnell eine Kopie erzeugen. Noch einfacher geht es bei Verwendung von Backup-Files die man in den Server wieder einspielt.

Dabei gibt es allerdings einige Fallstricke, die man kennen sollte – unter anderem merkt man den Microsoft Tools an, dass sie erst am Anfang stehen was den Betrieb unter Linux betrifft. So kann es beim Einspielen eines Skripts schon mal vorkommen, dass der Parser sich verhaspelt und dann meint das Skript würde ewig nicht fertig. Eine Leerzeile am Ende des Scripts kann hier Wunder wirken, man muss auf diese Idee erst mal kommen. Zudem gibt es natürlich noch Probleme bei einem vollen Export, denn der MSSQL-Server im Docker-Container kann ggf. mit irgendwelchen Authentifizierungsinformationen eines Windows-Rechners sehr wenig anfangen. Auch daher besser ein Backup-File einspielen, dann gibt es diese Probleme nicht. Die Backup-Files kann man direkt in den laufenden Docker-Container mit


docker cp mybackupfile.bak mydbcontainer:/tmp/

in den Container kopieren. Alternativ kann man sie auch per Bind-Mount vom Host-System aus reinreichen, ganz nach Bedarf.

Hat man den Container am Laufen kann man sich in aller Ruhe und ohne Gefahr die Datenstruktur anschauen und Rückschlüsse daraus ziehen. Leider auch auf die Qualität der Modellierung – ich bin unter anderem auf “vergessene” Tabellen mit klarem Test-Charakter gestoßen. Ebenso habe ich feststellen müssen, dass referentielle Integrität per Fremdschlüssel sich auch noch nicht ganz so weit herum gesprochen hat, wie man sich das wünschen würde. Mit ein wenig Gespür für Datenanalyse kann man dann auch recht einfach die notwendigen Daten per SQL extrahieren – ganz ohne denormalisierte Zwischenformate.

Für den eiligen Fall mit der e-mail-Absage bin ich dann noch einen Umweg gegangen und habe per MySQL-Workbench eine Datenmigration in eine MySQL-Datenbank durchgeführt (natürlich auch wieder als Docker-Container). So konnte ich dann recht einfach ein kleines PHP-Skript zusammen stellen, dass die e-mails in Bündeln vorerzeugt per IMAP mit den gewünschten Empfängern bereit legt. Ebenso wäre es möglich gewesen ein Skript zu schreiben, welches die Mail gleich per SMTP an den Mailserver übergibt, aber ich wollte nochmal sichergehen dass alles auch richtig verschickt wird.

Wenn man dann etwas mehr Zeit und Lust hat, bohrt man die PHP-Installation derart auf, dass man mit PHP auch MSSQL-Server ansprechen kann. Das ist auch ein wenig frickelig – zum lokalen Entwickeln habe ich das erst mal nativ installiert. Auch hier wäre ggf. ein dezidierter Docker-Container sinnvoll.

Mit dem gesamten Wissen ist es nunmehr ein Leichtes die benötigten Abfragen und Ausgaben zu realisieren – zum Beispiel als fertiges PDF, das man dann nur noch an einen Drucker schicken muss. Filtern und sortieren kann man beliebig komplex in der Datenbank machen und die Geschäftslogik hat man nunmehr auch selbst in der Hand. Somit war zumindest einmal die Jahresendzeit-Aufgabe als Schriftführer erledigt.

Natürlich bin ich noch etwas neugieriger gewesen – es ist sogar möglich, dass Original-Programm gegen die Datenbank im Docker laufen zu lassen, dazu muss man nur den Connection-String anpassen und für diesen Fall sind sogar im Programm Funktionen vorgesehen. Mit diesem Konstrukt kann man die Vereinsverwaltung natürlich auf ein ganz neues Level heben: Abfragen und Statistiken die es im ursprünglichen Programm nicht gibt implementiert man kurzerhand per SQL-Befehl selbst. In begrenztem Umfang kann man mit etwas Vorsicht wahrscheinlich auf schreibende Zugriffe wagen.

Insgesamt ist das Thema spannender als ich gedacht habe, aber durchaus ein sinnvoller Fall für einen MSSQL-Server in Docker unter Linux.Einen kleine Wermutstropfen gibt es derzeit noch: Der MSSQL-Server benötigt zwingend eine x86 bzw. x64-Architektur – Experimente auf einem Raspi als “mini-Server” gehen daher nicht, denn Docker ist ja nur eine Paravirtualisierung. Aber auch ein kleiner kompatibler Server kostet heute nicht mehr die Welt.

Zudem finde ich es einen wichtigen Schritt zur Erhaltung der Datenhoheit. Gerade im Hinblick auf den weniger bekannten Artikel 20 der DSGVO, wonach man auf Anfrage Daten in einem gängigen maschinenlesbaren Format weitergeben können muss ist ein optionaler Zugriff auf die zu Grunde liegenden Daten ein echter Mehrwert. Die eingangs erwähnte Zuordnung von Mitgliedern zu Familien die ich nicht exportieren kann macht im Zweifel die Software ungeeignet für die Vereinswerwaltung, denn ein Mitglied müsste im Zweifel ja auch informiert werden zu welcher Familie er zugeordnet ist, wenn er per Artikel 15 Auskunft ersucht. Es ist ja durchaus möglich, dass aufgrund von Namensähnlichkeiten oder Bedienfehlern hier eine Zugehörigkeit gespeichert ist die man gerne korrigiert haben möchte. Wo wir gerade beim Datenschutz sind: Es versteht sich von selbst, dass man den Docker-Container nicht gerade offen auf irgendeiner Cloud-Instanz exponiert laufen lässt, sondern ihn entsprechend abschottet, auch wenn es nur ein Experiment ist.