Eine Web-App von GitHub bereitstellen: Python, Node, Go, Java oder eine statische Website
Ein Programm zu schreiben ist eine Sache; es dort zum Laufen zu bringen, wo andere es öffnen können, eine andere, und es ist der Teil, den ein Klassenzimmer normalerweise gar nicht erreicht. Hier können Lernende aus einem öffentlichen GitHub-Repository bereitstellen, ohne Cloud-Konto und ohne Kreditkarte, und eine Lehrkraft kann eine bereitgestellte App als Abgabe einer Aufgabe verlangen.
Bereitgestellt werden können Python, Node, Go, Java und statische Websites aus HTML, CSS und JavaScript. Das Angebot dient dem Lernen und Vorführen, nicht dem Produktivbetrieb: lang genug, um es einer Lehrkraft zu zeigen, mit einigen Personen zu teilen oder als Link abzugeben, und bewusst nicht lang genug, um einen Dienst darauf zu betreiben.
Mit einem Beispiel beginnen
Auf der Seite „Bereitstellungen“ gibt es eine Beispiel-App: Datei-Uploads, in Node, Python, Go und Java, jeweils dieselbe App, damit Sie die Sprachen vergleichen können. Sie laden eine Datei hoch, sie landet in S3, und wohin sie gegangen ist, merkt sich Postgres. Klicken Sie auf „Dieses Beispiel bereitstellen“, und alles, was sie braucht, wird für Sie angelegt, eine Datenbank und ein Cloud-Stack, und die App geht bereits mit beiden verbunden online. Vorher ist nichts einzurichten, und es gibt keine Verbindungszeichenfolge zu kopieren. „Formular ausfüllen“ ist für den anderen Fall da: das Repository oder den Branch ändern, bevor sie online geht.
Es ist da, bevor sich jemand anmeldet, damit, wer überlegt, ob sich eine E-Mail-Adresse lohnt, zuerst eine echte App laufen sehen kann. Nichts wird für jemanden angelegt, bevor die Schaltfläche gedrückt wird, es kostet also niemanden etwas von der eigenen App-Zeit. Wer bereits eine Datenbank oder einen Cloud-Stack hat, bekommt diese statt einer zweiten.
Der Code ist öffentlich und lesenswert: Er ist kurz, und die README erklärt die drei Dinge, die Lernende zuerst falsch machen: S3 über den Pfad statt über den Hostnamen anzusprechen, den eigenen Bucket anzulegen, weil der Cloud-Stack leer startet, und die Datei vor der Zeile in der Datenbank nach S3 zu schreiben, damit ein Fehler nie eine Datei auf der Seite hinterlässt, die sich nicht öffnen lässt.
Wenn Sie es lieber nicht sehen möchten, klicken Sie in der Zeile auf „Ausblenden“, und es wird Ihnen nicht mehr angeboten.
Ausprobieren ohne Konto
Niemand braucht ein Konto, um es funktionieren zu sehen. Wer auf „Bereitstellen“ klickt oder in den Tabs „Datenbank“ oder „Cloud“ etwas erstellt, für den wird in diesem Browser ein temporäres Konto angelegt und angemeldet. Ein Gast hat eigene Grenzen, die ein System-Admin ändern kann: Sein Konto wird 24 Stunden nach der letzten Nutzung aufbewahrt, jede Bereitstellung läuft höchstens 30 Minuten, und er darf insgesamt 2 Bereitstellungen und 1 Datenbank anlegen, mit einem Cloud-Stack daneben, der nicht auf die Datenbank angerechnet wird.
Ein Gast kann niemanden einladen, eine App anzusehen, weil eine Einladung ein Link ist, den eine namentlich bekannte Person sendet, und kann kein privates Repository bereitstellen, weil ein Token, das zu einem Konto gespeichert ist, zu dem niemand zurückkehren kann, nie widerrufen werden könnte. „Dieses Konto behalten“ nimmt eine E-Mail-Adresse und einen Code und macht dasselbe Konto zu dem der Person, mit allem, was darin bereitgestellt wurde. Ein Gast, zu dem niemand zurückkehrt, wird mit seinen Apps, Datenbanken, Dateien und gespeicherten Container-Labs gelöscht.
Was sie angeben
Ein GitHub-Repository und einen Branch, die Sprache, einen Build-Befehl und einen Startbefehl. Das Formular enthält bereits etwas, das sich bereitstellen lässt: das letzte eigene Repository der lernenden Person oder, für jemanden, der noch nie bereitgestellt hat, eines von uns für die gewählte Sprache (hello-flask, hello-node, hello-go, hello-spring oder hello-static), sodass der erste Versuch ein funktionierender ist und der zweite der eigene. Das Wechseln der Sprache tauscht ein Beispiel gegen ein anderes und überschreibt nie, was getippt wurde.
Ein privates Repository funktioniert ebenfalls. Setzen Sie unter dem Repository-Feld das Häkchen bei „Dieses Repository ist privat“ und fügen Sie ein GitHub-Token ein: ein fein abgestuftes persönliches Zugriffstoken, auf dieses eine Repository beschränkt, nur lesend, mit Ablaufdatum. Es wird verschlüsselt gespeichert, niemandem je wieder angezeigt und nur verwendet, um den Code zu holen. Es erreicht nie die laufende App, sodass nichts, was die lernende Person bereitstellt, es lesen kann, und wer die Arbeit bewertet, baut die App damit, ohne es je zu sehen. Entfernen Sie das Häkchen, um es zurückzunehmen.
Einstellungen, die die App aus ihrer Umgebung liest, kommen in dasselbe Formular, als Zeilen aus Name und Wert, bis zu 20 davon und jeweils bis zu 4 KB. PORT und die eigenen Namen der Laufzeit werden abgelehnt. Sie werden verschlüsselt gespeichert und nach dem Speichern niemandem angezeigt: Die Seite zeigt Punkte, mit „Ersetzen“ und „Entfernen“. Eine Abgabe verweist auf die gespeicherte Bereitstellung, sodass, wer sie bewertet, die App mit den Variablen der lernenden Person bereitstellt und nur deren Namen sieht. Eine DATABASE_URL, die neben einer im Formular gewählten Datenbank eingetippt wird, wird abgelehnt, mit einem Satz, der sagt, welche zu entfernen ist.
Die App muss auf dem Port lauschen, der ihr zugewiesen wird. Das ist die eine echte Lektion der Übung und die, die jede Hosting-Plattform auf die harte Tour lehrt.
Zwei Häkchen im selben Formular geben ihr mehr Möglichkeiten: eine eigene Datenbank und einen Cloud-Stack mit einem Objektspeicher, einer NoSQL-Tabelle und einer Nachrichtenwarteschlange. Beide starten mit der App und setzen ihre eigenen Variablen, sodass eine Aufgabe eine App verlangen kann, die speichert, was Menschen hochladen, statt nur eine Seite zu zeichnen.

Welche Sprachen
Python, Node, Go, Java und statische Websites aus HTML, CSS und JavaScript, und keine anderen: Jede wird in einem Container für diese Sprache gebaut und ausgeführt, mit erreichbarer Paketregistry dieser Sprache und sonst nichts. Python läuft unter gunicorn, sodass Flask und Django beide funktionieren; Node ist, was sein Startskript ausführt; Go und Java werden aus dem Quellcode gebaut, Java als Spring-Boot-Anwendung; eine statische Website wird genau so ausgeliefert, wie sie im Repository liegt.
Für jede Sprache steht bereits ein funktionierendes Beispiel-Repository von uns im Formular, sodass, wer noch nie etwas bereitgestellt hat, einen Ausgangspunkt hat.
Eine statische Website ist die engste von allen: Sie installiert nichts, ihr Build erreicht also GitHub und keinen anderen Host. Ihr Build-Befehl prüft, ob oben im Repository eine index.html liegt, denn Seiten in docs/ oder dist/ würden sonst bereitgestellt und dann ein Verzeichnislisting liefern. Um einen Unterordner auszuliefern, fügen Sie dem Startbefehl --directory und seinen Namen hinzu, statt die Seiten zu verschieben.
Wo sie läuft und wer sie sehen kann
Jede App erhält unter learntools.dev eine eigene Adresse: zwei Wörter und eine Zahl oder einen Namen, den die lernende Person wählt und behält, sodass ein Link, den sie in einen Lebenslauf setzt, auch bei der nächsten Bereitstellung noch funktioniert. Eine gewählte Adresse bleibt ihre, bis sie sie löscht, und niemand sonst kann eine belegte nehmen.
Niemand erreicht eine App, indem er die Adresse errät. Die lernende Person lädt per E-Mail bis zu 5 Personen ein; jede folgt einem Link und bestätigt einen Code, der an dieselbe Adresse gesendet wird, sodass sich eine Einladung nicht weiterleiten lässt. Der eigene Zugang der lernenden Person steht auf ihrer Seite.
Mitarbeitende können eine stoppen. Ein System-Admin kann jede App, Datenbank oder jeden Cloud-Stack stoppen; alle Mitarbeitenden einer Einrichtung können eine stoppen, die zu einer lernenden Person dieser Einrichtung gehört, nicht nur der Einrichtungs-Admin, denn die Person, bei der eine Meldung ankommt, ist, wer unterrichtet. Zuvor haben nur die eigenen Zeitlimits je eine App gestoppt, was keine Antwort ist, wenn etwas sofort verschwinden muss.
Stoppen ist nur Stoppen. Die gespeicherten Daten bleiben, die Adresse bleibt, und die lernende Person kann sie wieder starten; jemandem die Arbeit wegzunehmen ist etwas anderes, und das kann niemand. Jedes Stoppen durch jemand anderen als die Person, der die App gehört, wird festgehalten, auf den Seiten unter „Bereitstellungen“, wo die lernende Person denselben Eintrag liest wie die Mitarbeitenden, und im Administrationsprotokoll der Einrichtung.
Wie lange sie läuft
Eine App läuft mindestens 1 Stunde und danach weiter, solange Platz ist, höchstens 4 Stunden; sie wird nach 30 Minuten ohne Besuch angehalten, und jedes Konto hat 8 Stunden App-Zeit pro Tag.
Das Angebot dient dem Lernen und Vorführen, nicht dem Produktivbetrieb: lang genug, um es einer Lehrkraft zu zeigen, mit einigen Personen zu teilen oder als Link abzugeben, und bewusst nicht lang genug, um einen Dienst darauf zu betreiben.
Die Seite sagt, was vom Tag übrig ist, bevor etwas bereitgestellt wird, zeigt die letzten Zeilen, die die App ausgegeben hat, während sie läuft, und bewahrt ihr Protokoll nach dem Stoppen drei Tage auf, genau dann, wenn man es am liebsten lesen möchte.
Nach ihrer garantierten Zeit läuft eine App weiter, solange niemand sonst den Platz braucht, und wird als Erste gestoppt, wenn jemand ihn braucht: Eine Bereitstellung, die auf eine volle Maschine trifft, stoppt die App, die am längsten läuft, und nur eine, die ihre Garantie bereits überschritten hat. Eine fünfte Zahl zählt Builds statt Minuten, standardmäßig 20 Bereitstellungen pro Tag, weil ein Build gleich viel kostet, wie lange die App danach lebt, und weil Lernende, die bei jedem Commit neu bereitstellen, eine Klasse in die Warteschlange bringen. Ein System-Admin legt all dies für die ganze Plattform und je Einrichtung fest.
Es läuft immer nur eine App. Solange die aktuelle nicht gestoppt ist, ist die Schaltfläche „Bereitstellen“ ausgeschaltet, und die Seite sagt, ob sie in der Warteschlange steht, mit wie vielen vor ihr, gebaut wird, läuft oder gerade stoppt. Eine App, die von selbst stoppt, wird mit ihrer eigenen letzten Ausgabe gemeldet, getrennt von einer, die sich nicht bauen ließ, sodass niemand wegen eines Fehlers im eigenen Programm durch ein Build-Protokoll geschickt wird. Die letzten zehn ausgegebenen Zeilen aktualisieren sich etwa einmal pro Minute, das ganze Protokoll lässt sich herunterladen, und frühere Bereitstellungen stehen in einer Tabelle mit Zeitpunkt, Sprache, Repository, Ausgang und Protokoll.
Eine Datenbank neben der App
Ein Tab „Datenbank“ neben „App“ unter „Bereitstellungen“ lässt Lernende bis zu drei eigene Datenbanken anlegen, jede bis zu 10 MB: PostgreSQL oder MySQL als Server oder SQLite als Datei. Wird eine im Bereitstellungsformular gewählt, startet der Server mit der App und setzt DATABASE_URL darauf, sodass der Code, den sie auf dem Laptop gegen SQLite geschrieben haben, hier dieselbe Variable liest; eine SQLite-Datei wird in die App gelegt und beim Stoppen der App zurückgespeichert.
Niemand wird nach einem Namen gefragt. Eine Datenbank erhält den Namen der Adresse, unter der die App der lernenden Person antwortet, mit einem Wort dafür, welche von beiden sie ist: Eine App unter sams-shop.learntools.dev erhält eine Datenbank namens sams_shop_db und einen Cloud-Stack namens sams-shop-cloud. Der Name einer Datenbank ist ein SQL-Name, daher werden die Bindestriche einer Adresse zu Unterstrichen, was jede Engine und jeder Treiber so annimmt, wie es ist. Ein Cloud-Stack behält seine Bindestriche, weil sein Name zum Namen eines Speicher-Buckets wird und diese keinen Unterstrich enthalten dürfen. Eine zweite Datenbank derselben Adresse zählt hoch, sams_shop_db_2; eine Adresse, die mit einer Ziffer beginnt, bekommt das Wort davor, db_2048_game; und wer noch nichts bereitgestellt hat, erhält db_1 oder cloud-1. Das Formular sagt, was es anlegen wird, bevor die Schaltfläche gedrückt wird.
Ein Server läuft genau so lange wie eine App, und seine Daten werden beim Stoppen gespeichert und beim Start zurückgespielt. Nur eine hier bereitgestellte App kann ihn erreichen; die Seite zeigt die Verbindungsdaten, damit Lernende lesen können, was die Variable bedeutet. Wer eine abgegebene App bewertet, erhält die Datenbank der lernenden Person mit deren Daten dazu und kann nicht ändern, was gespeichert ist.
Jede Datenbank hat „Starten“, „Beenden“, „Herunterladen“ und „Löschen“. Ein Server lässt sich für sich allein starten, und die gespeicherten Daten werden als .sql-Dump heruntergeladen oder, bei SQLite, als .sqlite-Datei, die die App in /data findet, nach der Datenbank benannt (etwa /data/sams_shop_db.sqlite), mit ihrem Pfad in DATABASE_PATH. Ein laufender Server hat eine Schaltfläche „Abfrage“, die dieselben Tabs „Abfrage“ und „Schema“ öffnet wie die SQL-Testumgebung, gegen die echte Datenbank und als eigene Rolle der lernenden Person; der Tab „Schema“ ist dort schreibgeschützt. „Löschen“ wird abgelehnt, solange die Datenbank läuft oder eine abgegebene Bereitstellung sie nennt, und eine nicht abgegebene Bereitstellung verliert sie einfach und wird ohne sie bereitgestellt. Bei der Grenze von 10 MB wird ein Server schreibgeschützt, und die Seite sagt, dass die letzten Änderungen nicht gespeichert wurden. Die Zugangsdaten werden erzeugt und nie gewählt, und das Passwort ist versiegelt: Die Seite zeigt URL, Host, Datenbank und Benutzer, und das Passwort auf Verlangen.
Eine Sitzung: die App, eine Datenbank, ein Cloud-Stack und ein Terminal
„Bereitstellungen“ ist ein Eintrag in der Leiste, mit Tabs für App, Datenbank und Cloud, und jeder Tab zeichnet oben dasselbe Bild der Sitzung der lernenden Person: ein privates Netzwerk mit der App, einer Datenbank, einem Cloud-Stack und einem Terminal, wobei jeder Platz sagt, was darin ist. Alles Laufende erreicht die anderen unter festen Namen, app, db und cloud, sodass die Konfiguration eines Tutorials unverändert funktioniert und nichts eine URL braucht.
„Terminal öffnen“ in einem der Tabs startet eine Shell neben der Sitzung, in der psql, mariadb, aws und curl bereits auf ihre Datenbank, ihren Cloud-Stack und ihre App zeigen. Es gibt ein Terminal pro Sitzung, und es zählt als Datenbankzeit. Sein Home-Ordner geht mit der Sitzung, es bleibt also, was die lernende Person in die Datenbank oder den Bucket gelegt hat.
Als Kursarbeit: eine bereitgestellte App abgeben
Eine Textaufgabe kann statt einer Datei eine bereitgestellte App verlangen. Die Aufgabenstellung bleibt Ihre wie gewohnt; was sich ändert, ist die Abgabe.
- Die Aufgabe stellen. Wählen Sie unter „Was abzugeben ist“ „Eine bereitgestellte App“ und dann, in welcher Sprache die Lernenden bereitstellen sollen.
- Die lernende Person stellt bereit. Ihre Aufgabenseite zeigt „Ihre App bereitstellen“, was die Bereitstellungsseite mit bereits gewählter Sprache öffnet. Sie stellt bereit, prüft, dass es funktioniert, und klickt auf „Abgeben“.
- Was abgegeben wird. Die ganze Bereitstellung: ihr Name und jede App darin mit dem Repository, dem Branch und den beiden Befehlen, mit denen diese App lief. Lernende mit einem Frontend und einer API geben eine Arbeit ab, nicht zwei. Sie wird wie jede andere Abgabe bei der Aufgabe aufbewahrt: bewertet, zur Überarbeitung zurückgegeben und versioniert.
- Bewerten, indem man sie ausführt. Öffnen Sie ihre Arbeit und klicken Sie auf „App bereitstellen“. Dieselbe App startet erneut unter einer eigenen Adresse, und das Hochfahren der Abgaben einer ganzen Klasse verbraucht nicht Ihr eigenes Tageskontingent an App-Zeit. Enthält die Bereitstellung mehrere Apps, ist jede mit einem eigenen Link aufgelistet, und sie starten nacheinander.
Eine Bereitstellung bewerten, und Grenzen für einen Wettbewerb
Eine Abgabe muss keine funktionierende Bereitstellung sein. Lernende, deren Build sich nicht bauen lässt, können trotzdem abgeben und das im Gespräch sagen; abgelehnt wird ein Repository oder ein Branch, den auch die Bereitstellungsseite ablehnen würde, sodass das Abgegebene zumindest etwas ist, das sich bauen ließe.
Wer bewertet, erhält kein Tageslimit für App-Zeit, und nur für die Arbeit, die bewertet wird: Fünfundzwanzig Abgaben hochzufahren würde das eigene Kontingent einer lernenden Person schon in den ersten paar erreichen, daher weichen die Tagesminuten und die Regel „eine auf einmal“, und die Seite sagt das. Die Sitzungsobergrenze weicht nicht, sodass eine zurückgelassene App trotzdem endet, und eine Lehrkraft, die eine eigene Idee bereitstellt, unterliegt wie alle anderen den üblichen Grenzen.
Eine Aufgabe kann eigene Grenzen setzen, wofür ein Wettbewerb oder eine Prüfung da ist. Ihr Tab „Einstellungen“ nimmt entgegen, wie viele Bereitstellungen sie erlaubt und wie lange jede App dann lebt. Sie werden innerhalb der eigenen Uhr dieser Aufgabe gezählt, sodass, wer später beginnt, sein eigenes Zeitfenster bekommt, und sie gelten für jede App, die diese lernende Person bereitstellt, solange die Uhr läuft, nicht nur für solche, die sie der Aufgabe zuordnet. Eine Aufgabe kann nur verkürzen, was die Einrichtung erlaubt.
Häufige Fragen
- Welche Sprachen lassen sich bereitstellen?
- Python, Node, Go, Java und statische Websites aus HTML, CSS und JavaScript. Die Build- und Startbefehle können Lernende innerhalb dieser Sprache bearbeiten, und ein Repository in etwas anderem lässt sich nicht bauen.
- Ist das ein Hosting-Dienst?
- Nein. Das Angebot dient dem Lernen und Vorführen, nicht dem Produktivbetrieb: lang genug, um es einer Lehrkraft zu zeigen, mit einigen Personen zu teilen oder als Link abzugeben, und bewusst nicht lang genug, um einen Dienst darauf zu betreiben. Eine App stoppt von selbst, und Lernende stellen sie wieder bereit, wann immer sie sie erneut brauchen, auf derselben Adresse, wenn sie eine gewählt haben.
- Kann die App eine Datenbank haben?
- Ja. PostgreSQL oder MySQL als Server, der neben der App läuft, oder SQLite als Datei, die in sie gelegt wird, jeweils bis zu 10 MB und drei pro lernender Person, angelegt im Tab „Datenbank“ und im Bereitstellungsformular gewählt, was DATABASE_URL setzt. Ein Server läuft so lange wie die App und behält seine Daten zwischen den Läufen. Er ist nur für eine hier bereitgestellte App erreichbar, nicht von einem Laptop aus.
- Kann man es ohne Konto ausprobieren?
- Ja. Ein Klick auf „Bereitstellen“ legt in diesem Browser ein temporäres Gastkonto mit eigenen Grenzen an, und „Dieses Konto behalten“ macht daraus mit einer E-Mail-Adresse und einem Code ein echtes und behält alles, was darin bereitgestellt wurde.
- Kann eine App Geheimnisse haben, etwa einen API-Schlüssel?
- Ja. Das Bereitstellungsformular nimmt bis zu 20 Zeilen aus Name und Wert entgegen, verschlüsselt gespeichert und nach dem Speichern nie wieder angezeigt. Sie erreichen die laufende App als Umgebungsvariablen, und eine Lehrkraft, die die Arbeit bewertet, sieht nur ihre Namen.
- Brauchen Lernende ein GitHub-Konto?
- Sie brauchen ein Repository, auf das sie zeigen können, und das ist selbst lehrreich: Versionsverwaltung und Bereitstellung sind dieselbe Lektion. Es kann öffentlich oder privat sein; ein privates wird bereitgestellt, indem man ein nur lesendes GitHub-Token einfügt, das verschlüsselt gespeichert und niemandem angezeigt wird.
- Können Lernende die Adresse wählen?
- Ja, unter „App erstellen“, wo sie die Arbeit benennen und die Adresse wählen, unter der sie antwortet: ein eigener Name aus Kleinbuchstaben, Ziffern und Bindestrichen, den niemand sonst belegt hat und der kein reserviertes Wort ist. Das Bereitstellungsformular darunter fragt nach keinem von beiden, die Entscheidung fällt also einmal. Die Adresse bleibt ihre, bis sie sie aus der Tabelle der gespeicherten Bereitstellungen unter dem Formular löschen, und genau dadurch kann jemand anderes sie bekommen.
- Kann eine lernende Person dieselbe App wieder starten, ohne das Formular erneut auszufüllen?
- Ja. Jede Zeile in der Tabelle der gespeicherten Bereitstellungen unter dem Formular hat „Erneut bereitstellen“, was genau dieses Repository, diesen Branch, diese Befehle und Variablen mit einem Klick auf derselben Adresse wieder online bringt. „Verwenden“ gibt es weiterhin für den anderen Fall, zuerst etwas zu ändern. Es fragt vorher nichts, weil „Beenden“ der Weg zurück ist; das Einzige, was es vorher sagt, ist, dass eine Bereitstellung ohne eigene Adresse auf einer neuen zurückkommt, ein alter Link also nicht mehr funktioniert. Eine für eine Aufgabe abgegebene Bereitstellung lässt sich auf diese Weise wieder online bringen und auf keine andere Weise ändern, was genau das ist, was hier schreibgeschützt bedeutet.
- Kann eine Einrichtung es abschalten?
- Nicht ausschalten, aber herunterdrehen. Ein System-Admin legt fünf Werte für die ganze Plattform und je Einrichtung fest: wie lange eine App garantiert läuft, wie lange höchstens, wie lange ohne Zuschauende, die Tagessumme und wie viele Bereitstellungen pro Tag, jeweils bis hinunter auf wenige Minuten oder eine einzige Bereitstellung.
- Was geschieht, wenn sie stoppt?
- Die App verschwindet, und ihr Protokoll bleibt drei Tage. Eine gewählte Adresse wird behalten, sodass eine erneute Bereitstellung die App wieder auf denselben Link bringt; eine zufällige nicht.
- Kann eine Lehrkraft die App einer lernenden Person herunternehmen?
- Ja. Alle Mitarbeitenden der Einrichtung können eine ihrer Lernenden stoppen, und ein System-Admin kann die von jedem stoppen, sodass eine Beschwerde über etwas, das Lernende online gestellt haben, jemanden hat, der noch am selben Tag handeln kann. Es stoppt die App, statt etwas zu löschen: Die Daten und die Adresse bleiben, und die lernende Person kann sie wieder starten. Sie sieht, wer sie gestoppt hat und wann, auf derselben Seite, von der aus sie bereitstellt.