In diesem Kapitel beschäftigen wir uns nun endlich mit der Veröffentlichung unserer Anwendung. Wir werden dazu den Dienst Heroku verwenden, da dieser ein kostenloses Kontingent bereitstellt und hierfür auch keine Kreditkarte hinterlegt werden muss. Die größte Einschränkung ist jedoch, dass unsere Instanz nach 30 Minuten ohne Aktivität in einen Ruhezustand geht. Bei der nächsten Anfrage muss sie deshalb erst neu starten und braucht deshalb einige Sekunden länger für eine Antwort. Heroku ist aber natürlich nicht der einzige Anbieter. Einige kostenlose Alternativen sind unter Free Cloud Computing aufgeführt und abhängig vom Anwendungsfall können auch kostenpflichtige Angebote die bessere Wahl sein.

Wie schon im vorherigen Kapitel erwähnt, unterstützt Heroku sowohl ein Deployment mit Git als auch mit Docker. Abhängig davon, ob das eigene Projekt ebenfalls mit Heroku realisiert werden soll bzw. ob das letzte Kapitel übersprungen wurde, kann in diesem Kapitel eine der beiden Möglichkeiten gewählt werden. Da wir in diesem Tutorial für beide Fälle Heroku nutzen, ist der erste Abschnitt jedoch auch für beide Fälle relevant.

Dieses Kapitel ist leicht veraltet, da Heroko keine einfache kostenlose Umgebung mehr anbietet. Für manche Use Cases ist Heroku dennoch praktisch, insbesondere für größere Projekte sollte man sich jedoch mit alternativen Anbietern beschäftigen!

Heroku Vorbereitung

Cloud Application Platform | Heroku

Um Heroku nutzen zu können, muss auf der Webseite zuerst ein Account angelegt werden. Dabei müssen einige Daten angegeben werden, Kreditkarten-Information sind nicht zwingend erforderlich. Allerdings kann das kostenlose Kontingent durch die Angabe einer Kreditkarte erhöht werden. Angemeldet, kann man auf der Webseite alle seine Apps überblicken und verwalten.

Um eine neue App zu erstellen, müssen wir jedoch auch noch das Heroku CLI installieren. Dieses ist für macOS, Windows sowie Linux verfügbar und kann hier heruntergeladen werden. Dort finden sich auch Installationsanleitungen für alle Betriebssysteme. Ob die Installation erfolgreich war, kann anschließend mit heroku --version überprüft werden.

Ist dies der Fall, können wir uns mit unserem zuvor erstellten Account einloggen, indem wir den folgenden Befehl aufrufen:

heroku login

Die Anmeldung selbst erfolgt dann in dem daraufhin geöffneten Browserfenster.

A. Deployment mit Git

Wir können mit Heroku Apps direkt aus einem Git Repository heraus deployen. Standardmäßig wird dazu der Stand aus dem main (oder master) Branch verwendet, wir können allerdings auch explizit einen anderen Branch wählen. Da Heroku den gesamten aktuellen Commit hochlädt, bereiten wir zunächst einen Branch deploy entsprechend vor. Unsere Trainings- und Test-Skripte werden nicht mehr benötigt, dafür brauchen wir jedoch zusätzlich die Modelle und eine requirements.txt, damit Heroku alle benötigten Abhängigkeiten installieren kann. Falls du unsicher bist, wie diese aussehen soll, findest du im vorherigen Kapitel einen Abschnitt dazu (siehe hier). Es gibt hierbei zwei Besonderheiten zu beachten: Zum einen muss gunicorn als Webserver mit aufgenommen werden und zum anderen sollte das Package tensorflow durch tensorflow-cpu ersetzt werden. Da unser Projekt bei Heroku in der Größe limitiert ist und uns ohnehin keine GPU zur Verfügung steht, können wir so Platz sparen ohne Performanceeinbußen fürchten zu müssen.

Haben wir alles erledigt und unsere Änderungen committed, können wir damit beginnen eine neue Heroku App zu erstellen:

heroku create

Diese App taucht sofort in unserer Heroku Weboberfläche auf. Mit git remote -v sehen wir zudem, dass unserem Git Repository ein neues Remote Repository mit dem Namen heroku hinzugefügt wurde. Auf dieses können wir nun einfach unseren aktuellen Stand wie gewohnt mit Git pushen. Wenn wir nicht den aktuellen Stand des main Branches pushen wollen, müssen wir unseren Branch Namen explizit angeben:

git push heroku deploy:main

Wir können nun verfolgen, wie Heroku die Packages aus unserer requirements.txt Datei installiert. Sobald der Prozess abgeschlossen ist, können wir versuchen auf unsere Seite zuzugreifen. Der entsprechende Link wurde uns bei der Erstellung unserer App mitgeteilt und ist auch in der Weboberfläche zu finden. Dort können wir ebenfalls den Status unseres Builds verfolgen.

Wenn wir den Link aufrufen, wird uns allerdings eine Fehlermeldung von Heroku angezeigt. Bisher haben wir nämlich nicht definiert, was Heroku überhaupt ausführen soll. Dafür legen wir im Root-Verzeichnis eine neue Datei Procfile an. In welcher wir einen Befehl zum Starten unseres Servers hinterlegen. Außerdem müssen wir angeben welche Art von Prozess wir benötigen. In unserem Fall ist es web, da wir Anfragen aus dem Internet empfangen wollen. Unser Procfile sieht dann so aus:

web: gunicorn app:app

Da uns Heroku die Auswahl eines Ports ohnehin nicht erlaubt, können wir das bind Argument weglassen. Das Procfile muss mit in des Git Repository aufgenommen und anschließende der aktuelle Stand in des Heroku Remote Repository gepusht werden.

Damit unsere App erreichbar wird, müssen wir nun nur noch einen sogenannten Dyno starten. So werden bei Heroku die Container genannt, in denen die Anwendungen ausgeführt werden. Für ihren Betrieb verbrauchen diese Dyno Hours. Jeden Monat erhält man davon ein kostenloses Kontingent. In der Weboberfläche oder mit heroku ps lässt sich sein verbleibendes Kontingent prüfen. Für unsere App starten wir nun einen Dyno des Typs web:

heroku ps:scale web=1

Sobald dieser erfolgreich gestartet ist, erreichen wir unsere App im Internet. Die URL ist analog zu unseren vorherigen lokalen Versuchen aufgebaut: https://app-name-12345.herokuapp.com/api/car-price?model=.... Unseren Dyno können wir auch in der Weboberfläche betrachten.

Mit dem Befehl heroku ps:scale web=0 können wir ihn wieder ausschalten. Da unsere App im kostenlosen Tarif nach 30 Minuten Inaktivität in einen Ruhezustand übergeht und während dieser Zeit keine Dyno Hours verbraucht, ist es jedoch nicht notwendig den Dyno manuell auszuschalten, um Dyno Hours zu sparen.

B. Deployment mit Docker

In diesem Abschnitt wird ein alternatives Vorgehen vorgestellt, der vorherige Abschnitt ist zum Verständnis deshalb nicht zwingend erforderlich. Falls du zu einzelnen Heroku-eigenen Begriffen mehr erfahren möchtest, findest du dort ausführlichere Erläuterungen.

Alternativ können wir unsere App mit Docker deployen. Dieses Vorgehen lässt sich einfacher auf viele andere Provider übertragen, wobei uns Heroku auch bei dieser Variante mit einigen Befehlen unterstüzt. Zunächst müssen wir wieder bei Heroku eingeloggt sein (siehe hier). Wie wir bereits im letzten Kapitel erfahren haben, werden Docker Images in Registries verwaltet. Auch Heroku bietet eine solche Registry an. Bei dieser müssen wir uns ebenfalls anmelden:

heroku container:login

Anschließend können wir wieder eine neue Heroku App anlegen, welche direkt im Dashboard auf der Webseite erscheint:

heroku create



Da Heroku die Auswahl eines Ports nicht erlaubt, müssen wir den `CMD`-Befehl in unserem Dockerfile nochmal anpassen. Statt `CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]` reicht nun der Befehl `CMD ["gunicorn", "app:app"]`.


Wenn unser aktueller Ordner ein Dockerfile enthält, können wir mit nur einem einzigen Befehl unser Docker Image bauen und dieses in die Heroku Registry pushen. Dabei geben wir sofort auch unseren gewünschten Dyno Typ web an, da wir Anfragen aus dem Internet empfangen wollen:

heroku container:push web

Das Image wird lokal gebaut und anschließend hochgeladen. Aufgrund der Layer braucht dieser Prozess bei einer zweiten Ausführung nach einer Änderung deutlich weniger Zeit als beim ersten Mal. Da das Image lokal gebaut wird, musst du Docker installiert haben und kannst es anschließend mit docker image ls sehen. Falls du das Docker Image bereits gebaut hast, kannst du dieses auch direkt mit Docker in die Heroku Registry pushen. Damit Docker weiß in welche Registry das Image gepusht werden soll, musst du vorher jedoch einen entsprechenden Tag vergeben. Die beiden Befehle, wenn du bereits ein Docker Image besitzt, lauten also folgendermaßen:

docker tag <image> registry.heroku.com/<app>/web
docker push registry.heroku.com/<app>/web

Hier musst du nur noch die ID des existierenden Images (<image>) und den Namen deiner Heroku App (<app>) angeben.

Nachdem das Image vollständig erzeugt und gepusht ist, können wir es nun veröffentlichen. Der entsprechende Befehl lautet:

heroku container:release web

Damit wird ein Dyno des Typs web angelegt und unsere App veröffentlicht. Ein entsprechendes Statusupdate erscheint wieder im Dashboard auf der Heroku Webseite. Mit dem Befehl heroku ps können wir auch direkt in der Kommandozeile den Status unseres Dynos abfragen und erhalten eine Übersicht über unsere verbleibenden kostenlosen Dyno Hours.

Wir können unsere App nun im Internet erreichen. Die URL ist analog zu unseren vorherigen lokalen Versuchen aufgebaut: https://app-name-12345.herokuapp.com/api/car-price?model=.... Außerdem können wir uns mit heroku open auch direkt ein Browserfenster zu unserer App öffnen lassen, dort müssen wir nur noch unseren individuellen API-Aufruf ergänzen.

  • Keine Stichwörter