Ein Artikel von Docker
Einführung
Continuous Integration (CI) bezieht sich auf die Vorgehensweise, bei der Entwickler Code so oft wie möglich integrieren und jedes Commit vor und nach dem Zusammenführen in einem gemeinsam genutzten Repository durch einen automated Build getestet wird.
CI beschleunigt Ihren Entwicklungsprozess und minimiert das Risiko kritischer Probleme in der Produktion, ist jedoch nicht einfach einzurichten. Automatisierte Builds werden in einer anderen Umgebung ausgeführt, in der die Installation von * Laufzeitabhängigkeiten * und die Konfiguration von * externen Diensten * möglicherweise anders sind als in Ihrer lokalen Umgebung und Ihrer Entwicklungsumgebung.
Docker ist eine Containerisierungsplattform, mit der die Probleme der Umgebungsstandardisierung vereinfacht werden sollen, sodass die Bereitstellung von Anwendungen auch standardisiert werden kann (https://www.digitalocean.com/community/tutorials) / das-docker-ökosystem-eine-übersicht-über-containerisierung [erfahren sie mehr über docker]). Mit Docker können Entwickler Produktionsumgebungen auf lokalen Computern simulieren, indem Anwendungskomponenten in lokalen Containern ausgeführt werden. Diese Container können mithilfe von Docker Compose unabhängig von der Anwendung und dem zugrunde liegenden Betriebssystem problemlos automatisiert werden.
In diesem Tutorial wird Docker Compose verwendet, um die Automatisierung von CI-Workflows zu demonstrieren.
Wir werden eine dockerisierte Python-Anwendung vom Typ "Hallo Welt" und ein Bash-Testskript erstellen. Für die Ausführung der Python-Anwendung sind zwei Container erforderlich: einer für die App selbst und ein Redis-Container für den Speicher, der als Abhängigkeit für die App erforderlich ist.
Anschließend wird das Testskript in einem eigenen Container angedockt und die gesamte Testumgebung in eine * docker-compose.test.yml * -Datei verschoben, damit wir sicherstellen können, dass jede Testausführung in einer neuen und einheitlichen Anwendungsumgebung ausgeführt wird.
Dieser Ansatz zeigt, wie Sie bei jedem Test eine identische, frische Testumgebung für Ihre Anwendung erstellen können, einschließlich ihrer Abhängigkeiten.
So automatisieren wir die CI-Workflows unabhängig von der zu testenden Anwendung und der zugrunde liegenden Infrastruktur.
Bedarf
Bevor Sie beginnen, benötigen Sie:
-
Ein Ubuntu 14.04 Server
-
Ein Benutzer ohne Rootberechtigung mit sudo-Berechtigungen. Sie können diesem tutorial folgen, um dies einzurichten
-
Etwas Vertrautheit mit Docker und https://www.digitalocean.com/community/tutorials/how- Docker-Compose-on-Ubuntu-14-04-installieren und-verwenden [Docker Compose]; Die Links dienen als Referenz, da wir die Software während dieses Tutorials installieren
-
* Testen, Testen und mehr (automatisiertes) Testen! * Sie sollten bereits von den Vorteilen des Testens und Anwendens von CI in Ihren Entwicklungsworkflows überzeugt sein
Schritt 1 - Installieren Sie Docker
Wenn Docker noch nicht auf Ihrem Server verfügbar ist, können Sie am einfachsten das offizielle Docker-Installationsskript herunterladen und ausführen, das Sie zur Eingabe eines Sudo-Kennworts auffordert (weitere Informationen zur Installation von Docker finden Sie unter https://www.digitalocean.com/community/tutorials) / Wie installiere und verwende ich Docker? [hier]):
wget -qO- https://get.docker.com/ | sh
Um die Arbeit mit Docker zu vereinfachen, fügen Sie Ihren Benutzer mit dem folgenden Befehl der Gruppe * docker * hinzu:
sudo usermod -aG docker $(whoami)
Melden Sie sich ab und dann bei Ihrem Server an, um die Gruppe * docker * für Ihren Benutzer zu aktivieren.
Schritt 2 - Installieren Sie Docker Compose
Docker Compose ist ein Open-Source-Tool zum Definieren und Ausführen von Anwendungen mit mehreren Containern mithilfe eines deklarativen Ansatzes. Führen Sie die folgenden Befehle aus, um Docker Compose zu installieren:
sudo apt-get update
sudo apt-get -y install python-pip
sudo pip install docker-compose
Stellen Sie sicher, dass + docker-compose +
korrekt installiert ist, indem Sie Folgendes ausführen:
docker-compose --version
Sie sollten etwas sehen wie:
Ausgabe
docker-compose version 1.6.2, build 4d72027
Dies sollte Ihnen die installierte Docker-Compose-Version mitteilen.
Schritt 3 - Erstellen Sie die Python-Anwendung "Hello World"
In diesem Schritt erstellen wir eine einfache Python-Anwendung als Beispiel für den Anwendungstyp, den Sie mit diesem Setup testen können.
Erstellen Sie einen neuen Ordner für unsere Anwendung, indem Sie Folgendes ausführen:
cd ~
mkdir hello_world
cd hello_world
Bearbeite eine neue Datei + app.py +
mit nano:
nano app.py
Fügen Sie den folgenden Inhalt hinzu:
app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host="redis")
@app.route("/")
def hello():
visits = redis.incr('counter')
html = "<h3>Hello World!</h3>" \
"<b>Visits:</b> {visits}" \
"<br/>"
return html.format(visits=visits)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80)
+ app.py +
ist eine auf Flask basierende Webanwendung, die eine Verbindung zu einem Redis-Datendienst herstellt. Die Zeile + visitors = redis.incr ('counter') +
erhöht die Anzahl der Besuche und behält diesen Wert in Redis bei. Schließlich wird eine "+ Hello World +" - Nachricht mit der Anzahl der Besuche in HTML zurückgegeben.
Unsere Anwendung hat zwei Abhängigkeiten, "+ Flask " und " Redis +", die Sie in den ersten beiden Zeilen sehen können. Diese Abhängigkeiten müssen definiert werden, bevor wir die Anwendung ausführen können. Bearbeiten Sie eine neue Datei:
nano requirements.txt
Fügen Sie den Inhalt hinzu:
requirements.txt
Flask
Redis
Schritt 4 - Dockerisieren Sie die Anwendung „Hello World“
Docker verwendet eine Datei mit dem Namen "+ Dockerfile +", um die erforderlichen Schritte zum Erstellen eines Docker-Images für eine bestimmte Anwendung anzugeben. Bearbeiten Sie eine neue Datei:
nano Dockerfile
Fügen Sie den folgenden Inhalt hinzu:
Dockerfile
FROM python:2.7
WORKDIR /app
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
ADD app.py /app/app.py
EXPOSE 80
CMD ["python", "app.py"]
Analysieren wir die Bedeutung jeder Zeile:
-
+ FROM python: 2.7 +
: Gibt an, dass unser "Hello World" -Anwendungsimage aus dem offiziellen Docker-Image von+ python: 2.7 +
erstellt wurde -
+ WORKDIR / app +
: Setzt das Arbeitsverzeichnis im Docker-Image auf+ / app +
-
+ ADD requirements.txt / app / requirements.txt
: Fügt die Datei` + requirements.txt` zu Ihrem Docker-Image hinzu -
+ RUN pip install -r requirements.txt +
: Installiert die Abhängigkeiten der Anwendung+ pip +
-
+ ADD app.py / app / app.py +
: Fügt unseren Anwendungsquellcode zum Docker-Image hinzu -
+ EXPOSE 80 +
: Zeigt an, dass unsere Anwendung unter Port 80 (dem Standard-Port für öffentliche Webanwendungen) erreichbar ist. -
+ CMD [" python "," app.py "] +
: Der Befehl, der unsere Anwendung startet
Diese + Dockerfile +
-Datei enthält alle Informationen, die zum Erstellen der Hauptkomponente unserer „Hello World“ -Anwendung erforderlich sind.
-
Die Abhängigkeit *
Jetzt kommen wir zum komplexeren Teil des Beispiels. Unsere Anwendung erfordert Redis als externen Dienst. Dies ist die Art von Abhängigkeit, die in einer herkömmlichen Linux-Umgebung möglicherweise nur schwer auf die gleiche Weise eingerichtet werden kann. Mit Docker Compose können wir sie jedoch jedes Mal auf wiederholbare Weise einrichten.
Erstellen wir eine + docker-compose.yml + -Datei, um Docker Compose zu verwenden.
Bearbeiten Sie eine neue Datei:
nano docker-compose.yml
Fügen Sie den folgenden Inhalt hinzu:
docker-compose.yml
web:
build: .
dockerfile: Dockerfile
links:
- redis
ports:
- "80:80"
redis:
image: redis
In dieser Docker Compose-Datei wird angegeben, wie die Anwendung „Hello World“ lokal in zwei Docker-Containern hochgefahren wird.
Es definiert zwei Container, "+ web " und " redis +".
-
+ web +
verwendet den aktuellen Ordner für den+ build
-Kontext und erstellt Ihre Python-Anwendung aus der soeben erstellten` + Dockerfile`-Datei. Dies ist ein lokales Docker-Image, das wir nur für unsere Python-Anwendung erstellt haben. Es definiert eine Verknüpfung zum Container "+ redis ", um Zugriff auf die Container-IP " redis +" zu erhalten. Über die öffentliche IP-Adresse Ihres Ubuntu-Servers können Sie auch über das Internet auf Port 80 zugreifen -
+ redis +
wird von einem öffentlichen Standard-Docker-Image mit dem Namen+ redis +
ausgeführt
Schritt 5 - Stellen Sie die Anwendung „Hello World“ bereit
In diesem Schritt stellen wir die Anwendung bereit und am Ende wird sie über das Internet zugänglich sein. Für die Zwecke Ihres Bereitstellungsworkflows können Sie dies als Entwicklungs-, Staging- oder Produktionsumgebung betrachten, da Sie die Anwendung mehrmals auf dieselbe Weise bereitstellen können.
Mit den Dateien + docker-compose.yml +
und + Dockerfile +
können Sie die Bereitstellung lokaler Umgebungen automatisieren, indem Sie Folgendes ausführen:
docker-compose -f ~/hello_world/docker-compose.yml build
docker-compose -f ~/hello_world/docker-compose.yml up -d
In der ersten Zeile wird unser lokales Anwendungsbild aus der Datei + Dockerfile +
erstellt. In der zweiten Zeile werden die Container "+ web " und " redis " im Dämonmodus (" -d ") ausgeführt, wie in der Datei " docker-compose.yml +" angegeben.
Überprüfen Sie, ob die Anwendungscontainer erstellt wurden, indem Sie Folgendes ausführen:
docker ps
Dies sollte zwei laufende Container mit den Namen "+ helloworld_web_1 " und " helloworld_redis_1 +" anzeigen.
Überprüfen wir, ob die Anwendung aktiv ist. Wir können die IP des Containers + helloworld_web_1 +
ermitteln, indem wir Folgendes ausführen:
WEB_APP_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' helloworld_web_1)
echo $WEB_APP_IP
Überprüfen Sie, ob die Webanwendung die richtige Nachricht zurückgibt:
curl http://${WEB_APP_IP}:80
Dies sollte ungefähr so aussehen:
Ausgabe
<h3>Hello World!</h3><b>Visits:</b> 1<br/>
Die Anzahl der Besuche wird jedes Mal erhöht, wenn Sie diesen Endpunkt erreichen. Sie können auch über Ihren Browser auf die Anwendung „Hello World“ zugreifen, indem Sie die öffentliche IP-Adresse Ihres Ubuntu-Servers aufrufen.
-
Wie für Ihre eigene Anwendung anpassen *
Der Schlüssel zum Einrichten Ihrer eigenen Anwendung besteht darin, Ihre Anwendung in einem eigenen Docker-Container abzulegen und jede Abhängigkeit in einem eigenen Container auszuführen. Anschließend können Sie die Beziehungen zwischen den Containern mit Docker Compose definieren, wie im Beispiel gezeigt. Docker Compose wird in diesem Docker Compose article ausführlicher behandelt.
In diesem Artikel erfahren Sie, wie Sie eine Anwendung in mehreren Containern ausführen können -on-ubuntu-14-04 [WordPress und phpMyAdmin mit Docker Compose].
Schritt 6 - Erstellen Sie das Testskript
Jetzt erstellen wir ein Testskript für Ihre Python-Anwendung. Dies ist ein einfaches Skript, das die HTTP-Ausgabe der Anwendung überprüft. Das Skript ist ein Beispiel für den Testtyp, den Sie möglicherweise als Teil Ihres Bereitstellungsprozesses für die kontinuierliche Integration ausführen möchten.
Bearbeiten Sie eine neue Datei:
nano test.sh
Fügen Sie den folgenden Inhalt hinzu:
test.sh
sleep 5
if curl web | grep -q '<b>Visits:</b> '; then
echo "Tests passed!"
exit 0
else
echo "Tests failed!"
exit 1
fi
+ test.sh +
testet die grundlegende Web-Konnektivität unserer "Hello World" -Anwendung. Es verwendet cURL, um die Anzahl der Besuche abzurufen und darüber zu berichten, ob der Test bestanden wurde oder nicht.
Schritt 7 - Erstellen Sie die Testumgebung
Um unsere Anwendung zu testen, müssen wir eine Testumgebung bereitstellen. Und wir möchten sicherstellen, dass es mit der Live-Anwendungsumgebung identisch ist, die wir in * Schritt 5 * erstellt haben.
Zuerst müssen wir unser Testskript andocken, indem wir eine neue Dockerfile-Datei erstellen. Bearbeiten Sie eine neue Datei:
nano Dockerfile.test
Fügen Sie den folgenden Inhalt hinzu:
Dockerfile.test
FROM ubuntu:trusty
RUN apt-get update && apt-get install -yq curl && apt-get clean
WORKDIR /app
ADD test.sh /app/test.sh
CMD ["bash", "test.sh"]
+ Dockerfile.test +
erweitert das offizielle + ubuntu: trusty +
Image, um die Abhängigkeit von + curl +
zu installieren, fügt + tests.sh +
zum Image-Dateisystem hinzu und gibt den Befehl + CMD +
an, der das Testskript ausführt mit Bash.
Sobald unsere Tests Dockerized sind, können sie auf reproduzierbare und agnostische Weise ausgeführt werden.
Der nächste Schritt ist die Verknüpfung unseres Testcontainers mit unserer Anwendung „Hello World“. Hier kommt Docker Compose wieder zur Hilfe. Bearbeiten Sie eine neue Datei:
nano docker-compose.test.yml
Fügen Sie den folgenden Inhalt hinzu:
docker-compose.test.yml
sut:
build: .
dockerfile: Dockerfile.test
links:
- web
web:
build: .
dockerfile: Dockerfile
links:
- redis
redis:
image: redis
In der zweiten Hälfte der Docker Compose-Datei werden die Hauptanwendung "+ web " und ihre Abhängigkeit " redis " auf die gleiche Weise wie in der vorherigen Datei " docker-compose.yml " bereitgestellt. Dies ist der Teil der Datei, der die Container " web " und " redis " angibt. Der einzige Unterschied besteht darin, dass der Container " web +" den Port 80 nicht mehr freigibt, sodass die Anwendung während der Tests nicht über das öffentliche Internet verfügbar ist. Sie sehen also, dass wir die Anwendung und ihre Abhängigkeiten genauso erstellen wie in der Live-Bereitstellung.
Die Datei + docker-compose.test.yml +
definiert auch einen Container + sut +
(benannt nach system under tests), der für die Ausführung unserer Integrationstests verantwortlich ist. Der Container "+ sut " gibt das aktuelle Verzeichnis als unser " build " - Verzeichnis an und gibt unsere " Dockerfile.test " - Datei an. Es ist mit dem Container " web " verknüpft, sodass die IP-Adresse des Anwendungscontainers für unser Skript " test.sh +" zugänglich ist.
-
Wie für Ihre eigene Anwendung anpassen *
Beachten Sie, dass "+ docker-compose.test.yml +" möglicherweise Dutzende externer Services und mehrere Testcontainer enthält. Docker kann alle diese Abhängigkeiten auf einem einzelnen Host ausführen, da jeder Container das zugrunde liegende Betriebssystem gemeinsam nutzt.
Wenn Sie mehr Tests für Ihre Anwendung ausführen möchten, können Sie zusätzliche Dockerdateien für diese erstellen, ähnlich wie in der oben gezeigten Datei + Dockerfile.test +
.
Anschließend können Sie zusätzliche Container unter dem Container "+ sut " in der Datei " docker-compose.test.yml +" hinzufügen, wobei auf die zusätzlichen Dockerdateien verwiesen wird.
Schritt 8 - Testen Sie die Anwendung „Hello World“
Wenn wir die Docker-Ideen von lokalen Umgebungen auf Testumgebungen ausweiten, können wir unsere Anwendung mithilfe von Docker automatisiert testen, indem wir Folgendes ausführen:
docker-compose -f ~/hello_world/docker-compose.test.yml -p ci build
Dieser Befehl erstellt die lokalen Images, die von + docker-compose.test.yml +
benötigt werden. Beachten Sie, dass wir "+ -f " verwenden, um auf " docker-compose.test.yml " zu verweisen, und " -p +", um einen bestimmten Projektnamen anzugeben.
Starten Sie jetzt Ihre neue Testumgebung, indem Sie Folgendes ausführen:
docker-compose -f ~/hello_world/docker-compose.test.yml -p ci up -d
Überprüfen Sie die Ausgabe des Containers + sut +
, indem Sie Folgendes ausführen:
docker logs -f ci_sut_1
Ausgabe
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 42 100 42 0 0 3902 0 --:--:-- --:--:-- --:--:-- 4200
Tests passed!
Überprüfen Sie abschließend den Exit-Code des Containers "+ sut +", um zu überprüfen, ob Ihre Tests bestanden wurden:
docker wait ci_sut_1
Ausgabe
0
Nach der Ausführung dieses Befehls ist der Wert von "+ $? " " 0 +", wenn die Tests bestanden wurden. Ansonsten sind unsere Anwendungstests fehlgeschlagen.
Beachten Sie, dass andere CI-Tools unser Code-Repository klonen und diese wenigen Befehle ausführen können, um zu überprüfen, ob die Tests mit den neuesten Bits Ihrer Anwendung bestanden werden, ohne sich um Laufzeitabhängigkeiten oder externe Dienstkonfigurationen zu sorgen.
Das ist es! Wir haben unseren Test erfolgreich in einer frisch gebauten Umgebung durchgeführt, die mit unserer Produktionsumgebung identisch ist.
Fazit
Dank Docker und Docker Compose konnten wir automatisieren, wie eine Anwendung erstellt wird (+ Dockerfile +
), wie eine lokale Umgebung bereitgestellt wird (+ docker-compose.yml +
), wie ein Test-Image erstellt wird () + Dockerfile.test + `) und wie man (Integrations-) Tests (
+ docker-compose.test.yml + `) für jede Anwendung ausführt.
Die Verwendung der Datei + docker-compose.test.yml +
zum Testen hat insbesondere folgende Vorteile:
-
* Automatisch *: Die Art und Weise, wie ein Tool die Datei "+ docker-compose.test.yml +" ausführt, ist unabhängig von der zu testenden Anwendung
-
* Geringes Gewicht *: Hunderte von externen Diensten können bereitgestellt werden ein einzelner Host, der komplexe (Integrations-) Testumgebungen simuliert
-
* Agnostisch *: Vermeiden Sie die Sperre von CI-Anbietern, und Ihre Tests können in jedem ausgeführt werden Infrastruktur und auf jedem Betriebssystem, das Docker unterstützt
-
* Unveränderlich *: Tests, die auf Ihrem lokalen Computer bestanden werden, werden in Ihrem CI-Tool bestanden
Dieses Tutorial zeigt ein Beispiel für das Testen einer einfachen „Hello World“ -Anwendung.
Jetzt ist es an der Zeit, Ihre eigenen Anwendungsdateien zu verwenden, Ihre eigenen Anwendungstestskripte zu docken und Ihre eigene docker-compose.test.yml zu erstellen, um Ihre Anwendung in einer frischen und unveränderlichen Umgebung zu testen.