Blog

Atlassian Server mit Docker vereinfachen

SEP 14, 2020

Als Atlassian Platinum Partner haben wir nahezu jedes denkbare Szenario erlebt – auch schwierige Situationen mit selbst verwalteten bzw. selbst gehosteten Server-Setups. In diesem Blog beschreiben wir eine dieser Situationen und zeigen, wie ihr sie mit Containern bewältigen könnt.

Timothy Harris

An American living in Denmark. Tim used to work for Eficode. He has more than 20 years of experience in development, operations, continuous integration, and delivery.

Gelegentlich werden wir gebeten, bei der Aktualisierung einer Instanz einer Atlassian-Anwendung zu helfen. Oft sind diese Instanzen bereits Jahre alt.

Typisch für diesen Anwendungsfall ist, dass die Personen, die die Instanz installiert haben, nicht mehr verfügbar sind. Es gibt kein Wissen darüber, wie sie installiert und konfiguriert wurde, daher weiß niemand, wie sie aktualisiert werden kann.

Oft wurde alles manuell eingerichtet, wobei viele verschiedene Rollen beteiligt waren. Möglicherweise gab es ein Infrastrukturteam für die Hardware, ein Datenbankteam für die Datenbank, ein Anwendungsteam für einen Proxy und so weiter. Das kann überwältigend wirken, und das Upgrade kann zeitaufwendig und mühsam sein. Etwas, das eigentlich recht unkompliziert sein sollte, kann Stunden oder sogar Tage dauern.

Die Folgen einer solchen Situation sind leicht vorhersehbar: mögliche Sicherheitsprobleme, mühsame Upgrade-Prozesse und die Unfähigkeit, neue Features und Verbesserungen zu nutzen. Dazu kommt die Sorge: Was ist mit dem bevorstehenden Audit? Und dann entstehen zusätzliche Kosten, wenn Experten wie Eficode hinzugezogen werden müssen.

Als Unternehmen profitieren wir davon, Kunden in solchen Situationen zu helfen. Aber wir sind auch ein DevOps-Unternehmen: Bei solchen Szenarien schaudert es uns, und wir mögen mühsame Upgrades genauso wenig wie ihr. 

Lösung

Ziel ist es, Technologie zu nutzen, um Installation, Upgrades und Migrationen zu vereinfachen. 

  • Die Installation sollte einfach sein und nur wenig Fachwissen erfordern.

  • Upgrades sollten unkompliziert sein und so wenig Zeit in Anspruch nehmen, dass sie regelmäßig durchgeführt werden.

  • Die Migration auf einen neuen Host sollte relativ unkompliziert sein.

  • Um den Koordinationsaufwand zu reduzieren, sollten möglichst wenige Personen beteiligt sein.

  • Die Lösung sollte reproduzierbar und unempfindlich gegenüber Wissensverlust sein.

Technologieauswahl

Ich habe mich für Docker und docker-compose entschieden, um die Anwendungsinstanz bereitzustellen und zu verwalten. Damit lässt sich die Anwendung als Code verwalten, direkte Abhängigkeiten lassen sich gemeinsam paketieren, das Deployment der verschiedenen Komponenten orchestrieren und alles reproduzierbar gestalten.

Für diese Demo verwende ich den Bitbucket Server von Atlassian als Atlassian-Anwendung. 

Dabei kommt das Bitbucket Docker Image von Atlassian zum Einsatz. Wir möchten die Verwaltung und Wartung der Instanz so unkompliziert wie möglich gestalten, und eigene Images zu erstellen, ergibt wenig Sinn.

Für die Datenbank wird das offizielle PostgreSQL Image verwendet. PostgreSQL ist kostenlos, wird offiziell von Atlassian unterstützt und bietet eine sehr gute Performance. Soweit ich weiß, nutzt Atlassian diese Datenbank selbst – sie ist also eine sehr gute Wahl.

Schließlich verwende ich Traefik als Proxy. Es ist kostenlos, sehr einfach einzurichten, leistungsfähig und unterstützt HTTP/HTTPS sowie TCP. Für die SSH-Funktionalität benötigen wir einen Proxy mit TCP-Unterstützung. Zudem lässt es sich nahezu ohne Konfiguration in LetsEncrypt und die wichtigsten DNS-Anbieter integrieren, die das ACME-Protokoll unterstützen.

Architektur & Infrastruktur

Alle wesentlichen Komponenten sollten auf einer virtuellen Maschine (VM) bereitgestellt und von docker-compose orchestriert werden. Backups können über nächtliche Snapshots der VM oder per Skript erstellt werden. Ihr könnt auch einen CI-Server Backup-Skripte ausführen und die Backups remote speichern lassen. Es gibt viele Möglichkeiten.

Die Gründe dafür, alle Komponenten auf einer einzigen VM zu betreiben, sind einfach: Es geht um Einfachheit. Ein kleines Repository verwaltet alles, was für die Bereitstellung der Anwendung nötig ist. Eine VM macht Deployment und Backups so einfach wie möglich. 

Bei Bitbucket besteht außerdem eine enge Kopplung zwischen Dateisystem und Datenbank. Beispielsweise werden Metadaten, die auf im Dateisystem gespeicherte Hashes verweisen, in der Datenbank abgelegt. Für ein vollständiges Backup müssen daher Datenbank und Anwendung gemeinsam gesichert werden.

Architektonisch sind nur drei Komponenten erforderlich: Traefik als Proxy, Bitbucket und die PostgreSQL-Datenbank. 

Ich habe außerdem eine Domain bei AWS eingerichtet, damit ich Traefik über route53 so konfigurieren kann, dass es die SSL-Zertifikate für mich verwaltet. Traefik kann die Verwaltung von SSL-Zertifikaten erheblich vereinfachen.

imageLikeEmbed_blog_image

Das Repository

Wie schwierig ist das? Nun, nicht besonders. Ein Demo-Repository findet ihr hier.

Es gibt nur vier wichtige Dateien.

Die eigentliche Komplexität steckt im Skript backup-restore.sh. Der Rest besteht nur aus YAML und Variablenzuweisungen.

Im Demo-Repository verwenden wir Amazon Route53 mit LetsEncrypt, um unsere SSL-Zertifikate zu verwalten. Daher benötigen wir einen AWS Access Key, das zugehörige Secret und eine verknüpfte E-Mail-Adresse. Ihr könnt auch eigene Zertifikate in den Traefik-Container einbinden, aber es ist angenehm, sich nicht um die Zertifikatsverwaltung kümmern zu müssen.

Außerdem habe ich die Domain thedukedk.net bei Route53 registriert.

In den folgenden Abschnitten findet ihr Screencasts, die die Nutzung dieser Lösung zeigen.

Installation

Ihr müsst lediglich die Variablen in der Datei .env ausfüllen. Falls noch kein DNS-Eintrag auf den Host verweist, fügt SERVER_PROXY_NAME zu eurer Hosts-Datei hinzu.

Startet anschließend alles mit dem Befehl docker-compose up -d.

Der Screencast zeigt den gesamten Prozess.

Im Screencast seht ihr, dass alles nur wenige Minuten dauerte und einen einzigen Befehl erforderte.

  • Das Traefik-Dashboard erreicht ihr unter localhost:8080.

  • Traefik verarbeitet HTTPS über Port 443 und leitet den Web-Traffic an den Service bitbucket-web weiter.

  • Traefik verarbeitet SSH über Port 7999 und leitet den SSH-Traffic an den Service bitbucket-ssh weiter.

  • Traefik arbeitet mit LetsEncrypt und Route53 zusammen, um das SSL-Zertifikat für HTTPS zu erstellen.

  • Beim Verbinden von Bitbucket mit der Datenbank könnt ihr den Postgres-Containernamen postgres-bitbucket verwenden.

Um das gesamte Setup zu beenden, führt docker-compose stop aus.

Ihr könnt auch docker-compose down ausführen, um die Container zu stoppen und zu löschen. Alle erforderlichen Daten bleiben in Docker-Volumes erhalten, sodass beim Löschen der Container keine Daten verloren gehen.

VOLUME NAME

CONTENTS

bitbucket_data

Bitbucket’s data(home) directory.

bitbucket_db

Postgres database files.

bitbucket_letsencrypt

The certificate and key data. Stored in the file acme.json.

VOLUME-NAME

INHALT

bitbucket_data

Bitbuckets Daten-(Home-)Verzeichnis.

bitbucket_db

PostgreSQL-Datenbankdateien.

bitbucket_letsencrypt

Die Zertifikats- und Schlüsseldaten. Gespeichert in der Datei acme.json.

Upgrade

Das komplexeste Upgrade-Szenario umfasst ein Upgrade der Datenbank und der Anwendung. Sehen wir uns diesen Prozess an.

Im Screencast seht ihr:

  • Die Bitbucket-Version war 7.0.2 und die PostgreSQL-Version 9.5.

  • Ich habe die Container heruntergefahren.

  • Ich habe mit dem Skript backup-restore.sh ein Backup erstellt.

  • Ich habe das PostgreSQL-Docker-Volume gelöscht und die PostgreSQL-Version in den beiden Compose-Dateien aktualisiert.

  • Ich habe den PostgreSQL-Container mit der neuen Version gestartet, damit er initialisiert werden konnte.

  • Ich habe den PostgreSQL-Container gestoppt und die Daten aus der SQL-Backupdatei wiederhergestellt.

  • Ich habe die Bitbucket-Version in der Docker-Compose-Datei aktualisiert und die Container wieder gestartet.

Im Screencast seht ihr, dass der gesamte Prozess etwa 5 Minuten gedauert hat. Einen großen Teil davon nahm die Startzeit von Bitbucket ein.

Die Dauer hängt natürlich von der Größe des Bitbucket-Datenverzeichnisses ab, das gesichert werden soll. Aber selbst ein Backup einer Instanz mit einem Dateisystem von rund 10 GB dauert nur wenige Minuten. Das Backup und die Wiederherstellung der Datenbank gehen etwas schneller.

Host migrieren

Wenn ihr das Setup auf einen neuen Host migrieren müsst, startet ihr einfach ein noch nicht konfiguriertes Setup und stellt anschließend das Datenverzeichnis und die Datenbank aus einem Backup wieder her. Der Prozess sieht wie folgt aus.

Im Screencast seht ihr:

  • Eine neue Instanz von Bitbucket, Traefik und PostgreSQL wurde gestartet.

  • Bitbucket war weder konfiguriert noch mit PostgreSQL verbunden.

  • Das Skript backup-restore.sh wurde mit einem komprimierten Tarball des Datenverzeichnisses und einem SQL-Dump der Datenbank vom anderen Host ausgeführt.

  • Das Skript backup-restore.sh hat die Container nach der Wiederherstellung neu gestartet. Anschließend war alles konfiguriert und verbunden.

Migration zu Docker

Wenn ihr zu einer solchen Lösung wechseln möchtet, ist das nicht so schwierig, wie ihr vielleicht denkt. Angenommen, ihr habt ein Setup, bei dem der Server manuell auf einer Maschine installiert ist und die Datenbank auf einer Remote-Maschine mit einem anderen Datenbanktyp läuft, beispielsweise MSSQL.

Ihr möchtet die Anwendung in einem Container wiederherstellen und mit einer Kopie der MSSQL-Datenbank verbinden. Anschließend nutzt ihr die integrierte Datenbankmigrationsfunktion, um zur containerisierten PostgreSQL-Datenbank zu migrieren. 

imageLikeEmbed_blog_image_2

Damit die containerisierte Instanz eine Verbindung zur Kopie der bestehenden Datenbank herstellt, müsst ihr die Datei bitbucket.properties im Backup-Tarball bearbeiten, sodass sie auf die Datenbankkopie verweist. 

jdbc.url=jdbc:sqlserver://<MSSQL SERVER>:<PORT>;databaseName=<NAME OF DATABASE COPY>;

Der Ablauf sieht wie folgt aus.

Im Screencast seht ihr:

  • Wir starten eine frische Instanz aller Container.

  • Wir stellen einen komprimierten Tarball wieder her, bei dem die Datei bitbucket.properties so bearbeitet wurde, dass sie auf eine Kopie des MSSQL-Servers und der Datenbank verweist.

  • Wir starten alle Container erneut und überprüfen, ob die Repositories wiederhergestellt wurden.

  • Wir nutzen die Datenbankmigrationsfunktion von Bitbucket, um vom MSSQL-Server zum PostgreSQL-Container zu migrieren.

Zusammenfassung

Die Verwaltung von Atlassian-Anwendungen muss nicht mühsam sein. 

Wenn ihr gerade erst mit Atlassian-Anwendungen startet, solltet ihr alle verfügbaren Optionen in Betracht ziehen. Mein Kollege hat einen Blogbeitrag über wichtige Überlegungen beim Einstieg in Atlassian-Anwendungen geschrieben – er ist auf jeden Fall lesenswert.

Wenn Upgrades oder Migrationsszenarien für euch gerade mühsam sind, nehmt euch jetzt die Zeit für eine Veränderung. Andernfalls geratet ihr später wahrscheinlich in eine noch problematischere Situation. 

Abschließend noch ein wenig über uns und unsere Arbeit mit Atlassian-Anwendungen. 

  • Wir bieten Support für die allgemeine Nutzung und Konfiguration der Cloud- und Server-Angebote von Atlassian.

  • Als Atlassian-Schulungspartner bieten wir unseren Kunden außerdem praxisnahe Trainings. 

  • Für Kunden, die das Cloud-Angebot von Atlassian nicht nutzen können, die Anwendungen aber nicht selbst hosten und verwalten möchten, bieten wir im Rahmen der Eficode ROOT DevOps-Plattform eine vollständig gemanagte Option. 

  • Wir unterstützen Kunden bei der Installation und Wartung von Atlassian-Server- und Data-Center-Lösungen vor Ort.

  • Atlassian
  • Cloud

Subscribe to our newsletter