Ich erstelle gerade einen automatischen Ablauf um eine Webseite, welche in einem git-Repository erstellt wird, nachdem sie in ein zentrales Repository gepusht wurde, auf einen Webserver weiterzupushen und dort automatisch in das htdocs
-Verzeichnis zu kopieren.
Zunächst ist natürlich ein zentrales Entwicklungsrepository nötig. Dieses wird bei mir von gitolite verwaltet. In diesem muss ein post-receive
hook erstellt werden, der dafür sorgt, dass z.B. wenn in master ein neuer Commit empfangen wurde, master
an den Webserver gepusht wird.
Auf dem Webserver muss ein post-receive
dafür sorgen, dass die Webseite in htdocs
aktualisiert wird.
Es werden also zwei unterschiedliche post-receive
hooks benötigt, welche an den richtigen Stellen installiert werden müssen. Und der gitolite-Server muss in der Lage sein, post-receive hooks zu installieren.
Zunächst der gitolite Server: Hier findet sich eine recht gute Anleitung. Jetzt kann im gitolite-admin Repository unter dem (anzulegenden) Pfad local/hooks/repo-specific
ein Skript angelegt werden, das z.B. deploy
heißt. Dieses wird dann in der gitolite.conf
mit option hook.post-receive = deploy
in den gewünschten Repositories installiert. Es folgt der deploy post-receive hook:
#! /bin/bash
BRANCH="master"
# push to webserver
while read oldrev newrev ref
do
if [ "$ref" = "refs/heads/$BRANCH" ]
then
git push webserver ${BRANCH}
else
echo "Ref $ref received. Nothing to do"
fi
done
Damit das so funktioniert muss natürlich der Webserver als remote bekannt gemacht werden und ein SSH-Key hinterlegt werden. Also dem Repository auf dem gitolite Server mittels git remote add webserver <user>@<webserver>:<path> den Webserver bekannt machen und mit ssh-copy-id <user>@<webserver> den SSH-Zugang ermöglichen. Der gewählte user auf dem Webserver braucht Schreibzugriff auf das Verzeichnis, aus dem die Dateien ausgeliefert werden.
Auf dem Webserver muss nun unter dem zuvor gewählten <path>
mit git init --bare
ein leeres git Repository erzeugt werden. In dieses wird der folgende post-receive hook eingehängt.
#! /bin/bash
TARGET="/srv/www"
BRANCH="master"
while read oldrev newrev ref
do
if [ "$ref" = "refs/heads/$BRANCH" ];
then
echo "Ref "$ref" received. Deploying ${BRANCH} to htdocs"
git --work-tree=$TARGET checkout -f $BRANCH -- htdocs
else
echo "Ref $ref received. Doing nothing. Only ${BRANCH} will be deployed"
fi
done;
Ich habe in dem Repository einen Ordner mit dem Namen htdocs
, da noch mehr Dinge zu meiner Anwendung gehören. Es sollen natürlich nur diese ausgeliefert werden, daher wird in Zeile 10 nur dieses Verzeichnis in das Verzeichnis /srv/www
ausgecheckt.
Wenn alles funktioniert hat, wird nun jedes Mal, wenn etwas in den master branch des gitolite Repositorys gepusht wird, der Inhalt des Verzeichnisses htdocs
automatisch auf dem Webserver veröffentlicht.