Zurück zum Blog

Erstellen und Bereitstellen einer Flask-Anwendung mit Docker auf Ubuntu 20.04

Erstellen und Bereitstellen einer Flask-Anwendung mit Docker auf Ubuntu 20.04

Einführung

Docker ist eine Open-Source-Container-Plattform. Es handelt sich um eine leichtgewichtige, virtualisierte, portable, softwaredefinierte standardisierte Umgebung, die es der Software ermöglicht, isoliert von anderer Software auf dem physischen Host-Rechner zu laufen. Docker bietet eine leichtgewichtige Alternative zu virtuellen Maschinen. Gleichzeitig bietet es Portabilität, Leistung, Agilität und Skalierbarkeit von Anwendungen. Für einen umfassenden Leitfaden über das Docker-Ökosystem werfen Sie einen Blick auf unsere detaillierte Übersicht über die Containerisierung mit Docker.

Flask ist ein minimales Open-Source-Web-Framework, das mit Python erstellt wurde. Einige der großartigen Funktionen von Flask sind, dass es leichtgewichtig, flexibel und hochgradig strukturiert ist. Darüber hinaus benötigt es keine speziellen Tools oder Plug-ins, um ausgeführt zu werden.

Die Kombination von Flask und Docker bietet Ihnen eine leichtgewichtige, flexible und skalierbare Anwendung. Dank der portablen Natur von Docker-Containern können Sie sie über viele Server und Infrastrukturen hinweg bereitstellen. Der Schwerpunkt dieses Tutorials liegt darin, Ihnen zu zeigen, wie Sie eine Flask-Anwendung mit Docker bereitstellen. Wir werden auch demonstrieren, wie Sie sicherstellen, dass zukünftige Updates Ihrer Anwendung wirksam werden.

Voraussetzungen

Dies wird ein praktisches Tutorial sein, und Sie sollten eine Umgebung erstellen, die es Ihnen ermöglicht, den Schritten zu folgen:

Jetzt fangen wir an!

Schritt 1: Vorbereiten der Flask-Anwendung

Wir beginnen mit dem Erstellen eines Verzeichnisses, das unsere Flask-Anwendung enthalten wird. Sie können einen Verzeichnisnamen Ihrer Wahl wählen. Für dieses Tutorial nennen wir es jedoch flask_demo. Wir werden die Projektdateien im Verzeichnis /var/www speichern, welches normalerweise das Verzeichnis ist, über das Ubuntu standardmäßig den Zugriff auf das öffentliche Internet erlaubt. Führen Sie zuerst die folgenden Befehle aus, um das Verzeichnis zu erstellen und dorthin zu navigieren:

Innerhalb dieses Stammverzeichnisses unseres Projekts werden wir die Basisordnerstruktur einer Flask-Anwendung erstellen. Führen Sie als Nächstes den folgenden Befehl aus, um die Basisstruktur zu erstellen, und fügen Sie das Flag -p hinzu, um alle übergeordneten Ordner auf dem Weg zu erstellen:

Der Ordner „app“ enthält alle Dateien, die sich auf eine Flask-App beziehen, einschließlich views und blueprints. Views enthalten den Code, den Sie schreiben, um auf Anfragen zu antworten, die Ihre Anwendung erreichen. Blueprints helfen bei der Erstellung von Anwendungskomponenten und unterstützen gängige Muster in Flask-Anwendungen.

Der treffend benannte static-Ordner enthält statische Assets wie Bilder, CSS- und JavaScript-Dateien. Das Verzeichnis templates enthält alle HTML-Templates für das Projekt.

Jetzt können wir mit dem Schreiben der Dateien beginnen, die zur Initialisierung einer Flask-Anwendung benötigt werden. Beginnen Sie mit dem Erstellen einer Datei namens __init__.py im Verzeichnis „app“, um dem Python-Interpreter mitzuteilen, dass das Verzeichnis „app“ als Paket behandelt werden soll. Führen Sie den folgenden Befehl in Ihrem Terminal aus, um die Datei mit dem Nano-Editor zu öffnen:

Wir verwenden Pakete in Python, um Module in logische Namensräume oder Hierarchien zu gruppieren. Die Modularisierung ermöglicht es, Code in einzelne und überschaubare Blöcke aufzuteilen, die bestimmte Funktionen ausführen.

Danach fügen Sie in der in Ihrem Editor geöffneten Datei __init__.py das folgende Code-Snippet hinzu, um die Flask-Instanz zu starten und die Logik aus der Datei views.py zu importieren, die Sie in den nächsten Schritten erstellen werden:

Wenn Sie fertig sind, drücken Sie Strg + O und EINGABE um die Datei zu speichern, und schließen Sie sie dann mit Strg + X. Als Nächstes erstellen wir die views.py im app-Verzeichnis. Die Datei views.py enthält den Großteil der Anwendungslogik:

Fügen Sie in der Datei das folgende Code-Snippet hinzu. Dieser Code zeigt eine einfache Zeichenfolge an, um zu signalisieren, dass Ihre App läuft, wenn Benutzer Ihre Website besuchen:

In dieser Datei importieren wir zunächst die Flask-App-Instanz. Dann müssen wir eine Zeile hinzufügen, um die Route zu definieren: @app.route(/). Die Zeile @app.route(/) wird in Flask als ein Decorator bezeichnet. Sie können Decorators verwenden, um zusätzliche Funktionalitäten in eine oder mehrere Funktionen einzufügen. In diesem Fall übergeben wir einen Aufruf an die Route / an die home-Funktion. Wenn ein Benutzer diese Route besucht, sieht er den Text: "Unsere Flask-Anwendung läuft!".

Als Nächstes erstellen Sie die Datei uwsgi.ini , um die uWSGI-Konfigurationen für die Anwendung zu speichern. uWSGI ist eine Bereitstellungsoption für Nginx, die als Protokoll und Anwendungsserver dient. Führen Sie den folgenden Befehl aus, um die Datei im Stammverzeichnis des Projekts mit dem Nano-Editor zu erstellen:

Fügen Sie in der geöffneten Datei das folgende Code-Snippet hinzu:

Diese Datei enthält einige Direktiven. Wir definieren deren Zweck unten:

  • module – definiert das Modul, aus dem die Flask-Anwendung bereitgestellt wird. Wir haben das Modul auf main gesetzt, was sich auf die Datei main.py im Stammverzeichnis bezieht. Wir werden diese Datei im nächsten Schritt erstellen.
  • callable – weist uWSGI an, die aus der Anwendung exportierte app -Instanz zu verwenden.
  • master – stellt sicher, dass die Anwendung weiterläuft, um Ausfallzeiten beim Neuladen der gesamten Anwendung zu minimieren.

Speichern und schließen Sie die Datei, wenn Sie fertig sind.

Jetzt können Sie die Datei main.py erstellen, um den Einstiegspunkt für Ihre Anwendung festzulegen. uWSGI liest diese Datei, um zu wissen, wie es mit der Anwendung interagieren soll. Führen Sie den folgenden Befehl aus, um die Datei main.py -Datei mit nano im root Verzeichnis Ihres Projekts zu erstellen:

Fügen Sie in der Datei die folgende Zeile hinzu, die die im Anwendungspaket erstellte Flask-Instanz importiert:

Als Letztes definieren Sie in diesem Schritt die für die Ausführung der Anwendung erforderlichen Abhängigkeiten. Wir definieren diese Abhängigkeiten in einer Datei namens dependencies.txt. Wenn Docker das Image Ihrer Anwendung erstellt, führt es einen pip (-Paket manager)-Befehl aus, um die Abhängigkeiten zu installieren. Öffnen Sie die Datei im Stammverzeichnis mit dem folgenden Befehl:

Bis zu diesem Punkt in unserem Projekt wollen wir nur eine Abhängigkeit: Flask. Daher können wir die folgende Zeile hinzufügen, um auf die richtige Flask-Version zu verweisen, die wir für unser Projekt wünschen:

Wir entscheiden uns für Flask Version 2.0.1 als Abhängigkeit. Dies ist die neueste Version zum Zeitpunkt der Erstellung dieses Tutorials. Mehr über die verschiedenen Versionen erfahren Sie auf der Seite Flask Changes. Damit ist die Einrichtung der Flask-Anwendung abgeschlossen. Bereiten wir nun die Docker-Konfigurationen für die Bereitstellung vor.

Step 2: Configure Docker

Um eine Docker-Bereitstellung einzurichten, erstellen wir zwei Dateien: Dockerfile und start.sh. Das Dockerfile enthält deklarative Zeilen, die ein Docker-Image bilden. Die Datei start.sh ist ein einfaches Shell-Skript, um das Image zu erstellen und den Container aus dem Dockerfile zu starten. Führen Sie im Stammverzeichnis des Projekts den folgenden Befehl aus, um das Dockerfile zu erstellen:

Diese Datei enthält die erforderlichen Konfigurationen für ein Docker-Image. Fügen Sie als Nächstes das folgende Code-Snippet hinzu, um die Abhängigkeiten und die Erstellung des Images anzugeben:

Die erste Zeile in einer Dockerfile definiert das Basis-Image, auf dem wir unser Image aufbauen. In diesem Fall bauen wir auf Basis des tiangolo/uwsgi-nginx-flask, verfügbar von DockerHub. Wir haben dieses spezielle Image gewählt, da es viele Python-Versionen unterstützt.

Wir geben auch an, dass wir das Image aktualisieren möchten. Dann müssen wir den bash-Befehlsprozessor , den nano-Texteditor, und den git-Client zum Abrufen (Pull) und Übertragen (Push) von Quellcode aus Versionsverwaltungs-Repositorys wie GitHub, Bitbucket, oder Gitlab. Die Zeilen mit ENV geben Umgebungsvariablen an, die im Container verwendet werden sollen.

Der COPY-Befehl kopiert die Abhängigkeiten in den Container. Der RUN-Befehl ruft den pip-Paket manager auf, um die Datei dependencies.txt zu analysieren und die Abhängigkeiten zu installieren. Speichern und schließen Sie die Datei, wenn Sie mit der Bearbeitung fertig sind.

Als Nächstes erstellen Sie das Skript start.sh. Dieses Skript enthält Docker-Befehle zum Erstellen und Ausführen des Images. Obwohl Sie diese Befehle schrittweise im Terminal ausführen können, dachten wir, es sei sauberer, sie in ein Shell-Skript einzufügen und dieses einfach mit einem einzigen Befehl aus dem Terminal aufzurufen.

Bevor wir den Inhalt dieser Datei definieren können, müssen wir zunächst einen freien Port ermitteln, der nicht von anderen Diensten verwendet wird. Wir werden den Port 45644 verwenden. Sie können jedoch auch einen anderen Port wählen. Führen Sie die folgende Zeile aus, um zu prüfen, ob der Port frei ist:

Abhängig von dem von Ihnen gewählten Port: Wenn die Ausgabe des obigen Befehls 1 ist, dann ist er frei. Andernfalls müssen Sie möglicherweise einen anderen Port wählen und den Befehl erneut versuchen:

Flask application Port Check

Da wir einen freien Port ermittelt haben, können wir nun die Datei mit nano im Stammverzeichnis des Projekts erstellen, indem wir folgenden Befehl ausführen:

Fügen Sie in dieser Datei den folgenden Code-Ausschnitt hinzu:

Die erste Zeile, auch bezeichnet als shebang, gibt an, dass es sich um eine Bash-Datei handelt und diese als Befehle ausgeführt werden soll. Die zweite Zeile deklariert eine Variable namens app_name. Wir verwenden diese Variable, um die Image- und Containernamen festzulegen. Die dritte Zeile weist Docker an, das Image zu erstellen, basierend auf der Dockerfile-Definition im aktuellen Verzeichnis. Das Image wird docker-flask-demo genannt, entsprechend der Variable.

Die letzte Zeile erstellt einen Container namens docker-flask-demo entsprechend der von uns definierten Variable. Das -d-Flag sorgt dafür, dass der Container im Hintergrund in einem losgelösten Zustand (detached) weiterläuft, nachdem der Befehl ausgeführt wurde. Das -p-Flag bindet einen Port auf dem Server an einen bestimmten Port im Container. In diesem Fall leiten wir den Port 45644 auf dem Host-Rechner an den Port 80 weiter, den Docker im Container freigeben wird.

Wir verwenden das -v-Flag, um ein Docker-Volume anzugeben, das im Container gemountet werden soll. Die Variable $PWD ist eine Standard-Linux-Variable, die den Pfad zum aktuellen Verzeichnis enthält, in dem Sie sich zu einem bestimmten Zeitpunkt befinden:

Flask application pwd

In unserem Fall mounten wir das gesamte Projektverzeichnis in das Verzeichnis /var/www des Containers. Die Docker-Konfiguration ist nun bereit. Sie können das Image erstellen und den Container basierend auf dem erstellten Image starten, indem Sie den folgenden Befehl ausführen:

Warten Sie, bis das Skript die Ausführung beendet hat, und führen Sie dann den folgenden Docker-Befehl aus, um alle laufenden Container aufzulisten:

Die Ausgabe zeigt die laufenden Container an:

Demo Docker

Sie sollten unseren Container mit dem Namen docker-flask-demo in der Liste der laufenden Container sehen. Suchen Sie die öffentliche IP Ihres Servers und rufen Sie sie in Ihrem Browser unter dem angegebenen Port auf: http://your-server-public-ip:45644.

Sie sollten eine ähnliche Ausgabe sehen:

Flask App Running

Wenn Sie das Obige in Ihrem Browser sehen, haben Sie erfolgreich eine Flask-Anwendung bereitgestellt. Als Nächstes werden wir Dateien ändern und Benutzern Inhalte über Templates bereitstellen.

Schritt 3: Inhalte über Template-Dateien bereitstellen

In Flask werden Templates verwendet, um Website-Besuchern statische und dynamische Inhalte anzuzeigen. Wir zeigen Ihnen, wie Sie ein HTML Template erstellen und es Ihren Benutzern bereitstellen, wenn sie eine bestimmte Route besuchen. Dies kann beispielsweise eine Startseite oder eine „Über uns“-Seite sein.

Führen Sie den folgenden Befehl in Ihrem Terminal aus, um eine index.html Datei im Verzeichnis app/templates zu erstellen:

Fügen Sie dann den folgenden Code-Ausschnitt in die Datei ein:

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Erstellen Sie außerdem eine weitere Seite, nennen wir sie die „Über uns“-Seite, mit dem folgenden Befehl:

Fügen Sie den folgenden Code-Ausschnitt in die Datei ein:

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Ändern Sie als Nächstes die app/views.py Datei, um sowohl auf die Templates als auch auf die Routen für die eigentlichen Seiten zu verweisen:

Ändern Sie die Datei so, dass sie wie folgt aussieht:

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Die vorgenommenen Änderungen werden erst wirksam, wenn Sie den Container stoppen und neu starten. Führen Sie die folgenden Docker-Befehle aus, um den Container zu stoppen und zu starten. Notieren Sie sich den zuvor definierten Containernamen:

Sobald der Container läuft, besuchen Sie die Startseite und die „Über uns“-Seite, um einige der neuen Inhalte zu sehen:

Flask application Index

 Flask application 1

Bisher haben Sie eine Flask-Anwendung erstellt, die Inhalte für Ihre Website-Besucher bereitstellen kann. Hier ist die Dateistruktur für das Projekt:

File Structure

Sie haben wahrscheinlich bemerkt, dass wir den Docker-Container neu starten mussten, damit er neue Änderungen übernimmt. Im nächsten Schritt werden wir dies automatisieren, um weniger Ausfallzeiten zu gewährleisten.

Schritt 4: Aktualisierungen der Anwendungsdateien für den automatischen Neustart konfigurieren

Fast täglich nehmen wir Änderungen an einer Anwendung vor, um die Logik oder Benutzeroberflächen zu verbessern oder Abhängigkeiten hinzuzufügen. Damit solche Änderungen wirksam werden, müssen Sie möglicherweise den Docker-Container neu starten. Glücklicherweise uWSGI über eine Funktion namens touch-reload zum Neuladen eines Python-Skripts ohne Neustart des Containers verfügt.

Standardmäßig verfügt Python über eine auto-reloading-Funktion, die das gesamte Dateisystem auf Änderungen überwacht und die Anwendung aktualisiert, wenn eine Änderung auftritt. Während das automatische Neuladen gut zur Minimierung von Ausfallzeiten ist, kann es ressourcenintensiv sein. Daher wird es für Produktionsumgebungen nicht empfohlen.

Sehen wir uns an, wie Sie touch-reload verwenden können, um Änderungen an einer bestimmten Datei zu überwachen und die Anwendung bei Änderungen neu zu laden. Ändern Sie die Datei uwsgi.ini mit dem Nano-Editor:

Fügen Sie die hervorgehobene Zeile hinzu, sodass sie wie folgt aussieht:

Speichern und schließen Sie die Datei, wenn Sie fertig sind. Die hinzugefügte Zeile gibt eine Datei an, die geändert werden muss, um das Neuladen der Anwendung auszulösen. Damit diese Bedingung für zukünftige Änderungen aktiviert wird, müssen Sie jedoch zuerst den Container neu starten:

Sie können nun die Datei app/views.py ändern, um zu demonstrieren, wie das automatische Neuladen funktioniert:

Ändern Sie die von der Home-Funktion zurückgegebene Zeichenfolge wie hervorgehoben:

Speichern und schließen Sie die Datei, sobald Sie fertig sind.

Öffnen Sie die Startseite Ihrer Anwendung im Browser: http://your-server-public-ip:45644.

Sie werden noch keine Änderungen sehen. Dies liegt daran, dass die touch-reload-Bedingung eine Änderung an der Datei uwsgi.ini erkennt. Sie können touch verwenden, um die Bedingung zu aktivieren und somit die gesamte Anwendung mit dem folgenden Befehl neu zu laden:

Wenn Sie nun die Startseite neu laden, werden die neuen Änderungen angezeigt:

Touch Reload

Wenn Sie in Zukunft weitere Änderungen vornehmen, müssen Sie nur noch den folgenden Befehl ausführen: sudo touch uwsgi.ini und die gesamte Anwendung wird mit weniger Ausfallzeit neu geladen. Damit sind wir am Ende dieses Tutorials angelangt.

Fazit

In diesem Tutorial haben Sie eine Flask-Anwendung mit Docker-Images und -Containern implementiert und bereitgestellt. Um Ausfallzeiten zu minimieren, indem ein Neustart des Containers vermieden wird, haben Sie touch-reload so konfiguriert, dass auf Änderungen an einer bestimmten Datei geachtet und die gesamte Anwendung automatisch neu geladen wird. Schließlich haben Sie all dies im Browser getestet, um sicherzustellen, dass es funktioniert.

Docker sorgt für schnellere Bereitstellungen und ermöglicht eine einfache Skalierung von Anwendungen. Wenn Sie mehr über die verschiedenen Docker-Befehle erfahren möchten, werfen Sie bitte einen Blick auf dieses Tutorial über die Installation und Verwendung von Docker auf Ubuntu.

Weitere Ressourcen zu Docker auf unserem Blog, finden Sie im Folgenden:

Viel Spaß beim Computing!

author

Pranay Kapgate

Autor · CloudSigma

Preslav Dobrev ist ein kreativer Designer bei CloudSigma und konzentriert sich auf eine konsistente Unternehmensidentität durch traditionelle und innovative Marketingkanäle. Er versteht es meisterhaft, künstlerische Vision mit strategischem Marketing zu verbinden, um wirkungsvolle Markengeschichten zu schaffen.

Kommentare

Noch keine Kommentare. Schreiben Sie den ersten.