curl output anpassen

Wenn du den Output von Curl anpassen willst, um z.B. nur zu schauen, welcher http Code zurückgeben wird oder nur schauen möchtest, wie lange das laden der Seite gedauert hat, dann kannst du mit der Option “-w” genau das tun:

curl -s -w "%{http_code} - %{time_total}\n" -o /dev/null [URL]

In diesem Beispiel war der http Status 200 und die Seite hat 0.08s zum Laden benötigt.

docker-compose Setup ist von anderen Containern nicht erreichbar

Folgende Situation:

Du hast auf einem Docker Host diverse Container laufen, die teilweise auch untereinander kommunizieren. Nun möchtest du per docker compose ein paar weitere Container hinzufügen. Und dann bemerkst du, dass diese Container von den “alten” Containern (z.B. einem nginx Proxy) nicht erreichbar sind, weil docker-compose diese automatisch in ein eigenes Network packt.

Um das Problem zu lösen, ist die einfachste (wenn auch nicht schönste) Variante, dass die docker-compose container auch im “default” Netzwerk (“bridge”) teilnehmen. Dazu muss man einfach für jeden Container/Service der Eintrag

network_mode: bridge

Damit die Container aus der docker-compose Datei sich auch noch untereinander sehen können, kann man sie ganz klassisch per

link:

Annotation zusammenführen.

Linux Server zeigt unterschiedliche Werte bei df und du

Wenn das Monitoring meldet, dass die Platte eines Servers voll läuft, ein

du -hs /*

aber deutlich weniger verwendeten Speicher anzeigt als man es per df sieht – dann gibts erstmal Verwunderung.

Eine google Recherche hat mich dann auf den Trichter gebracht, dass dies ein Zeichen von zwar gelöschten Dateien, aber noch offenen Dateihandles auf diesen liegen kann. Sprich, man hat zwar eine Datei gelöscht, aber ein Programm hat die Datei aktuell noch geöffnet. Dann ist zwar der Dateiname nicht mehr sichtbar, aber die Inhalte der Datei liegen noch immer auf der Festplatte und verbrauchen natürlich auch ensprechend Platz. In meinem Fall ist filebeat nicht mit einem Logrotate klar gekommen und hatte somit eine relativ große Log Dateien weiterhin geöffnet. Mit jedem Logrotate kam eine dazu…

Wie kann man das sichtbar machen? So:

lsof | grep "/var" | grep deleted

oder gleich mit

lsof | grep deleted

wobei man bei letzterem vielleicht ein paar Ergebnisse sieht, die berechtigt noch Handles offen halten.

Hier mal eine Beispielhafte Ausgabe:

Ganz links sieht man den Dienst bzw. Command, und in der ganz rechten Spalte die jeweilige Datei.

Normalerweise sollte es reichen, den entsprechenden Dienst einfach neu zu starten und das Problem ist erstmal behoben. Sollte der Fehler wieder auftreten, müsste dann evtl ein Update/Patch oder als letzte Möglichkeit ein kontrollierter regelmäßiger Neustart das Problem beheben.

Ansible startet nicht mehr unter Mac OS Catalina

Beim Ausführen von Ansible Befehlen bekam ich seit kurzem immer wieder die Fehlermeldung

Abort trap: 6

angezeigt. Da ich Ansible direkt über pip installiert hatte, führte ich natürlich erstmal ein Update dort durch – was aber keine Abhilfe brachte. Irgendwie hatte das ganze mit dem Wegfall von python 2.7 mit Mac OS Catalina zu tun.

Die relativ plumpe, aber doch effektive Lösung war:

pip3 uninstall ansible
brew install ansible

🤷‍♂️😂

Nach Mac OS Catalina Update – Mail App Suchfunktion ist kaputt

Das Update auf Mac OS Catalina lief bei mir eigentlich ohne Probleme durch, aber heute fiel mir dann auf, dass die Suchfunktion in der Mail App sich sehr komisch verhielt bzw. einfach kaputt war.

Mir war natürlich gleich klar, dass der Suchindex wahrscheinlich einen Treffer hatte, da ich die App ja trotzdem normal bedienen und Mails senden/empfangen konnte.

Um das Problem zu beheben, musste ich also den Suchindex der Mail App zurücksetzen und neu aufbauen lassen. Dazu sind folgende Schritte nötig:

  1. Mail App beenden
  2. Im Finder den Ordner ~/Library/Mail/V7/MailData öffnen (mit CMD+SHIFT+G)
  3. Alle Dateien, die mit „Envelope Index“ beginnen löschen (oder in einen Backup-Ordner schieben)
  4. Mail App wieder starten. Es empfängt euch ein Screen, der mitteilt, dass Mail sich selbst reparieren muss. Anschließend werden die Mails neu indiziert, in dieser Zeit ist Mail nicht benutzbar.

Nginx Docker Reverse Proxy wirft 404 Fehler ab dem zweiten Request

Als großer Fan von “nackten Servern” auf denen nur Docker Container laufen, nutze ich Nginx als Reverse Proxy – im Speziellen das großartige Setup von jwilder/nginx-proxy in Kombinantion mit dem Let’s Encrypt Addon. Effektiv läuft das Teil passiv mit und schaut nur auf bestimmte Environment-Variablen anderer Docker Container. Sobald es diese sieht, wird automatisch ein Reverse Proxy in Nginx so konfiguriert, dass er diesen Dienst erreichbar macht und gleichzeitig wird noch ein Let’s Encrypt Cert für die entsprechende Domain besorgt und auf dem neuesten Stand gehalten.

Nun hatte ich in einem Setup mit sehr vielen gleichzeitig laufenden Diensten das Problem, dass einer der Dienste immer nur auf den ersten Request erfolgreich geantwortet hat, aber bei jedem weiteren Request nur noch einen 404 geworfen hat. Der Dienst selbst lief, Nginx hat auch keinen Fehler im Log geworfen und ich war etwas ratlos.

Nach ein paar grauen Haaren mehr und dem ein oder anderen versteckten Hinweis auf Google kam ich dann auf des Rätsels Lösung: durch ein fehlerhaftes Deployment lief kurzzeitig ein weiterer Container, der mittels der Environment Variable die gleiche URL für sich beanspruchte. Der Nginx Automatismus machte daraus automatisch einen Load Balancer. Nachdem das fehlerhafte Deployment weg war, wurde der Loadbalancer aber nicht mehr aufgelöst und somit war nur noch einer von beiden Einträgen aktiv. Warum der Nginx dann trotzdem immer wieder auf den nicht vorhandenen Host gehen wollte erschließt sich mir nicht so richtig, aber das war des Problems Lösung.

Also bin ich einfach per docker exec in den Nginx Container und habe die Datei /etc/nginx/conf.d/default editiert:


# server.name.com
upstream server.name.com {
# CONTAINER_NAME_1
server 123.45.0.67:1234;
# CONTAINER_NAME_2
server 123.45.0.78:1234;
}

Nachdem ich den Part von CONTAINER_NAME_2 gelöscht hatte, konnte ich mittels

nginx -s reload

die Config von Nginx on the fly neu laden und ab dem Moment lief der Service wieder wie gewohnt.

Wie man Featurebranches mit Jenkins baut

Meine Güte! Wie viel Zeit habe ich bereits in dieses Thema investiert und am Ende ist die Lösung meines Problems dann doch so simpel…

Aber fangen wir von vorn an. Der moderne Entwickler arbeitet in der Regel mit git und im optimalen Fall nach dem gitflow Konzept bzw. mit Featurebranches. Ist der Code fertig gestellt, wird ein für den Branch ein Review durchgeführt und davor bzw. gleichzeitig wird durch eine CI – in meinem Fall Jenkins – geprüft, ob dieser Branch denn so überhaupt noch lauffähig ist. Im konkreten Beispiel ist Atlassian Bitbucket dabei der Git host, es werden Pull Requests verwendet und um diese mergen zu können, muss Jenkins melden, dass der Code erfolgreich integriert werden konnte.

Jenkins ist dabei so eingestellt, dass es einen Job gibt, der auf sämtliche Branches eines Repositories lauscht. Sobald es einen Push gibt, checkt Jenkins diesen Code-Stand aus und baut ihn. Wenn alles gut ist meldet er das an Bitbucket zurück. Das Problem ist nun: was ist, wenn der Build wegen eines Problems auf der Buildnode, fehlendem Internet oder warum auch immer fehlschlägt? Dann wird man nie den Merge vollziehen können, da die Rückmeldung von Jenkins fehlt. Man kann nun einfach irgendeinen weiteren Commit machen, diesen pushen und es geht von neuem los. Oder aber, man macht es folgendermaßen:

Der ursprüngliche Job (“Job-01”), der auf alle Branches gelauscht hat, wird so umgebaut, dass er parametrisiert ist (Parametername “Branchname” z.B.) und im git Bereich wird angegeben , dass nur der Branch “$Branchname” gebaut werden soll. Anschließen legt man einen weiteren Job an (“Job-02”), der auf das gleiche repo sowie Veränderungen in allen Branches lauscht.

Dieser Job wiederum macht nichts anderes, als bei einer erkannten Änderung den parametrisierten Job  (“Job-01”) auszuführen und den entprechenden Branch als Parameter zu übergeben.

Nun haben wir erstmal den gleichen Zustand wie vorher – aber zusätzlich die Möglichkeit, den parametrisierten Job von Hand und unter Angabe des gewünschten Branches zu bauen. Also eben z.B., wenn der Job vorher fehlgeschlagen ist. Dieser wiederum kann dann seinen Status auch an Bitbucket melden.