Auslieferung und Backup von Web-Apps im Zeitalter der DevOps
Montag, 03.09.2018
Das Backup und die Auslieferung (Deployment) von Web-Applikationen sind ähnliche Aufgaben mit ähnlichen Herausforderungen. Ihre Lösung birgt Synergien, die in systematischen Prozessen der Continuous Delivery genutzt werden können.
Die Time-to-Deploment-Zyklen in der Entwicklung von Web-Applikationen werden immer kürzer. Daher ist es notwendig, die Prozesse für das Deployment weitgehend zu automatisieren und dabei dennoch die Kontrolle über die Auslieferung zu behalten. Sie wollen wissen, wer wann was und warum ausgeliefert hat.
In der Entwicklung auf Basis von Content-Management-Systemen (CMS) kommt dazu, dass sich Teile des Deployments auf Datenbanken beziehen, die sich einer unmittelbaren Versionskontrolle entziehen. Synergien entstehen dadurch, dass Teilprozesse des Backups und des Deployments wiederverwendet werden können.
Backup richtig gemacht
Jedes CMS hat im Prinzip das gleiche Problem. Wir haben Dateien, die wir ausliefern müssen, wie zum Beispiel Views, Stylesheets, Scripts, Bilder und nicht zuletzt DLLs. Und wir haben eine Datenbank, in der die Contents hinterlegt sind. Im Idealfall passen beide Teile zusammen und ergeben eine lauffähige Website.
Will man ein Backup einer Website erstellen, aus dem man später wieder eine laufende Website restaurieren will, ist es sinnvoll, alle nötigen Dateien zu speichern, sowie ein Backup der Datenbank anzulegen, das dann mit den gespeicherten Dateien zusammen in einem Archiv abgelegt ist.
Das ist nicht ganz so simpel, wie der letzte Absatz glauben macht. So hat eine frische Umbraco-Installation ohne jede Funktionalität ca. 64 MByte Größe. Sie enthält über 1.700 Dateien in fast 400 Ordnern. In anderen CMS ist die Situation ähnlich. Man möchte nicht in jedem Backup diese immer gleich bleibenden 1.700 Dateien mitschleppen. Was wir im Backup brauchen, sind nur jene Dateien, die zusätzlich in eine bestimmte Umbraco-Version kopiert werden müssen, um eine lauffähige Kopie eines bestehenden Systems zu erhalten.
Welche Dateien das sind, lässt sich mit Hilfe einer Steuerdatei definieren. Auf unseren Systemen heißt diese Datei Backup.config und sie enthält Xml-Code, der nicht nur die Dateikopien steuert, sondern auch das Anlegen des Datenbank-Backups. Datenbanken können zum Beispiel auf getrennten Datenbank-Servern liegen. Erstellt man ein Backup der Datenbank, so muss dieses in einen shared Folder kopiert werden, aus dem sich dann der Backup-Code die Datei holt und dem Backup-Archiv hinzufügt. Solche Dinge werden in der Backup.config-Datei definiert.
Als weiteres Detail zum Thema Backup sei erwähnt, dass ein Backup nicht viel nützt, wenn es auf der gleichen Festplatte liegen bleibt, auf der auch die Website läuft. Das Backup muss via Ftp oder ähnliche Protokolle auf einen anderen Server kopiert werden. Auch dieser Vorgang wird bei uns über die Backup.config-Datei gesteuert.
Das lässt sich alles noch händisch beim Projektstart einrichten. Das eigentlich herausfordernde Problem ist jedoch, wie man dafür sorgt, dass die Liste der zu kopierenden Dateien in der Backup.config auch wirklich vollständig ist.
Auslieferung
Hier kommt uns die Lösung einer anderen Herausforderung entgegen, nämlich der Auslieferung (Deployment). Unsere Umbraco-Applikation entsteht in einem Ordner, in dem sämtliche zur Projekterstellung notwendigen Dateien liegen. So liegen dort zum Beispiel die Source-Code-Dateien, die dann später zu DLLs kompiliert werden.
Die gesamten Source-Codes werden über ein Versionsverwaltungssystem mit einem Repository auf einem Server abgeglichen. Damit ist es möglich, dass wir im Team gleichzeitig an Projekten arbeiten können, ohne dass sich unsere Aktivitäten in die Quere kommen - zum Beispiel durch gleichzeitiges Editieren an ein und derselben Datei.
Das System macht es möglich, dass ein Mitarbeiter eine Kopie des Repositories anlegen kann und daraus sofort ein lauffähiges System kompilieren kann. Einzige Ausnahme ist hierbei die Datenbank, die von einem Backup genommen und mit speziellen Scripts im lokalen Datenbank-Server installiert wird.
Man könnte jetzt auf die Idee kommen, dieses Repository zu nutzen, und auf dem Web Server einfach eine Kopie des Repositories anzulegen und aktuell zu halten. Aber die Source-Code-Dateien sind nicht das, was wir für ein lauffähiges System brauchen. Ja, es gibt eine Schnittmenge zwischen dem Entwicklungsrepository und dem Zielsystem, aber die beiden sind weit von einer Deckungsgleichheit entfernt.
Auftritt Deployment-Repository
Die Auslieferung des lauffähigen Systems über das Versionsverwaltungssystem ist dennoch eine gute Idee. Statt die Dateien aus dem Entwicklungssystem mit Ftp oder anderen Tools auf den Webserver zu kopieren, werden die Dateien erst einmal in das Auslieferungs-Repository kopiert. Damit ist nachvollziehbar, wer wann welche Dateien geändert hat. Mit Hilfe der Check-In-Kommentare lässt sich sehr gut nachvollziehen, welchem Stand des Entwicklungs-Repositories eine bestimmte Auslieferung entspricht.
Als Grundausstattung eines solchen Auslieferungs- bzw. Deployment-Repositories nehmen wir ein frisches Umbraco-System in der Version, für die wir die Anwendung entwickeln wollen. Nun müssen wir nur noch die Dateien aus dem Entwicklungs-Repository in das Deployment-Repository kopieren, die man braucht, um aus der reinen Umbraco-Kopie eine lauffähige Website zu erzeugen.
Wenn Sie jetzt ein Déjà-vu erleben, dann haben Sie gut aufgepasst. Die Dateien, die wir vom Entwicklungs-Repository in das Deployment-Repository kopieren müssen, sind exakt die gleichen Dateien, die wir beim Backup sichern müssen.
Ein Tool für's Deployment
Diese Tatsache, dass wir beim Deployment die gleichen Dateien kopieren müssen, wie beim Backup, machen wir uns nun zunutze. Wir haben ein Tool geschrieben, das den Kopiervorgang automatisiert. Und das Tool kopiert exakt die Dateien vom Entwicklungs- ins Deployment-Repository, die in der Backup.config-Datei gelistet sind. Damit können wir während der Entwicklung sicherstellen, dass alle Dateien, die wir brauchen, auch wirklich in der Backup.config-Datei stehen.
Wenn ein Entwickler für eine Funktion eine bestimmte Datei benötigt, dann wird er relativ schnell feststellen, wenn er die Datei in der Backup.config-Datei vergessen hat. Denn sein Test wird nach der Auslieferung nicht funktionieren. Hätten wir nicht diese Kopplung zwischen Auslieferung und Backup, müssten wir die Backup-Funktionalität mit der kompletten Abarbeitung des Testplans testen. Das können wir uns direkt sparen.
Um ganz sicher zu gehen, zeigt das Tool nach dem Kopieren an, welche Dateien neu sind, sodass keine neue Datei in der Auslieferung vergessen wird. Nun muss der Entwickler nur noch mit den üblichen Tools die Dateien des Deployment-Repositories einchecken.
Die eigentliche Auslieferung läuft über ein Verwaltungstool auf dem Webserver. Zum Zeitpunkt des Deployments kann die Applikation auf Knopfdruck auf den neuesten Stand des Deployment Repositories gebracht werden.
Was die Änderung der Datenbank anbetrifft, werden Skripts mit ausgeliefert, die beim ersten Start der Webapplikation nach dem Deployment die Datenbank aktualisieren.
Die Auslieferung erfolgt in zwei Stufen. Zunächst wird in ein Qualitätssicherungs-System deployed. Hier können unmittelbar automatisierte Tests angeschlossen werden. Sofern händische Tests notwendig sind, werden diese vom ausliefernden Entwickler vorgenommen.
Verlaufen die Tests zur Zufriedenheit, wird der gleiche Vorgang des Deployments auf dem Live-System wiederholt. Durch die automatisierte Auslieferung ist die Downtime des Systems meist auf wenige Sekunden beschränkt.
Natürlich steht auch die Backup.config-Datei in der Liste der zu kopierenden Dateien. Damit ist sichergestellt, dass auf dem Webserver immer die neueste Version dieser Datei liegt. Und diese sorgt nun dafür, dass unsere Backups vollständig sind.
Playdoyer für einen Software-Prozess
Das Fazit unter diesem Artikel ist aus unserer Sicht, dass es oft nicht die Algorithmen oder die tolle Technologie sind, die den Erfolg von Projekten ausmachen, sondern dass die Vorgehensweise einen großen Anteil am Projekterfolg hat. Und die Gesamtheit aller wohldefinierten Vorgehensweisen in der Software-Entwicklung nennt sich Software-Prozess.
In Zeiten der agilen Software-Entwicklung ist es notwendig, Teilprozesse möglichst zu automatisieren, sodass eine Pipeline aus Aktivitäten der Continuous Delivery entsteht, die möglichst wenig Overhead erzeugt.
Es lohnt sich, einen solchen agilen Software-Prozess zu etablieren. Als Entwickler spart man sich eine Menge Schwierigkeiten und die Kunden sind zufrieden, wenn die Systeme einfach laufen, ohne dass man darüber nachdenken muss. Denn wenn der Kunde anfängt, über Ihren Software-Prozess nachzudenken, liegt das Kind meist schon im Brunnen.