Flotter Dreier mit Jenkins, Git und Tomcat
Das Ziel war klar: Unser Java-Programmcode soll von unserem Jenkins-Build-Server regelmäßig kompiliert und dann auf unseren Tomcat-Server deployt werden. So weit, so gut. Doch dafür mussten einige Hindernisse überwunden werden.
In Bezug auf Versionierungs-Systeme hatte ich in meiner Programmierer-Vergangenheit bislang hauptsächlich Kontakt mit CVS und Subversion. Beide sind heute nicht mehr zeitgemäß, also wird unser Programmcode mit Git verwaltet. Als Hoster habe ich Github ausgewählt, so viele bekannte Projekte können da nicht falsch liegen.
Zudem bin ich es beruflich mittlerweile gewohnt, dass der Programmcode mindestens einmal am Tag "gebaut" wird, der Griff zum Jenkins-Buildserver lag da sehr nah. Und der Tomcat-Server für unsere Java-Webanwendung sollte da leicht angebunden werden können - dachte ich zumindest. Also, Schritt 1: Git-Plugin für Jenkins installieren. Klappt problemlos.
Schritt 2: Einen Git-Job im Jenkins erstellen, der den Programmcode aus unserem Repository bei Github auscheckt. Leider klappt das nicht ganz problemlos, als eines der Probleme erweist sich die Authentifizierung bei Github - wobei ich dachte, dass man über die korrekte URL auch "anonym" auschecken kann. Ist aber wohl nicht so, zumindest über http(s) und ssh. Die als "read only" angepriesene URL git://github.com/oregami/oregami.org.git klappt leider nicht, vermutlich wegen der Firewall auf meinem Server. Die will ich aber lieber nicht anfassen.
Die Lösung für dieses Problem: Der Tomcat-User, unter dem Tomcat auch läuft, bekommt über ssh-keygen ein eigenes private/public-Key-Paar, und der Puclic Key wird bei Github hinterlegt. Dann noch über "git config" die EMail-Adresse und den Github-Usernamen hinterlegen, und es müsste klappen. Pustekuchen. Letzter Schritt vor dem Zwischenziel: einmal "git clone" in der Konsole aufrufen und den SSH-Server zu den "known-hosts" hinzufügen lassen. Erst jetzt klappt der Git-Checkout im Build-Job!
Schritt 3: Jenkins soll per Maven den Java-Programmcode kompilieren. Eigentlich auch einfach. Aber auch hier liegt der Teufel im Detail: Der Programmcode liegt innerhalb des Repositories in einem Unterverzeichnis. Man hat ja auch noch was Anderes im Repository außer Programmcode... Das ist für das Git-Plugin anscheinend ein Problem. Diverse Google-Suchen bringen kein hilfreiches Ergebnis. Letzendlich habe ich mich für die Notlösung entschieden: Im Hauptverzeichnis des Repositories wird eine neue pom.xml-Datei angelegt, die auf ein Modul mit dem Namen des Unterverzeichnisses verweist. Kleiner Missbrauch von Maven-Technologien, aber es funktioniert. Der Build läuft und gibt endlich (u.a.) das hier aus:
Aus dem Build purzelt eine WAR-Datei, die soll nun im letzten Schritt 4 noch auf den laufenden Tomcat-Server deployt werden. Also her mit dem Jenkins-Deploy-Plugin. Aber auch hier ist das, was ich als selbstverständlich erwartet hatte, nicht so einfach möglich: Wie sich nach weiteren Google-Recherchen herausstellt, haben sich mit Tomcat 7 die URLs für die Manager-Anwendung geändert, wodurch das Deployen fehlschlägt. Angeblich ist das gefixt, das scheint aber meiner installierten Version (die neueste) nicht zu interessieren. Glücklicherweise finde ich hier eine alternative Lösung, auch wenn sie keinen Schönheitspreis gewinnt: anstelle des Deploy-Plugins einfach einen Shell-Befehl mit "curl" ausführen, der die WAR-Datei an die entsprechende Tomcat-URL sendet. Was mir noch fehlte, war die Authentifizierung des curl-Aufrufs, dafür braucht man in der Datei tomcat-users.xml eine Rolle "manager-script". Auch das ist neu erst seit Tomcat Version 7. Keine Langeweile.
Zu guter letzt noch herausfinden, wie man beim curl-Aufruf die übergebene User/Passwort-Kombination unsichtbar macht: nämlich indem man diese mit der Option "-K" aus einer Textdatei ausliest. Super! Das Ergebnis ist dann dieser Befehl:
curl -K /opt/tomcat/.tomcat_curl_user -T - 'http://demo.oregami.org/manager/text/deploy?update=true&path=/' < /opt/jenkins/jobs/oregami-git/workspace/java/target/web.war
Und die Moral von der Geschicht':
Nach dem Prinzip der Continuous Integration sollten die Entwickler oft ihre Programmänderungen committen und es sollten oft Anwendungs-Builds erfolgen. Das haben wir für unsere neue Online-Spiele-Datenbank Oregami nun hinbekommen. Zumindest das regelmäßige Bauen der Anwendung läuft, für mehr Commits brauchen wir mehr Java-Programmierer :-)
Also: Steigt mit ein und schreibt eine Mail an sebastian[at]oregami.org !
Zudem bin ich es beruflich mittlerweile gewohnt, dass der Programmcode mindestens einmal am Tag "gebaut" wird, der Griff zum Jenkins-Buildserver lag da sehr nah. Und der Tomcat-Server für unsere Java-Webanwendung sollte da leicht angebunden werden können - dachte ich zumindest. Also, Schritt 1: Git-Plugin für Jenkins installieren. Klappt problemlos.
Schritt 2: Einen Git-Job im Jenkins erstellen, der den Programmcode aus unserem Repository bei Github auscheckt. Leider klappt das nicht ganz problemlos, als eines der Probleme erweist sich die Authentifizierung bei Github - wobei ich dachte, dass man über die korrekte URL auch "anonym" auschecken kann. Ist aber wohl nicht so, zumindest über http(s) und ssh. Die als "read only" angepriesene URL git://github.com/oregami/oregami.org.git klappt leider nicht, vermutlich wegen der Firewall auf meinem Server. Die will ich aber lieber nicht anfassen.
Die Lösung für dieses Problem: Der Tomcat-User, unter dem Tomcat auch läuft, bekommt über ssh-keygen ein eigenes private/public-Key-Paar, und der Puclic Key wird bei Github hinterlegt. Dann noch über "git config" die EMail-Adresse und den Github-Usernamen hinterlegen, und es müsste klappen. Pustekuchen. Letzter Schritt vor dem Zwischenziel: einmal "git clone" in der Konsole aufrufen und den SSH-Server zu den "known-hosts" hinzufügen lassen. Erst jetzt klappt der Git-Checkout im Build-Job!
Schritt 3: Jenkins soll per Maven den Java-Programmcode kompilieren. Eigentlich auch einfach. Aber auch hier liegt der Teufel im Detail: Der Programmcode liegt innerhalb des Repositories in einem Unterverzeichnis. Man hat ja auch noch was Anderes im Repository außer Programmcode... Das ist für das Git-Plugin anscheinend ein Problem. Diverse Google-Suchen bringen kein hilfreiches Ergebnis. Letzendlich habe ich mich für die Notlösung entschieden: Im Hauptverzeichnis des Repositories wird eine neue pom.xml-Datei angelegt, die auf ein Modul mit dem Namen des Unterverzeichnisses verweist. Kleiner Missbrauch von Maven-Technologien, aber es funktioniert. Der Build läuft und gibt endlich (u.a.) das hier aus:
[INFO] Building Oregami Webapp
[INFO] task-segment: [clean, install]
Aus dem Build purzelt eine WAR-Datei, die soll nun im letzten Schritt 4 noch auf den laufenden Tomcat-Server deployt werden. Also her mit dem Jenkins-Deploy-Plugin. Aber auch hier ist das, was ich als selbstverständlich erwartet hatte, nicht so einfach möglich: Wie sich nach weiteren Google-Recherchen herausstellt, haben sich mit Tomcat 7 die URLs für die Manager-Anwendung geändert, wodurch das Deployen fehlschlägt. Angeblich ist das gefixt, das scheint aber meiner installierten Version (die neueste) nicht zu interessieren. Glücklicherweise finde ich hier eine alternative Lösung, auch wenn sie keinen Schönheitspreis gewinnt: anstelle des Deploy-Plugins einfach einen Shell-Befehl mit "curl" ausführen, der die WAR-Datei an die entsprechende Tomcat-URL sendet. Was mir noch fehlte, war die Authentifizierung des curl-Aufrufs, dafür braucht man in der Datei tomcat-users.xml eine Rolle "manager-script". Auch das ist neu erst seit Tomcat Version 7. Keine Langeweile.
Zu guter letzt noch herausfinden, wie man beim curl-Aufruf die übergebene User/Passwort-Kombination unsichtbar macht: nämlich indem man diese mit der Option "-K" aus einer Textdatei ausliest. Super! Das Ergebnis ist dann dieser Befehl:
curl -K /opt/tomcat/.tomcat_curl_user -T - 'http://demo.oregami.org/manager/text/deploy?update=true&path=/' < /opt/jenkins/jobs/oregami-git/workspace/java/target/web.war
Und die Moral von der Geschicht':
Nach dem Prinzip der Continuous Integration sollten die Entwickler oft ihre Programmänderungen committen und es sollten oft Anwendungs-Builds erfolgen. Das haben wir für unsere neue Online-Spiele-Datenbank Oregami nun hinbekommen. Zumindest das regelmäßige Bauen der Anwendung läuft, für mehr Commits brauchen wir mehr Java-Programmierer :-)
Also: Steigt mit ein und schreibt eine Mail an sebastian[at]oregami.org !