Erstellen und Bereitstellen einer Kolbenanwendung mit Docker unter Ubuntu 18.04

_Der Autor hat das Programm Tech Education Fund ausgewählt, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten. _

Einführung

Docker ist eine Open Source-Anwendung, mit der Administratoren Anwendungen mithilfe von Containern erstellen, verwalten, bereitstellen und replizieren können. Container können als Paket betrachtet werden, das Abhängigkeiten enthält, die eine Anwendung benötigt, um auf Betriebssystemebene ausgeführt zu werden. Dies bedeutet, dass jede mit Docker bereitgestellte Anwendung in einer eigenen Umgebung ausgeführt wird und die Anforderungen separat behandelt werden.

Flask ist ein Web-Mikro-Framework, das auf Python basiert. Es wird als Micro-Framework bezeichnet, da zum Ausführen keine speziellen Tools oder Plug-Ins erforderlich sind. Das Flask-Gerüst ist leicht und flexibel, weist jedoch eine hohe Struktur auf, sodass es anderen Gerüsten vorgezogen wird.

Durch die Bereitstellung einer Flask-Anwendung mit Docker können Sie die Anwendung mit minimaler Neukonfiguration auf verschiedenen Servern replizieren.

In diesem Tutorial erstellen Sie eine Flask-Anwendung und stellen sie mit Docker bereit. In diesem Lernprogramm wird auch erläutert, wie eine Anwendung nach der Bereitstellung aktualisiert wird.

Voraussetzungen

Um diesem Tutorial zu folgen, benötigen Sie Folgendes:

Schritt 1 - Einrichten der Kolbenanwendung

Zunächst erstellen Sie eine Verzeichnisstruktur, die Ihre Flask-Anwendung enthält. In diesem Lernprogramm wird ein Verzeichnis mit dem Namen "+ TestApp " in " / var / www +" erstellt. Sie können den Befehl jedoch ändern, um ihm einen beliebigen Namen zu geben.

sudo mkdir /var/www/

Wechseln Sie in das neu erstellte Verzeichnis + TestApp +:

cd /var/www/

Erstellen Sie als Nächstes die Basisordnerstruktur für die Flask-Anwendung:

sudo mkdir -p app/static app/templates

Das Flag "+ -p " gibt an, dass " mkdir " ein Verzeichnis und alle übergeordneten Verzeichnisse erstellt, die nicht vorhanden sind. In diesem Fall erstellt " mkdir " das übergeordnete Verzeichnis " app ", während die Verzeichnisse " static " und " templates +" erstellt werden.

Das Verzeichnis "+ app +" enthält alle Dateien, die sich auf die Flask-Anwendung beziehen, z. B. die views und blueprints. Views ist der Code, den Sie schreiben, um auf Anforderungen an Ihre Anwendung zu antworten. Blueprints erstellt Anwendungskomponenten und unterstützt gemeinsame Muster innerhalb einer Anwendung oder über mehrere Anwendungen hinweg.

Im Verzeichnis "+ static " befinden sich Elemente wie Bilder, CSS und JavaScript-Dateien. Im Verzeichnis ` templates +` legen Sie die HTML-Vorlagen für Ihr Projekt ab.

Nachdem die Basisordnerstruktur vollständig ist, erstellen Sie die Dateien, die zum Ausführen der Flask-Anwendung erforderlich sind. Erstellen Sie zunächst eine "+ init . Py" -Datei im "+ app" -Verzeichnis. Diese Datei teilt dem Python-Interpreter mit, dass das Verzeichnis "+ app +" ein Paket ist und als solches behandelt werden sollte.

Führen Sie den folgenden Befehl aus, um die Datei zu erstellen:

sudo nano app/__init__.py

Mit Paketen in Python können Sie Module in logischen Namespaces oder Hierarchien gruppieren. Dieser Ansatz ermöglicht es, den Code in einzelne und verwaltbare Blöcke zu unterteilen, die bestimmte Funktionen ausführen.

Als nächstes fügen Sie dem + init . Py + Code hinzu, der eine Flask-Instanz erstellt und die Logik aus der + views.py + -Datei importiert, die Sie nach dem Speichern dieser Datei erstellen. Fügen Sie Ihrer neuen Datei den folgenden Code hinzu:

/var/www/TestApp/init.py

from flask import Flask
app = Flask(__name__)
from app import views

Speichern und schließen Sie die Datei, nachdem Sie diesen Code hinzugefügt haben.

Mit der erstellten "+ init . Py " -Datei können Sie die " views.py " -Datei in Ihrem " app +" -Verzeichnis erstellen. Diese Datei enthält den größten Teil Ihrer Anwendungslogik.

sudo nano app/views.py

Fügen Sie als Nächstes den Code zu Ihrer Datei + views.py + hinzu. Dieser Code gibt die Zeichenfolge "+ Hallo Welt! +" An Benutzer zurück, die Ihre Webseite besuchen:

/var/www/TestApp/app/views.py

from app import app

@app.route('/')
def home():
  return "hello world!"

Die Zeile "+ @ app.route " über der Funktion wird als "http://flask.pocoo.org/docs/0.12/patterns/viewdecorators/[decorator" bezeichnet. Dekorateure ändern die darauf folgende Funktion. In diesem Fall teilt der Dekorateur Flask mit, welche URL die Funktion ` home () ` auslöst. Der von der Funktion " home " zurückgegebene Text " hello world +" wird dem Benutzer im Browser angezeigt.

Wenn die Datei "+ views.py " vorhanden ist, können Sie die Datei " uwsgi.ini +" erstellen. Diese Datei enthält die https://uwsgi-docs.readthedocs.io [uWSGI] -Konfigurationen für unsere Anwendung. uWSGI ist eine Bereitstellungsoption für Nginx, bei der es sich sowohl um ein Protokoll als auch um einen Anwendungsserver handelt. Der Anwendungsserver kann die Protokolle uWSGI, FastCGI und HTTP bedienen.

Führen Sie den folgenden Befehl aus, um diese Datei zu erstellen:

sudo nano uwsgi.ini

Fügen Sie als Nächstes den folgenden Inhalt zu Ihrer Datei hinzu, um den uWSGI-Server zu konfigurieren:

/var/www/TestApp/uwsgi.ini

[uwsgi]
module = main
callable = app
master = true

Dieser Code definiert das Modul, von dem aus die Flask-Anwendung bedient wird. In diesem Fall ist dies die Datei "+ main.py ", die hier als " main " bezeichnet wird. Die Option " callable " weist uWSGI an, die von der Hauptanwendung exportierte Instanz " app " zu verwenden. Mit der Option " master +" kann Ihre Anwendung weiter ausgeführt werden, sodass selbst beim erneuten Laden der gesamten Anwendung nur geringe Ausfallzeiten auftreten.

Als nächstes erstellen Sie die Datei + main.py +, die den Einstiegspunkt für die Anwendung darstellt. Der Einstiegspunkt weist uWSGI in die Interaktion mit der Anwendung ein.

sudo nano main.py

Kopieren Sie als Nächstes Folgendes und fügen Sie es in die Datei ein. Dadurch wird die Flask-Instanz mit dem Namen "+ app +" aus dem zuvor erstellten Anwendungspaket importiert.

/var/www/TestApp/main.py

from app import app

Erstellen Sie abschließend eine + requirements.txt + - Datei, um die Abhängigkeiten anzugeben, die der + pip + - Paketmanager in Ihrer Docker-Bereitstellung installiert:

sudo nano requirements.txt

Fügen Sie die folgende Zeile hinzu, um Flask als Abhängigkeit hinzuzufügen:

/var/www/TestApp/app/requirements.txt

Flask==1.0.2

Dies gibt die Version von Flask an, die installiert werden soll. Zum Zeitpunkt des Schreibens dieses Tutorials ist + 1.0.2 + die neueste Flask-Version. Sie können auf der offiziellen Website unter Flask nach Updates suchen.

Speichern und schließen Sie die Datei. Sie haben Ihre Flask-Anwendung erfolgreich eingerichtet und können Docker jetzt einrichten.

Schritt 2 - Einrichten von Docker

In diesem Schritt erstellen Sie zwei Dateien, "+ Dockerfile " und " start.sh ", um Ihre Docker-Bereitstellung zu erstellen. Das ` Dockerfile ` ist ein Textdokument, das die Befehle zum Zusammenstellen des Bildes enthält. Die Datei ` start.sh ` ist ein Shell-Skript, das ein Image erstellt und einen Container aus der ` Docker-Datei +` erstellt.

Zuerst erstellen Sie die + Dockerfile.

sudo nano Dockerfile

Fügen Sie als nächstes Ihre gewünschte Konfiguration in das Dockerfile ein. Diese Befehle legen fest, wie das Image erstellt wird und welche zusätzlichen Anforderungen enthalten sind.

/ var / www / TestApp / Dockerfile

FROM tiangolo/uwsgi-nginx-flask:
RUN apk --update add bash nano
ENV STATIC_URL /static
ENV STATIC_PATH /var/www/app/static
COPY ./requirements.txt /var/www/requirements.txt
RUN pip install -r /var/www/requirements.txt

In diesem Beispiel wird das Docker-Image aus einem vorhandenen Image "+ tiangolo / uwsgi-nginx-flask +" erstellt, das Sie unter https://hub.docker.com/r/tiangolo/uwsgi-nginx-flask finden [DockerHub]. Dieses spezielle Docker-Image ist eine gute Wahl, da es eine Vielzahl von Python-Versionen und Betriebssystem-Images unterstützt.

Die ersten beiden Zeilen geben das übergeordnete Image an, mit dem Sie die Anwendung ausführen und den Bash-Befehlsprozessor sowie den Texteditor "+ nano " installieren. Es installiert auch den " git " - Client, um Hosting-Dienste zur Versionskontrolle wie GitHub, GitLab und Bitbucket abzurufen und zu übertragen. ` ENV STATIC_URL / static +` ist eine Umgebungsvariable, die für dieses Docker-Image spezifisch ist. Es definiert den statischen Ordner, in dem alle Elemente wie Bilder, CSS-Dateien und JavaScript-Dateien bereitgestellt werden.

In den letzten beiden Zeilen wird die Datei "+ requirements.txt" in den Container kopiert, damit sie ausgeführt werden kann. Anschließend wird die Datei "+ requirements.txt" analysiert, um die angegebenen Abhängigkeiten zu installieren.

Speichern und schließen Sie die Datei, nachdem Sie Ihre Konfiguration hinzugefügt haben.

Wenn Sie Ihre Docker-Datei installiert haben, können Sie fast Ihr Skript "+ start.sh " schreiben, mit dem der Docker-Container erstellt wird. Stellen Sie vor dem Schreiben des Skripts ` start.sh +` sicher, dass Sie einen offenen Port für die Konfiguration haben. Führen Sie den folgenden Befehl aus, um zu überprüfen, ob ein Port frei ist:

sudo nc localhost  < /dev/null; echo $?

Wenn die Ausgabe des obigen Befehls "+ 1 " ist, ist der Port frei und verwendbar. Andernfalls müssen Sie einen anderen Port auswählen, der in Ihrer Konfigurationsdatei " start.sh +" verwendet werden soll.

Wenn Sie einen offenen Port gefunden haben, erstellen Sie das Skript "+ start.sh +":

sudo nano start.sh

Das Skript + start.sh + ist ein Shell-Skript, das ein Image aus der + Docker-Datei + erstellt und einen Container aus dem resultierenden Docker-Image erstellt. Fügen Sie Ihre Konfiguration zur neuen Datei hinzu:

/var/www/TestApp/start.sh

#!/bin/bash
app=""
docker build -t ${app} .
docker run -d -p :80 \
 --name=${app} \
 -v $PWD:/app ${app}

Die erste Zeile heißt shebang. Es gibt an, dass dies eine Bash-Datei ist und als Befehle ausgeführt wird. In der nächsten Zeile wird der Name angegeben, den Sie dem Bild und dem Container geben möchten, und als Variable mit dem Namen "+ app " gespeichert. In der nächsten Zeile wird Docker angewiesen, ein Image aus Ihrer Docker-Datei zu erstellen, die sich im aktuellen Verzeichnis befindet. Dadurch wird in diesem Beispiel ein Bild mit dem Namen " docker.test +" erstellt.

In den letzten drei Zeilen wird ein neuer Container mit dem Namen "+ docker.test " erstellt, der an Port " 56733 " verfügbar gemacht wird. Schließlich wird das aktuelle Verzeichnis mit dem Verzeichnis " / var / www +" des Containers verknüpft.

Sie verwenden das Flag "+ -d ", um einen Container im Dämonmodus oder als Hintergrundprozess zu starten. Sie fügen das Flag " -p " ein, um einen Port auf dem Server an einen bestimmten Port im Docker-Container zu binden. In diesem Fall binden Sie den Port " 56733 " an den Port " 80 " des Docker-Containers. Das Flag ` -v ` gibt ein Docker-Volume an, das in den Container geladen werden soll. In diesem Fall mounten Sie das gesamte Projektverzeichnis in den Ordner ` / var / www +` des Docker-Containers.

Führen Sie das Skript + start.sh + aus, um das Docker-Image zu erstellen und einen Container aus dem resultierenden Image zu erstellen:

sudo bash start.sh

Verwenden Sie nach Beendigung des Skripts den folgenden Befehl, um alle ausgeführten Container aufzulisten:

sudo docker ps

Sie erhalten eine Ausgabe, die die Container zeigt:

OutputCONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
58b05508f4dd        docker.test         "/entrypoint.sh /sta…"   12 seconds ago      Up 3 seconds       443/tcp, 0.0.0.0:56733->80/tcp   docker.test

Sie werden feststellen, dass der Container "+ docker.test" ausgeführt wird. Besuchen Sie jetzt die IP-Adresse des angegebenen Ports in Ihrem Browser: + http: //: +

Es wird eine Seite angezeigt, die der folgenden ähnelt:

In diesem Schritt haben Sie Ihre Flask-Anwendung erfolgreich in Docker bereitgestellt. Als Nächstes verwenden Sie Vorlagen, um den Benutzern Inhalte anzuzeigen.

Schritt 3 - Bereitstellen von Vorlagendateien

Templates sind Dateien, die Benutzern, die Ihre Anwendung besuchen, statischen und dynamischen Inhalt anzeigen. In diesem Schritt erstellen Sie eine HTML-Vorlage, um eine Homepage für die Anwendung zu erstellen.

Beginnen Sie, indem Sie eine "+ home.html" -Datei im "+ app / templates" -Verzeichnis erstellen:

sudo nano app/templates/home.html

Fügen Sie den Code für Ihre Vorlage hinzu. Dieser Code erstellt eine HTML5-Seite, die einen Titel und Text enthält.

/var/www/TestApp/app/templates/home.html

<!doctype html>

<html lang="en-us">
 <head>
   <meta charset="utf-8">
   <meta http-equiv="x-ua-compatible" content="ie=edge">
   <title>Welcome home</title>
 </head>

 <body>
   <h1>Home Page</h1>
   <p>This is the home page of our application.</p>
 </body>
</html>

Speichern und schließen Sie die Datei, sobald Sie Ihre Vorlage hinzugefügt haben.

Ändern Sie als Nächstes die Datei + app / views.py +, um die neu erstellte Datei bereitzustellen:

sudo nano app/views.py

Fügen Sie zuerst die folgende Zeile am Anfang Ihrer Datei hinzu, um die Methode + render_template + von Flask zu importieren. Diese Methode analysiert eine HTML-Datei, um eine Webseite für den Benutzer zu rendern.

/var/www/TestApp/app/views.py

from flask import render_template
...

Am Ende der Datei fügen Sie außerdem eine neue Route hinzu, um die Vorlagendatei zu rendern. Dieser Code gibt an, dass Benutzer den Inhalt der Datei "+ home.html" erhalten, wenn sie die Route "+ / template a" in Ihrer Anwendung aufrufen.

/var/www/TestApp/app/views.py

...

@app.route('/template')
def template():
   return render_template('home.html')

Die aktualisierte Datei + app / views.py + sieht folgendermaßen aus:

/var/www/TestApp/app/views.py

from flask import render_template
from app import app

@app.route('/')
def home():
   return "Hello world!"

@app.route('/template')
def template():
   return render_template('home.html')

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

Damit diese Änderungen wirksam werden, müssen Sie die Docker-Container stoppen und neu starten. Führen Sie den folgenden Befehl aus, um den Container neu zu erstellen:

sudo docker stop  && sudo docker start

Besuchen Sie Ihre Anwendung unter + http: //: 56733 / template +, um zu sehen, welche neue Vorlage bereitgestellt wird.

In diesem Abschnitt haben Sie eine Docker-Vorlagendatei erstellt, um Besucher in Ihrer Anwendung zu bedienen. Im nächsten Schritt sehen Sie, wie die Änderungen, die Sie an Ihrer Anwendung vornehmen, wirksam werden können, ohne den Docker-Container neu starten zu müssen.

Schritt 4 - Aktualisierung der Anwendung

Manchmal müssen Sie Änderungen an der Anwendung vornehmen, unabhängig davon, ob neue Anforderungen installiert, der Docker-Container aktualisiert oder HTML- und Logikänderungen vorgenommen werden. In diesem Abschnitt konfigurieren Sie "+ Touch-Reload +", um diese Änderungen vorzunehmen, ohne den Docker-Container neu starten zu müssen.

Python autoreloading überwacht das gesamte Dateisystem auf Änderungen und aktualisiert die Anwendung, wenn eine Änderung festgestellt wird. Das automatische Laden wird in der Produktion nicht empfohlen, da es sehr schnell ressourcenintensiv werden kann. In diesem Schritt verwenden Sie "+ Touch-Reload +", um nach Änderungen an einer bestimmten Datei zu suchen und sie neu zu laden, wenn die Datei aktualisiert oder ersetzt wird.

Um dies zu implementieren, öffnen Sie zunächst Ihre Datei + uwsgi.ini +:

sudo nano uwsgi.ini

Fügen Sie als Nächstes die hervorgehobene Zeile am Ende der Datei hinzu:

/var/www/TestApp/uwsgi.ini

module = main
callable = app
master = true

Dies gibt eine Datei an, die geändert wird, um ein vollständiges erneutes Laden der Anwendung auszulösen. Speichern und schließen Sie die Datei, nachdem Sie die Änderungen vorgenommen haben.

Nehmen Sie zur Veranschaulichung eine kleine Änderung an Ihrer Anwendung vor. Öffnen Sie zunächst die Datei "+ app / views.py +":

sudo nano app/views.py

Ersetzen Sie den von der Funktion + home + zurückgegebenen String:

/var/www/TestApp/app/views.py

from flask import render_template
from app import app

@app.route('/')
def home():
   return ""

@app.route('/template')
def template():
   return render_template('home.html')

Speichern und schließen Sie die Datei, nachdem Sie eine Änderung vorgenommen haben.

Wenn Sie die Startseite Ihrer Anwendung unter "+ http: //: " öffnen, werden Sie feststellen, dass die Änderungen nicht übernommen werden. Dies liegt daran, dass die Bedingung für das Neuladen eine Änderung der Datei " uwsgi.ini " ist. Um die Anwendung neu zu laden, aktivieren Sie die Bedingung mit ` touch +`:

sudo touch uwsgi.ini

Laden Sie die Anwendungshomepage erneut in Ihren Browser. Sie werden feststellen, dass die Anwendung die Änderungen übernommen hat:

In diesem Schritt richten Sie eine "+ touch-reload +" - Bedingung ein, um Ihre Anwendung zu aktualisieren, nachdem Sie Änderungen vorgenommen haben.

Fazit

In diesem Lernprogramm haben Sie eine Flask-Anwendung erstellt und in einem Docker-Container bereitgestellt. Sie haben auch "+ touch-reload +" konfiguriert, um Ihre Anwendung zu aktualisieren, ohne den Container neu starten zu müssen.

Mit Ihrer neuen Anwendung in Docker können Sie jetzt problemlos skalieren. Weitere Informationen zur Verwendung von Docker finden Sie in der official documentation.