Dokumentation

Vom Repository zum laufenden Dienst.

Drumlin baut Ihre Anwendung aus dem Quellcode und betreibt sie. Diese Seite genügt, um eine Anwendung bereitzustellen, ihr Zustand und eine Domain zu geben und zu wissen, wo man nachsieht, wenn man verstehen will, was sie tut. Alles hier Beschriebene ist über die Oberfläche, über die Kommandozeile und über dieselbe API erreichbar. Es ist ein Produkt mit drei Eingängen.

#Anwendung bereitstellen

Ein Dienst ist eine laufende Anwendung. Er gehört zu einer Umgebung innerhalb eines Projekts und wird entweder aus einem Git-Repository gebaut oder aus einem Container-Image, das Sie schon haben.

Aus einem Repository

Verbinden Sie einen Git-Anbieter mit Ihrer Organisation und legen Sie dann einen Dienst an, der auf ein Repository und einen Branch zeigt. Drumlin legt diesen Branch für jeden Build auf einen genauen Commit fest, eine Bereitstellung nennt also immer den Code, der gelaufen ist.

Ihr Repository braucht eine Dockerfile. Drumlin baut sie und schiebt das Ergebnis in die Registry der Plattform.

Aus einem Image, das Sie nicht gebaut haben

Ein Dienst braucht überhaupt kein Repository. Geben Sie ihm den Namen eines Images, und Drumlin betreibt es: vaultwarden/server, nginx, redis oder alles andere, das irgendwo veröffentlicht ist, wo Drumlin hinkommt. Die meiste selbst betriebene Software wird genau so verteilt, und sie hier zu betreiben sind dieselben drei Felder wie bei eigenem Code.

# all of these are accepted
vaultwarden/server
ghcr.io/example/tool:v2.3.1
registry.example.com/team/api@sha256:…

Ein Tag wird einmal auf das genaue Image festgelegt, auf das er zeigte, beim Anlegen des Dienstes oder wenn Sie erneut danach fragen. Was danach läuft, sind diese Bytes und nicht der Tag: wenn morgen jemand :latest neu veröffentlicht, ändert das nicht, was Ihr Dienst betreibt, und der Bereitstellungseintrag nennt den Digest; die Bezeichnung, unter der er ankam, kann sich seither verschoben haben.

Aktualisiert wird deshalb, wenn Sie es verlangen. Bitten Sie Drumlin, den Tag erneut aufzulösen, dann nimmt es, worauf er jetzt zeigt, als neues Release, von dem Sie wie von jedem anderen zurückgehen können.

Die Registry muss eine sein, die Drumlin ohne Zugangsdaten lesen kann. Docker Hub, die Registry von GitHub und die anderen öffentlichen sind das; eine Registry, die ein Passwort von Ihnen braucht, wird noch nicht unterstützt, und der Dienst sagt das beim Anlegen, statt zu warten und dann an einem Image zu scheitern, das er nicht holen kann.

#Releases und Rückschritt

Jeder erfolgreiche Build erzeugt ein Release: ein unveränderliches Image, per Digest festgenagelt, mit dem Commit und dem Build, die es hervorgebracht haben. Ein Dienst betreibt genau ein Release zur Zeit.

Weil ein Release unveränderlich ist, stellt Zurückgehen das alte Image erneut bereit und baut nichts:

$ drumlin releases api
$ drumlin rollback api 23

Skalieren ist von Bereitstellen getrennt. Die Anzahl der Kopien zu ändern baut nichts:

$ drumlin scale api --copies 3

#Datenbanken

Legen Sie in einem Projekt eine verwaltete PostgreSQL-Datenbank an und geben Sie einem Dienst Zugriff darauf. Der Zugriff gilt je Dienst: eine Datenbank ist nicht für alles im Projekt lesbar, nur weil sie dort liegt.

$ drumlin databases
$ drumlin databases url orders-db

Eine Datenbank läuft als einzelne Instanz, bei der Anlage dimensioniert. Sie wird laufend in einen Objektspeicher in einem anderen Rechenzentrum archiviert als dem, in dem sie läuft, und die Wiederherstellung auf einen Zeitpunkt liest diese Archive, nie etwas, das auf derselben Maschine wie die Datenbank liegt.

#Dauerhafte Volumes

Ein Volume ist Speicher, der einem Dienst an einem von Ihnen gewählten Pfad angehängt wird, und es überlebt Bereitstellungen: ein neues Release startet mit denselben Dateien, die das letzte hinterlassen hat. Die meisten Anwendungen brauchen keines, und was seinen Zustand in einer Datenbank hält, sollte keines nehmen, aber ein Medienspeicher, ein Suchindex oder ein selbst betriebenes Werkzeug mit eigenen Daten braucht eines.

Volumes werden zu einem Dienst angelegt und dort eingehängt, wo Sie es sagen. Ein Dienst mit Volume läuft als eine einzige Kopie, denn zwei Kopien, die auf einen Datenträger schreiben, sind keine Einstellung, die die Plattform aus Versehen zulässt.

Kopien, und eine zurückholen

Jedes Volume wird in einen Objektspeicher in einem anderen Rechenzentrum kopiert. Ein neu angelegtes Volume bekommt seine erste Kopie innerhalb von Sekunden und wartet nicht auf den nächsten geplanten Lauf. Danach werden die Kopien datiert und aufbewahrt.

Ein Volume können Sie selbst wiederherstellen, über die Oberfläche, ohne jemanden zu fragen: Volume wählen, Datum wählen, bestätigen. Der Dienst wird gestoppt, die Dateien durch diese Kopie ersetzt, der Dienst wieder gestartet. Das ist mit Absicht kein stiller Vorgang. Die Wiederherstellung erscheint im Aktivitätsprotokoll des Dienstes, und während sie läuft meldet sich der Dienst als wiederherstellend, damit ihn nichts als gesund anzeigt.

Eine Wiederherstellung ersetzt, was jetzt da ist. Putting a volume back to yesterday discards anything written since. The dashboard says which copy it is about to use and how large it is before it will let you continue, and a copy that holds nothing is refused outright, so it cannot be used to empty a volume that still has data in it.

#Variablen und Geheimnisse

Konfiguration gehört zu einem Dienst. Setzen Sie Variablen daran, dann stehen sie beim nächsten Start in der Umgebung jeder Instanz; markieren Sie eine als Geheimnis, wird sie mit einem Schlüssel verschlüsselt, den die Datenbank allein nicht entschlüsseln kann.

Ein Geheimnis lässt sich zurücklesen, und irgendwann werden Sie das brauchen. Jedes Lesen wird mit Person und Zeitpunkt in das Aktivitätsprotokoll der Organisation geschrieben. Das ist der Handel, den die Plattform eingeht: ein Geheimnis, das man zurücklesen kann, muss als lesbar behandelt werden, und das Protokoll macht das sichtbar.

Jeder Satz Variablen wird als Version aufbewahrt, eine Änderung, die etwas kaputt gemacht hat, ist also eine Änderung, die Sie sehen können. Einem Dienst Zugriff auf eine Datenbank zu geben schreibt deren Verbindungsangabe im gleichen Vorgang als Variable hinein, es gibt also keinen Schritt, in dem die Zugangsdaten existieren und der Dienst sie nicht erreicht.

#Was ein Image darf

Ein Container läuft in einer Sandbox mit eigener Kernelgrenze. Innerhalb dieser Grenze kann er tun, was ein gewöhnliches Image beim Start braucht: auf einem niedrigen Port lauschen, die Rechte seiner eigenen Dateien ändern und auf seinen eigenen Benutzer wechseln. Die offiziellen Images nginx, postgres und redis tun genau das und starten hier alle unverändert.

Was ein Container nicht kann, ist die Maschine darunter erreichen: ein Dateisystem einhängen, einen Geräteknoten anlegen, einen Raw-Socket öffnen, einen anderen Prozess beobachten, ein Kernelmodul laden. Ein Image, das eines davon braucht, war normalerweise dafür gebaut, eine ganze Maschine zu besitzen.

Wird etwas abgewiesen, nennt es die Diagnose des Dienstes, Sie müssen es also nicht aus einem Startprotokoll heraussuchen. Die Meldung sagt, dass die Plattform es abgewiesen hat, damit Sie nicht schlussfolgern, Ihr Image sei kaputt.

#Domains und TLS

Jeder Dienst hat vom Start an eine eigene Adresse, etwa api-7bvb32zq.apps.drumlin.cloud, und antwortet dort über HTTPS, ohne jede Einrichtung.

Für einen eigenen Hostnamen fügen Sie ihn dem Dienst hinzu und richten die Einträge, die Drumlin Ihnen zeigt, auf die Region. Sobald diese Einträge auflösen, wird das Zertifikat geholt und danach verlängert, solange die Domain angehängt bleibt. Die Verlängerung passiert bei uns, kein Zertifikat hier hat also ein Ablaufdatum, das Sie sich notieren müssten.

$ drumlin domains api
$ drumlin domains add api www.example.com

Bis die Einträge stimmen, wird die Domain als nicht bestätigt geführt und sagt, worauf sie wartet. Ein Zertifikat, das nicht ausgestellt werden kann, wird genau als das gemeldet, und der Dienst gilt deshalb nicht als kaputt.

Die Drumlin-Adresse abschalten

Sobald Ihre eigene Domain antwortet, wollen Sie meist, dass die erzeugte aufhört. Zwei Eingänge zur gleichen Anwendung sind normalerweise nicht gemeint: eine Suchmaschine kann den zweiten aufnehmen, ein Cookie oder eine Weiterleitung für den einen Hostnamen verhält sich auf dem anderen falsch, und eine Testumgebung, die jemand für privat hielt, ist für jeden erreichbar, der acht Zeichen errät.

Es ist deshalb ein Schalter auf der Domain-Seite des Dienstes. Schalten Sie ihn aus, hört der Name innerhalb einer Minute auf zu antworten; schalten Sie ihn wieder ein, kommt dieselbe Adresse zurück und keine neue, alles, wo Sie sie eingefügt hatten, funktioniert also weiter.

Ohne eigene Domain nimmt das Abschalten den Dienst vollständig vom Netz. That is allowed on purpose: an API that only the rest of its environment talks to has no business having a public address. Nothing stops running and nothing is deleted, and the other services in the same environment go on reaching it by name. The dashboard asks before doing it.

#Dienste, die miteinander sprechen

In einem Repository steckt oft mehr als eine lauffähige Sache, ein Frontend und die API, die es aufruft. Legen Sie je Sache einen Drumlin-Dienst an, alle in derselben Umgebung, und richten Sie jeden auf sein eigenes Verzeichnis und seine eigene Dockerfile.

Jeder Dienst ist dann von den anderen über seinen eigenen Namen erreichbar, auf Port 80, unabhängig davon, auf welchem Port die Anwendung selbst lauscht. Ein Frontend, das an einen Dienst namens notifier weiterleitet, nutzt:

proxy_pass http://notifier;

Port 80, nicht der eigene Port der Anwendung. Drumlin stellt innerhalb der Umgebung jeden Dienst hinter denselben Port, ein als notifier:3001 geschriebenes Ziel verbindet sich also nicht, auch wenn der Name auflöst.

Nur Dienste in derselben Umgebung erreichen sich. Produktion kann nicht mit der Testumgebung sprechen, und kein anderer Kunde erreicht eine von beiden. Diese Grenze wird im Netzwerk erzwungen, nicht durch eine Konfiguration.

#Protokolle und Messwerte

Protokolle und Messwerte gehören zum Dienst. Es gibt keinen Agenten zu installieren und kein zweites Konto anzulegen.

$ drumlin logs api
$ drumlin logs api --build 01M1V4…

#Konsole

Wenn Protokolle lesen nicht reicht, öffnen Sie eine Shell in einer laufenden Instanz:

$ drumlin shell api

Eine Konsolensitzung ist authentifiziert, einmalig und läuft ab. Sie wird im Aktivitätsprotokoll beim Dienst festgehalten, neben den Bereitstellungen. Eine Shell ist das Eingriffsstärkste, was die Plattform kann, also ist sie dort sichtbar, wo jemand danach suchen würde.

#Personen und Rollen

Eine Organisation ist das, was Projekte, Dienste und die Rechnung besitzt. Laden Sie Personen per E-Mail-Adresse dazu ein und geben Sie jeder eine Rolle: Eigentümer, Mit-Eigentümer, Administrator, Entwickler oder Betrachter. Eine Rolle kann je Projekt weiter eingeengt werden, wer an einer Anwendung arbeitet, bekommt also nicht den ganzen Rest dazu.

Genau eine Person ist Eigentümer. Die Eigentümerschaft geht in einem Schritt von einem Konto auf ein anderes über, es gibt also keinen Weg zu zwei Eigentümern oder zu keinem.

Das Aktivitätsprotokoll

Alles, was irgendwer getan hat, steht im Protokoll der Organisation: Bereitstellungen, Skalierungen, offengelegte Variablen, eingeladene und entfernte Personen, angelegte und wiederhergestellte Datenbanken. Es wird nur angefügt, und die Datenbank selbst erzwingt das, kein Codeweg kann also einen Eintrag umschreiben.

Das gilt auch für uns. Wenn unser Personal Ihre Organisation ansieht oder darin handelt, erscheint der Eintrag in Ihrem Protokoll und nennt, was getan wurde, ohne dass Sie danach fragen müssen und ohne dass wir ihn entfernen könnten.

#Abrechnung

Drumlin sieht zu jeder volle Stunde nach, was Ihr Konto belegt, bepreist es und notiert den Messwert. Zu Beginn jedes Monats werden aus diesen Messwerten eine Rechnung für den abgelaufenen Monat.

Rechenleistung zählt nur, solange ein Dienst läuft, etwas zu stoppen beendet seine Kosten also zur nächsten Stunde. Speicherplatz zählt in jedem Fall, denn ein Datenträger hält seine Bytes so oder so.

Was es kostet

Processor€0.012per core-hour
Memory€0.006per GiB-hour
Disk€0.00015per GiB-hour, for databases and volumes

Es gibt keine Plattformgebühr, keinen Preis pro Person und kein Guthaben zum Vorauskauf. Ein Viertelkern und ein halbes Gibibyte, die Vorgabe für einen Dienst, kosten 4,38 € im Monat. Derselbe Dienst mit einer Datenbank von zehn Gibibyte daneben kostet 9,86 €.

Der Monat, während er läuft

Die Abrechnungsseite zeigt genau, was der laufende Monat bisher gekostet hat, und eine Schätzung, wo er landet, wenn sich nichts ändert. Die beiden sind mit Absicht unterschiedlich benannt: das eine ist eine Messung, das andere eine Fortschreibung der letzten Stunde.

Jeder stündliche Messwert liegt dahinter. Jede Zahl auf einer Rechnung lässt sich zu den Stunden zurückverfolgen, aus denen sie entstand, und genau dafür werden sie aufbewahrt.

Bezahlen

Eine Rechnung wird zu Beginn des Monats für den Vormonat ausgestellt und ist innerhalb von vierzehn Tagen per Überweisung oder Karte zahlbar. Die Umsatzsteuer richtet sich danach, wo Sie sind: deutsche Umsatzsteuer für deutsche Kunden, keine für Unternehmen anderswo in der EU mit einer USt-IdNr., die wir gegen das Register der Europäischen Kommission bestätigt haben, und keine außerhalb der Union.

Eine offene Rechnung bekommt eine Mahnung. Zehn Tage danach stoppen die Dienste des Kontos. Ihre Daten bleiben unberührt, und alles startet innerhalb von Minuten nach dem Ausgleich der Rechnung wieder. Ein darüber hinausgehendes Mahnverfahren gibt es nicht.

Ein Konto braucht Rechnungsangaben, bevor es etwas Kostenpflichtiges betreiben kann. An invoice has to carry a name, an address and a country, and the country is what decides the tax. We ask for them before the first service, because asking after a month of usage means asking somebody to volunteer an address for work already done.

#API und Webhooks

Alles, was die Oberfläche tut, tut die API. Es ist dieselbe API, und die Kommandozeile ist einer ihrer Clients. Stellen Sie ein Token für Ihre Continuous Integration aus, dann kann es bereitstellen, skalieren, Protokolle lesen und alles andere, was die vergebene Rolle erlaubt.

Ein Token gehört zu einer Organisation und trägt eine Rolle, ein Token für eine Bereitstellungskette muss also keine Personen entfernen können. Tokens werden mit ihrer letzten Nutzung aufgelistet, und ein Widerruf wirkt sofort.

Webhooks

Registrieren Sie einen Webhook, dann schickt Drumlin eine Anfrage an Ihren eigenen Endpunkt, wenn etwas passiert: eine Bereitstellung gelang oder scheiterte, ein Build scheiterte, ein Dienst wurde ungesund, eine Domain wurde bestätigt, ein Zertifikat konnte nicht ausgestellt werden. Jede Zustellung ist signiert, und jeder Versuch wird mit der erhaltenen Antwort festgehalten, ein Webhook, der nicht ankommt, hinterlässt also einen lesbaren Eintrag.

E-Mail-Benachrichtigungen deckeln dieselben Ereignisse ab, und welche davon Sie erreichen, wählen Sie je Organisation selbst.

Ihr eigenes Konto

Zwei-Faktor-Anmeldung gibt es mit einer Authenticator-App, samt Wiederherstellungscodes für den Tag, an dem das Telefon weg ist. Sie sehen jede offene Sitzung Ihres Kontos, können jede einzelne beenden und alle auf einmal. Sie können das Konto auch selbst schließen und seine Daten löschen lassen, ohne jemandem zu schreiben.

#Kommandozeile

Die Kommandozeile sprichtmit derselben API wie die Oberfläche und gibt dieselben Meldungen zurück.

$ drumlin login
$ drumlin use acme/storefront
$ drumlin services

$ drumlin deploy api --wait
Build 24 of api, from acme/storefront at 7b21d9a.
  Fetching the repository
  Building the image
  Pushing the image
Built in 18s.

Weitere Befehle, nach denen Sie greifen werden: services show, start, stop, scale, domains, databases url, shell, use und whoami. Jeder davon nimmt --json, wenn Sie es lieber auswerten als lesen.

#Regionen

Dienste laufen in NL01, Netherlands 1, der heute einzigen Region. Sie gehört uns und wird von uns betrieben. Weitere Regionen werden aufgeführt, wenn es sie gibt.

Something missing from this page? It covers the paths most people need first. The dashboard describes each screen as you use it, and the CLI's --help is generated from the same definitions as the API.