Automatisches Deployment mit Bitbucket

In größeren Projekten und mit vielen Team-Mitgliedern ist es sicher von Vorteil eine Versionierungssoftware wie Git zu nutzen. Viele nutzen deswegen oft Plattformen wie Github, Gitlab oder Bitbucket. Wer dazu sein eigenes Deployment-Environment nutzt, der könnte das auschecken der letzten Version automatisieren. Wie das mit Bitbucket geht, zeige ich auf dieser Seite.

Vorbereitung: Das Deployment Environment

In der Regel besteht eine minimale Entwicklungsumgebung aus einer lokalen, einem Develop- und einer Live-Instanz einer Website. Wer es noch weiter treiben möchte, kann auch noch eine separate Test-Instanz betreiben. Diese wird aber oft – gerade in kleineren Projekten – weggelassen. Zur Übersichtlichkeit – und damit Sie es einmal gehört haben – noch einmal die englischen Begrifflichkeiten:

  • Development / (lokale) Entwicklungsumgebung
  • Testing
  • Staging
  • Production

Automatisches Bitbucket Deployment: Anleitung

Schritt 1: SSH Schlüssel generieren

Damit der Server mit Bitbucket ohne Passwort-Abfrage Kontakt aufnehmen kann, muss ein SSH-Schlüssel hinterlegt werden. Dazu wechselt man auf dem Server mit

cd ~/.ssh

in das SSH-Verzeichnis und legt dann mittels:

ssh-keygen -t rsa

einen neuen Schlüssel an.

Die Ausgabe sieht dann ungefähr so aus:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/flo/.ssh/id_rsa): bitbucket
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in bitbucket.
Your public key has been saved in bitbucket.pub.
The key fingerprint is:
c7:1d:c8:xx:xx..... flo@some.server.de
The key's randomart image is:
+--[ RSA 2048]----+
....

Schritt 2: Schlüssel bei bitbucket hochladen

Im .ssh-Verzeichnis befinden sich jetzt zwei neue Dateien: bitbucket und bitbucket.pub. Ersteres ist der private, letzteres der öffentliche Schlüssel.

Den Inhalt des öffentlichen Schlüssels kopiert man sich nun vom Server und fügt ihn bei Bitbucket ein. Und zwar im Repository unter „Einstellungen“ > „Access keys“.

Einstellungsseite für die Access Keys bei Bitbucket
Einstellungsseite für die Access Keys bei Bitbucket

Schritt 3: Host auf dem Server freigeben

Auf dem Server editiert man nun die Datei ~/.ssh/config (wenn sie nicht existiert, muss man sie anlegen). Dort fügt man folgende Zeile ein:

Host bitbucket.org
IdentityFile /path/to/.ssh/bitbucket

Verlinkt wird hier quasi auf die zuvor erstellte, private Schlüsseldatei.

Schritt 4: Hochladen des PHP-Tools

Nun holt man sich das PHP-Tool automatic-bitbucket-deploy, entpackt es und lädt es in ein Unterverzeichnis auf dem Server. Wichtig ist, dass Sie sich die URL merken, über die das Tool dann erreichbar ist. Zum Beispiel:

https://develop.meine-domain/bitbucket-deployment/

Schritt 5: Konfiguration des PHP-Tools

Nun kopiert man sich die Inhalte aus config.sample.php und kopiert sie in die config.php. Dabei wird die Zeile

include_once "config.sample.php";

überschrieben. Die Konfiguration könnte dann so aussehen:

$CONFIG = array(
    'gitCommand'       => 'git',                   // Git-Aufruf (wir nutzen git, deswegen ist das hier ok).
    'repositoriesPath' => '/path/to/repos',        // Der Pfad zum Verzeichnis in dem alle Repositories liegen.
    'log'              => true,                    // Ob das Logging aktiviert werden soll.
    'logFile'          => 'bitbucket.log',         // Dateinamen für das Logging.
    'logClear'         => true,                    // Ob die Logdatei bei jedem Webhook-Aufruf geleert werden sool.
    'verbose'          => true,                    // Ob Debug-Informationen angezeigt werden sollen.
    'folderMode'       => 0775,                    // Welche Rechte neu angelegte Verzeichnisse haben sollen.
);

// Liste der Projekte
$PROJECTS = array(
    'florian-simeth/lynk' => array(
        'master' => array(
            'deployPath'  => '/var/www/live-website.de/wp-content/themes/lynk',
            'postHookCmd' => '',
        ),
    ),

    'florian-simeth/lynk' => array(
        'develop' => array(
            'deployPath'  => '/var/www/dev-website.de/wp-content/themes/lynk',
            'postHookCmd' => '',
        ),
    ),
);

Wichtig sind die Konfigurations-Angaben (siehe Quellcode) sowie die Angabe der Projekte. Hierzu die Erklärung:

  • florian-simeth/lynk = der Benutzername (oder der Team-Name) sowie der Repository-Name
  • master = der Branch der ausgecheckt werden soll
  • deployPath = das Verzeichnis in die ausgecheckt werden soll.
  • postHookCmd = der Befehl der danach ausgefüllt werden soll (z.B. dann interessant, wenn man SCSS oder LESS noch automatisch umwandeln lassen muss).

Schritt 6: Webhook konfigurieren

Nun fügt man im Bitbucket-Repository (unter Einstellungen > Webhooks) die URL zum PHP-Script hinzu.

Weboberfläche zum Hinzufügen eines Webhooks in Bitbucket
Webhook hinzufügen

Unserem Beispiel wäre das:

https://develop.meine-domain/bitbucket-deployment/bitbucket-hook.php

Schritt 7: Download der Repositories

Auf dem Server wechselt man nun in das Verzeichnis, in dem die Repositories liegen sollen. Zu empfehlen ist ein Verzeichnis auf die der Webserver keinen Zugriff hat (z.B. ein Unterordner im Home-Verzeichnis). Danach checkt man die Repositories aus. In unserem Beispiel wäre das:

cd /path/to/repos

git clone --mirror git@bitbucket.org:florian-simeth/lynk.git
  • florian-simeth = Der Bitbucket Benutzer- oder Teamname.
  • lynk = der Repository-Name.

Der Befehl wird dann ein Verzeichnis mit dem Namen lynk.git anlegen. Sie erhalten dann eine Ausgabe, die ungefähr wie folgt aussehen könnte:

Cloning into bare repository 'lynk.git'...
The authenticity of host 'bitbucket.org (2401:1d80:1010::151)' can't be established.
RSA key fingerprint is 97:8c:xx:xx.....
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'bitbucket.org,2401:1d80:1010::151' (RSA) to the list of known hosts.
remote: Counting objects: 136, done.
remote: Compressing objects: 100% (135/135), done.
remote: Total 136 (delta 60), reused 0 (delta 0)
Receiving objects: 100% (136/136), 80.26 KiB | 0 bytes/s, done.
Resolving deltas: 100% (60/60), done.
Checking connectivity... done.

Schritt 8: Initiales auschecken der Repositories

Nun erstellen wir die entsprechenden Verzeichnisse in die ausgecheckt werden sollen:

und erstellen die entsprechenden Verzeichnisse:

mkdir /var/www/live-website.de/wp-content/themes/lynk

mkdir /var/www/dev-website.de/wp-content/themes/lynk

danach begeben wir uns in das Repository-Verzeichnis

cd lynk.git

und checken aus:

Für die Live-Seite

GIT_WORK_TREE=/var/www/live-website.de/wp-content/themes/lynk git checkout -f master

und dann nochmal auf die Dev-Seite:

GIT_WORK_TREE=/var/www/dev-website.de/wp-content/themes/lynk git checkout -f develop

master und develop sind also die Bezeichnung der Branches.

Schritt 9: Automatisches Deployment

Das war’s. Wenn wir nun Änderungen in master pushen wird die Live-Seite geupdated (in unserem Fall ein WordPress-Theme). Wenn wir nach develop pushen betrifft es die Entwicklerseite.

Stolpersteine

Oft ist es so, dass der Webserver als eigenständiger Benutzer (www-data) läuft. Hier muss sichergestellt werden, dass dieser User ssh-Zugriff auf Bitbucket haben kann und dass er auch auf die entsprechenden Verzeichnisse schreibend zugreifen kann.