Perpetual Motion
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.
Wie werden die Mondgesteinsproben von den Apollo Missionen aufbewahrt
AWS Lambda@Edge liefert 503 Error und es gibt keine Logs
Jobbedingt musste ich mich kürzlich mit AWS Lambda@Edge Funktionen herumschlagen. Da die wenigesten wahrscheinlich wissen, was das ist:
Lamdba Funktionen gehören zum Bereich “serverless” – letztendlich bedeutet es nur, dass man nicht eigene Server oder Dienste (z.B. wordpress) hosted, sondern einzelne Funktionen. Beispiel: eine Bildskalierung. Sprich, man gibt dem Service eine URL mit und parameter, wie groß das Zielbild sein soll. Der Service holt sich das Bild von der URL, verkleinert/vergrößert es auf die Maße und gibt es dann zurück.
Lambda@Edge ist dann die Hipster Variante davon, diese Funktionen kann man nämlich vor sein AWS Cloudfront CDN hängen. Sprich, bei jedem Request, der beim CDN ankommt, wird vorher die entsprechende Lambda Methode ausgeführt. Mit dieser kann man den Request verändern, Authentifizierung abhandeln, oder auch z.B. A/B Tests fahren. (weitere Beispiele: docs.aws.amazon.com)
Im Gegensatz zum “normalen” Lambda gibt es jedoch ein paar Einschränkungen, die hier ganz gut erklärt werden: Lambda at the Edge
Zusätzlich zu den unzähligen Unterseiten, hier mal meine aktuellen Erkenntnisse zum Thema Lambda@Edge:
- AWS Lambda@Edge funkionen MÜSSEN in “North Virginia (us-east-1)” abgelegt werden!
- Der komplette Code für die Lambda Funktion darf nicht größer als 1MB sein, inkl. Libraries
- du MUSST nodejs8.10 oder nodejs10.x verwenden
- die Funktion darf nicht mehr als 128mb RAM verwenden
- die Funktion darf nicht länger als 5s laufen
- Die LOGS der Aufrufe über CLOUDFRONT werden nicht in Cloudwatch “North Virginia (us-east-1)” abgelegt, sondern in der Area, WO SIE HERKOMMEN. In meinem Fall also “EU (Frankfurt)”. Wenn man die Funktion selbst per Testcall in der Lambda Oberfläche aufruft, DANN landen die Logs in “North Virginia (us-east-1)”. Es hat mich mehrere Tage gekostet, darauf zu kommen…
- Cookies, die man an die Funktion überträgt, werden im Cookie Array (event.Records[0].cf.request.headers.cookie) nicht als “key: value” übergeben, sondern als “cookie: key=value”
Etwas fies ist, dass die Fehlercodes sich überlappen. In meinem Fall bekam ich immer wieder einen 503 Fehler angezeigt, sobald ich meine Funktion über Cloudfront aufrief. Da ich zu diesem Zeitpunkt den “anderen Ort” der Logs nicht kannte, musste ich raten. Die 503 Fehlerseite gab aber ungünstigerweise noch den Hinweis, dass die Funktion wahrscheinlich nicht genügend Permissions oder Ressourcen hat – was mich die ganze Zeit auf die falsche Fährte lockte. Denn eigentlich warf meine Funktion die ganze Zeit selbst einen 500er Fehler, weil das Cookie Parsing nicht richtig klappte. Diese Unterscheidung sieht man aber nicht wirklich von aussen – sprich, eine fehlerhafte Konfiguration von Lambda@Edge Funktionen und Fehler im Script selbst sehen von aussen exakt gleich aus.
Nachdem ich die Logs dann endlich gefunden hatte, war das Problem schnell behoben (siehe Punkt “cookies”) in der oberen Liste, funktionierte meine Funktion nun wie gewünscht.
Chrome scheint Videosoftware unter MacOS auszubremsen
Creative Director Felipe Baez von der Agentur Cre8ive Beast hat bemerkt, dass sich Final Cut Pro deutlich langsamer wird, und teilweise sogar abstürzen kann. Grund dafür ist das “Video-Toolbox” Framework, welches von MacOS bereitgestellt wird. Chrome nutzt dieses Framework und klaut somit die Ressourcen anderen Programmen, wie eben Final Cut Pro. Das gleiche Problem tritt auch z.B. bei Handbrake auf, und somit wahrscheinlich auch bei weiteren Video-Editoren.
Aktuell ist der Ratschlag: sobald man irgendeine Art von Videoschnitt macht, sollte Chrome nicht laufen.
Bei dieser Gelegenheit rate ich wirklich JEDEM dazu, sich den aktuellen Firefox nochmal anzusehen. War er in den letzten Jahren eher langsam und behäbig geworden, ist er nun seit ca. 0,5-1 Jahr wieder in seiner alten Form zurück. Er ist super schnell (teilweise sogar schneller als Chrome), hat die gleichen Funktionen, und ganz wichtig: nimmt Privatsphäre und Datenschutz höchstwahrscheinlich deutlich ernster als andere Browserhersteller. Ich bin schon vor einer ganzen Weile umgestiegen (auf meinem Mac und auch auf iPhone/iPad) und bereue es in keinster Weise!
via Golem
Wie funktioniert eine Spülmaschine
Richtung 2000 – Vorschau auf die Welt von Morgen
Unfassbar, wie gut die Vorhersagen getroffen wurden – zumindest teilweise 🙂
https://www.youtube.com/watch?v=kaGnBNhE2xI
https://www.youtube.com/watch?v=WiOaN5RbCBk
https://www.youtube.com/watch?v=StxNtLIhf4k
Firefox deaktiviert addons
Am Wochenende ist Mozilla leider ein sehr blöder Fehler unterlaufen: das Zertifikat, welches die Echtheit von Extensions sicherstellt, ist abgelaufen 🙁
Die Folge: sämtliche Extensions/Erweiterungen sind komplett deaktiviert und lassen sich weder aktivieren noch neu installieren.
Die Lösung ist, zumindest aktuell, relativ einfach:
Einstellungen öffnen, dann den Punkt Datenschutz & Sicherheit wählen und dort den Punkt aktivieren, dass ihr an so genannten “Studien” teilnehmen wollt. Darüber wird nämlich gerade der Hotfix verteilt:
Danach habe ich den Browser einmal neu gestartet, und nach ein paar Minuten erschienen meine Addons wieder.
Da ich noch nicht so recht weiß, was ich von diesem Setting halten soll, mit dem Mozilla eigentlich beliebig meinen Browser steuern darf, werde ich es wohl in den nächsten Tagen, sobald der “offizielle” Fix da ist, wieder deaktivieren.