In unserer ersten Remote-Ausgabe vom Geekstammtisch sprachen wir mit Florian Motlik, CTO von Codeship.io. In dem Gespräch haben wir im Grunde alle wesentlichen Aspekte einer Continuous Delivery Plattform abgeklopft. Technischen Themen wie der automatischen Provisionierung von Build-Servern oder der Verwaltung von LXC Container standen dabei ebenso im Fokus wie die Entwicklung eines sehr guten User-Interfaces. Da Codeship ein recht junges Unternehmen ist, gab es auch Einblicke in die Herausforderung der Produktentwicklung.

Remote-Episode mit Flo von Codeship.io über Serverautomatisierung und UX
Unser Gast (00:00:00)

Florian Motlik
CTO und Co-Founder von https://codeship.io
Codeship ist ein Continuous Integration/Deployment Service
Ist 2011 als Neben-dem-Studium-Projekt gestartet
2012 dann die Entscheidung das ganze Vollzeit zu verfolgen: Studium hinschmeißen und alle ziehen nach Berlin
Nach Berlin dann 2013 nach Boston
Hauptsitz in Boston und ein Büro Wien
Wachsen erstmal "nur" vor Ort in Boston/Wien, Remote erst später; Ziel: gesunder Wachstum

Usability ist wichtig (00:05:45)

Usability war von Anfang im Fokus
Geführter Einstieg in das Produkt und Features
Noch vor der Anmeldung eines Nutzers sollen Screencasts und Blogposts Interessenten in die Thematik einführen
Bei Anmeldung weiß man dann schon im Grunde worum es geht und kann schneller starten

Tour durch Codeship.io (00:10:46)

Erster Schritt: Anmeldung über GitHub (https://github.com/) oder Bitbucket (https://bitbucket.org/)
Anschließend die Wahl des Repositories
Einrichtung der Test-Befehle, dazu gibt Templates für die unterschiedlichsten Sprachen und Umgebungen
Solange der Exit-Status eines Befehls 0 ist wird der nächste Schritt ausgeführt
Nach dem Testing kommt das Deployment
Auch hier lässt sich aus fertigen Anbindungen wählen, oder ein eigenes Skript wird verwendet
Das Deployment ist dabei eher als Pipeline zu verstehen:
Deploye erst auf Staging
Lasse dann gegen Staging einige Tests laufen
Deploye dann auf Produktion
Prüfe auch hier mit einem Skript
Am Ende des Tages kann Ablauf beliebig komplex oder sehr einfach sein, was immer gebraucht wird
Genauso wird im übrigen auch Codeship selbst getestet und deployed
"Eat your own dog food" ist vor allem für Developer-Produkte extrem wichtig

Infrastruktur (00:14:10)

Website läuft auf Heroku (https://www.heroku.com/home)
Sidekiq (http://sidekiq.org/) als Worker Queue mit externem Redis (https://openredis.com/)
Die interessanten Dinge passieren bei AWS (https://aws.amazon.com/): Die Ausführung der Jobs
Zu AWS ist man von Hetzner über Rackspace gekommen. Die Erklärung warum haben wir dann später leider vergessen zu erwähnen :/
AWS-Setup
Eigenes Auto-Scaling: Mehr Builds -> mehr Server
Die größten Compute-Instanzen (c3.8xlarge) als Basis, Unterteilung mit LXC (https://linuxcontainers.org/)
Ein Container mit einem vollständigen Ubuntu inkl. aller möglichen Abhängigkeiten
Learning 1: Container eignen sich besser als dedizierte kleine Maschinen, weil mehr Speicher und CPU
Learning 2: Einfach alles hochfahren treibt den Speicherverbrauch hoch, macht aber das Handling sehr viel leichter
Jeder Push auf das Repo erzeugt eine neue virtuelle Maschine auf der man im Grunde tun und lassen kann was man will
Es gibt aus Sicherheitsgründen kein sudo
Es lässt sich alles nach installieren was ohne sudo geht
Es sind die gängigen Sprachen in unzähligen Versionen enthalten + Haskell
Das gleiche gilt für Datenbanken
Support ist sehr wichtig
Ein Dienst für Developer fordert Developer als Support, daher muss jeder Entwickler auch einen Tag Support machen und zwar 7 Tage die Woche
Es gibt einen Cache-Layer (wo zum Beispiel auch Rubygems gecached werden) in den sich eigene Erzeugnisse ebenfalls cachen lassen

Build-Artefakte (00:20:50)

Keine Integration in Codeship: Build-Artefakte müssen per Skript woanders hinkopiert werden
Hintergrund: Nach jedem Build wird der Container vollständig zerstört
Deployment muss kein "Deployment" auf einen Server sein, sondern kann auch ein Script sein, welches z.B. Artefakte auf S3 kopiert
von Codeship vordefinierte Deployments sind vorgefertigte Abläufe, machen aber sonst nichts spezielles
im Wesentlichen gibt es keine Unterscheidung zwischen Setup, Test und Deploymentphasen: Es werden lediglich Kommandos ausgeführt
Im Environment werden alle möglichen Informationen exportiert
Ein spezieller Schutz für "geheime" Informationen (wie Access Keys) können aktuell noch nicht verschlüsselt in die Build-Umgebung gereicht werden

Private Installations (00:28:10)

Konkrete Pläne gibt es für On-Premise Installationen gibt es aktuell nicht
Codeship will sich nicht in Unternehmen rein verkaufen, sondern die Teams sollen Codeship haben wollen

Server in der EU und Datenschutz? (00:31:30)

Aktuell benutzt Codeship AWS EC2 Instanzen in us-east
Instanzen in der EU werden irgendwann wichtig sein (Datenschutzgesetz und auch Ausfallsicherheit)
Aber: Die Kunden haben aktuell ihren Code ohnehin auf Github oder Bitbucket, und deren Code liegt dann ohnehin nicht in der EU

Produktentwicklung & Fokus behalten (00:33:45)

Wie behält man den Fokus bei der Entwicklung?
Der Fokus war bei Codeship notwendig, weil Flo der einzige Entwickler war
Tech-only Start-Ups "bauen sich gerne in den Markt", was nicht funktioniert

Blogposts und Screencast (00:37:30)

20% der Entwicklerzeit geht in Marketing: z.B. Blogposts und Screencasts
Der Aufwand für einen Blogpost: 4-8 Stunden, wenn man nicht zu viel Research machen muss
...und bei Screencasts: Aufnahme 2-3 Stunden, Schneiden noch mal 1-1,5 Tage
Auch in den 20%: Meetups organisieren, Konferenzbesuche, User Groups...
Flo's Pro Tip: Sticker!!!

Hosting bei Heroku (00:42:40)

Codeship selber läuft auf Heroku mit 8 Add-Ons
Postgres: https://addons.heroku.com/heroku-postgresql#premium-ika
Logentries: https://addons.heroku.com/logentries
New Relic: https://addons.heroku.com/newrelic
New Relic Alternative: Skylight: https://www.skylight.io/

Pricing bei Codeship (00:49:15)

Codeship Preise: https://codeship.io/pricing
Kostenfrei (keine: 50 Builds, ein Concurrent Build
49 USD: ein Concurrent Build, sonst keine Limits
je 50 USD mehr, +1 Concurrent Build

AWS (00:51:50)

EC2 Reserved Instances: https://aws.amazon.com/ec2/purchasing-options/reserved-instances/
AWS Trusted Advisor: https://aws.amazon.com/premiumsupport/trustedadvisor/

Immutable Servers (00:54:40)

Server sind immutable
Server werden gebaut mit Packer (http://www.packer.io/)
Aus einer JSON Konfiguration und Skripten zur Provisionierung wird eine Amazon Machine Image (AMI) erstellt
Worklfow bei Codeship.io:
Code-Änderungen auf GitHub
Automatische Tests
Erstellung des AMI (Laufzeit ~ 90 Minuten)
Austausch eines AMI
Alte Server werden ausgemacht wenn keine Jobs mehr laufen
Scaling-System fährt nur noch neue Maschinen hoch
Wichtig: Laufende Server werden nicht mehr angefasst!
Vorteil:
Alle Server sind immer gleich
Server sind getestet bevor ein AMI überhaupt gebaut wird
Ziel bei der Automatisierung: Fokus der Entwickler auf die Entwicklung, alles nach dem Push muss automatisch geschehen

Automatisierung (01:00:56)

Weiteres wichtiges Tool ist Librato (https://metrics.librato.com/) zur Erfassung und Auswertung von sämtlichen Daten
Neben Betriebsdaten von Heroku und Amazon laufen dort auch Businessdaten rein
Alerts auf unterschiedlichen Ebenen
Wenn was ist, dann wird man benachrichtigt
Über Health-Checks werden sogar die Build-Server automatisch deaktiviert und neue Instanzen hochgefahren
Wenn alles automatisiert ist, dann können sich die Entwickler stärker auf ihre Arbeit konzentrieren
Keine dedizierte Ops-Abteilung, sondern gute Sys-Admins, die in die Entwicklungsabteilung und deren Prozesse integriert sind (aka: DevOps)
Am Ende haben alle Beteiligten (Frontend, Backend, Ops) den gleichen Workflow

Wie kommen auf die Jobs auf die Build-Server (01:05:00)

Auf jedem Build-Server läuft ein Sidekiq-Job
Die Web-App schiebt neue Jobs in die Queue
Die Build-Server schieben Ergebnisse zur Anzeige auf der Webseite auch wieder in eine Queue
Sidekiq-Pro kommt zum Einsatz

Provisionierung der LXC-Container (01:08:12)

Provisionierung via Bash
Aktuelles Projekt: Migration auf Ansible (http://www.ansible.com/home)
Ansible erscheint für die Anforderungen als die sinnvollste Lösung
Trotz LXC ist Docker (http://www.docker.com/) aktuell keine Alternative
Früher oder später werden sie auf Docker umstellen, da es sich als das Tooling für LXC entwickelt
Aktuell würde es aber mehr Arbeit machen als Benefit bringen

UX (01:12:59)

Die Komplexität liegt bei Codeship.io in der Feinabstimmung aller beteiligten Komponenten
Technisch ist es kein Hexenwerk
Wie bereits mehrfach angesprochen: UI/UX war und ist eine der großen Herausforderungen
Daher: Dedizierte Menschen, die sich um dieses Thema kümmern
Interviews mit Kunden
User-Tracking spielt auch eine wichtige Rolle
Kommunikation mit den Usern über Intercom (https://www.intercom.io/)
grundsätzlicher Support
Auf Basis von Metriken Identifikation von möglichen Problemen bei Kunden
In der UI werden unterschiedliche Fehler unterschieden: Bundle Install, Tests nicht gelaufen, etc
Matching der Fehlermeldung auf Reguläre Ausdrücke
Nicht nur die Fehlermeldung sondern entsprechender Hinweis auf die Fehlerursache
Next-Steps: Unterschiedliche Benachrichtigungen für unterschiedliche Fehlertypen