Hallo zusammen. Wir setzen die Artikelserie zum Schreiben Ihres Projekts fort.
Sortieren Sie die Zweige
Um nicht in den Zweigen und ihrer Reihenfolge im Repository verloren zu gehen, habe ich beschlossen, sie umzubenennen, indem ich das Präfix STEP_{Nummer} hinzufüge . Beispielsweise haben wir neben der Hauptfiliale noch drei Filialen:- JRTB-0
- JRTB-2
- JRTB-3
- STEP_1_JRTB-0 – erster Schritt
- STEP_2_JRTB-2 – zweiter Schritt
- STEP_3_JRTB-3 – dritter Schritt
Ein wenig über Docker
Was ist Docker? Kurz gesagt, es handelt sich um ein Tool, mit dem Sie Anwendungen schnell und sicher bereitstellen (bereitstellen) können und eine geschlossene Infrastruktur für sie erstellen, die nur für sie notwendig ist. Es ist immer noch schwierig, ich verstehe. Generell kann man Docker als Entwicklungsplattform verstehen, auf der man schnell und effizient arbeiten kann. Unter Docker kann man ein Programm verstehen, das auf einem Server läuft. Dieses Programm bietet die Möglichkeit, Container mit Anwendungen zu speichern. Was ist ein Container? Dabei handelt es sich um eine separate Infrastruktur, in die Sie alles hinzufügen können, was Sie benötigen. Für eine Java-Anwendung benötigen wir beispielsweise eine JRE, um die Anwendung auszuführen. Der Container wird diese haben, wir benötigen andere Software – diese können wir hinzufügen. Oder vielleicht brauchen wir Linux und einen Tomcat-Servlet-Container. Dies ist auch möglich. Container werden auf Basis eines Images erstellt: Das heißt, es handelt sich um eine spezielle Vorlage, die alles Notwendige zum Erstellen eines Docker-Containers enthält. Wie erstelle ich dieses Bild? In unserem Fall müssen wir im Stammverzeichnis des Projekts eine Docker-Datei erstellen, die beschreibt, was im Container enthalten sein soll. Da wir das Token des Bots nirgendwo offenlegen möchten, müssen wir es jedes Mal weitergeben, wenn wir die Anwendung bereitstellen möchten. Mehr zu diesem Thema können Sie hier und hier lesen .Wir schreiben JRTB-13
Wir müssen einen schnellen und einfachen Bereitstellungsprozess für unsere Anwendung auf dem Server einrichten. Das heißt, für eine Maschine, die rund um die Uhr arbeitet. Nehmen wir Docker als Basis. Es gibt jedoch keine Aufgabe auf unserer Liste, die für das Hinzufügen dieser Funktionalität verantwortlich wäre. Irgendwie habe ich es beim Erstellen übersehen. Kein Problem, wir erstellen es jetzt. Wir gehen auf GitHub zur Registerkarte „Issue-Erstellung“ und wählen „Feature Request“ aus: Fügen Sie eine Beschreibung der Aufgabe und Kriterien für ihre Annahme hinzu, legen Sie fest, zu welchem Projekt dieses Issue gehört, und Sie können ein neues Issue erstellen: Jetzt, um zu zeigen, dass die Aufgabe erledigt wurde Zur Arbeit angenommen, ändern Sie den Status der Aufgabe von „Zu erledigen“ auf „In Bearbeitung“: Dies wird ein schwieriger Artikel. Wenn Sie Probleme haben, schreiben Sie in die Kommentare: Ich werde diese nach besten Kräften überwachen und beantworten. Dies wird ein kleiner Kundensupport sein :DErstellen einer Docker-Datei
Was ist eine Docker-Datei? Für Docker ist dies ein Skript (Schritt-für-Schritt-Anleitung) zum Erstellen eines Images für einen Docker-Container. Damit unsere Anwendung funktioniert, benötigen wir das JDK, und zwar Version 11. Das heißt, wir müssen das JDK 11-Docker-Image finden und es unserem Image hinzufügen. Dies ähnelt in etwa der Art und Weise, wie wir einer Erinnerung eine Abhängigkeit hinzufügen. Zu diesem Zweck verfügt Docker über DockerHub . Um Bilder lokal herunterzuladen, müssen Sie sich dort registrieren. Suchen wir nach der Registrierung nach JDK11. Nach meinen Erkenntnissen ist dies der Container: adoptopenjdk/openjdk11 . Die Beschreibung dieses Containers enthält alles, was für die Docker-Datei benötigt wird:FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
Lassen Sie uns den Ordner reparieren, aus dem wir die JAR-Datei entnehmen. Wir haben es im Zielordner, nachdem wir die Maven-Aufgabe „MVN-Paket“ ausgeführt haben. Bevor wir das alles tun, erstellen wir basierend auf dem aktualisierten Hauptzweig einen neuen für unsere Aufgabe: STEP_4_JRTB-13 . Jetzt können Sie arbeiten. Erstellen Sie im Stammverzeichnis des Projekts eine Datei ohne die Dockerfile -Erweiterung und fügen Sie Folgendes hinzu:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Die erste Zeile gibt an, worauf das Bild basieren wird: adoptopenjdk/openjdk11. Die zweite Zeile besteht darin, dem Bild ein Argument namens JAR_FILE hinzuzufügen, das sich im Zielordner befindet. Darüber hinaus wird der aktuelle Ordner durch den Speicherort der Docker-Datei bestimmt. Dritte Zeile – Kopieren Sie das JAR unseres Projekts in das Docker-Image. Die letzte Zeile enthält im Wesentlichen ein durch Leerzeichen getrenntes Array, das aus dem Befehl im Terminal erstellt wurde. Das heißt, am Ende wird Folgendes ausgeführt: „java -jar /app.jar“ Um das Bot-Token geheim zu halten, müssen wir beim Starten des Containers zwei Variablen übergeben – den Namen des Bots und sein Token. Dazu schreiben wir eine Abfrage, die unser Projekt mit Variablen starten soll. Und wie geht das? Sie müssen es googeln: Hier ist der erste Link mit einer normalen Beschreibung. Was wollen wir machen? Wir haben zwei Variablen in der Datei application.properties, die wir dort definieren:
- bot.Benutzername
- bot.token
- Lassen Sie uns das Bash-Skript ausführen.
- Das Bash-Skript führt Docker-Compose aus.
- Docker-Compose startet einen Docker-Container mit unserer Anwendung.
- Der Docker-Container führt unsere Anwendung aus.
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}", "-jar", "/app.jar"]
Sie können sehen, dass wir zwei Zeilen hinzugefügt und ENTRYPOINT aktualisiert haben. Linien:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
Deklarieren Sie Variablen in der Encoderdatei. Standardmäßig ist für sie ein Wert angegeben. Wenn beim Erstellen eines Images aus dieser Docker-Datei Umgebungsvariablen mit solchen Namen übergeben werden, sind die Werte unterschiedlich. Und in ENTRYPOINT haben wir ein paar weitere Elemente hinzugefügt, die diese Umgebungsvariablen lesen:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
Hier können Sie sehen, dass innerhalb der Zeile mithilfe des ${}-Konstrukts die Werte von BOT_NAME und BOT_TOKEN übergeben werden. Als nächstes müssen wir lehren, wie man diese Variablen empfängt und an Docker-Compose weitergibt.
Erstellen Sie docker-compose.yml
Es wäre gut, wenn Sie sich separat mit dem YAML-Format befassen, sonst wächst der Artikel bereits sprunghaft. Für uns ist dies nur eine weitere Beschreibung von Variablen vom Typ .properties. Nur in Eigenschaften wird es durch einen Punkt geschrieben, aber in YAML geht das etwas schöner. Zum Beispiel so. Zwei Variablen in .properties: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin Aber in .yaml (das gleiche wie .yml) wird es so sein:javarush:
telegram:
bot:
name: ivan
token: pupkin
Die zweite Option ist schöner und verständlicher. Die Leerzeichen sollten genau wie oben angegeben sein. Lassen Sie uns unsere application.properties und application.yml irgendwie übersetzen. Zuerst müssen Sie es erstellen. Erstellen Sie im Stammverzeichnis des Projekts eine Datei docker-compose.yml und schreiben Sie dort Folgendes:
version: '3.1'
services:
jrtb:
build:
context: .
environment:
- BOT_NAME=${BOT_NAME}
- BOT_TOKEN=${BOT_TOKEN}
restart: always
Die erste Zeile ist die Docker-Compose-Version. Services: besagt, dass sich alle folgenden Zeilen (werden verschoben) auf die Dienste beziehen, die wir konfigurieren. Bisher haben wir nur eine davon – eine Java-Anwendung namens jrtb . Und bereits darunter befinden sich alle Einstellungen. Beispiel: build: context: . sagt, dass wir nach der Docker-Datei im selben Verzeichnis wie docker-compose.yml suchen werden. Der Abschnitt „environment:“ ist jedoch dafür verantwortlich, dass wir die erforderlichen Umgebungsvariablen an die Docker-Datei übergeben. Genau das, was wir brauchen. Daher übergeben wir unten Variablen. Docker-Compose sucht in den Variablen der Server-Betriebsumgebung danach. Fügen wir sie dem Bash-Skript hinzu.
Bash-Skripte erstellen
Der letzte Schritt besteht darin, ein Bash-Skript zu erstellen. Erstellen Sie eine Datei namens start.sh im Stammverzeichnis des Projekts und schreiben Sie dort Folgendes:#!/bin/bash
# Pull new changes
git pull
# Prepare Jar
mvn clean
mvn package
# Ensure, that docker-compose stopped
docker-compose stop
# Add environment variables
export BOT_NAME=$1
export BOT_TOKEN=$2
# Start new deployment
docker-compose up --build -d
Die erste Zeile wird für alle Bash-Skripte benötigt: Ohne sie funktioniert es nicht. Und dann – nur noch eine Reihe von Befehlen im Terminal, die ausgeführt werden müssen. Ich habe jedem Befehl Kommentare hinzugefügt, damit es klar ist. Das Einzige, was ich erklären möchte, ist, was 1 $ und 2 $ bedeuten. Dies sind zwei Variablen, die beim Start des Bash-Skripts übergeben werden. Mit dem Export-Befehl werden sie zu den Servervariablen hinzugefügt und in Docker-Compose eingelesen. Das funktioniert für Ubuntu, wahrscheinlich nicht für Windows, aber ich bin mir nicht sicher. Jetzt müssen Sie das Skript stop.sh hinzufügen, das die Arbeit stoppt. Es wird mehrere Zeilen enthalten:
#!/bin/bash
# Ensure, that docker-compose stopped
docker-compose stop
# Ensure, that the old application won't be deployed again.
mvn clean
Hier stoppen wir Docker-Compose und bereinigen das Projekt Jarnik, das seit dem letzten Build herumliegt. Wir tun dies, um sicherzustellen, dass unser Projekt korrekt nachgebaut wird. Es gab Präzedenzfälle, deshalb füge ich hinzu) Als Ergebnis haben wir am Ende 4 neue Dateien:
- Dockerfile – eine Datei zum Erstellen eines Images unserer Anwendung;
- docker-compose.yml – eine Datei mit Einstellungen dafür, wie wir unsere Container starten;
- start.sh – Bash-Skript zum Bereitstellen unserer Anwendung;
- stop.sh ist ein Bash-Skript zum Stoppen unserer Anwendung.
# Versionshinweise ## 0.3.0-SNAPSHOT * JRTB-13: Bereitstellungsprozess zum Projekt hinzugefügt ## 0.2.0-SNAPSHOT * JRTB-3: Befehlsmuster für die Handhabung von Telegram Bot-Befehlen implementiert ## 0.1.0-SNAPSHOT * JRTB -2: Stub-Telegramm-Bot hinzugefügt * JRTB-0: SpringBoot-Skelettprojekt hinzugefügt
Und in der README-Datei werden wir einen neuen Absatz hinzufügen, der beschreibt, wie wir unsere Anwendung bereitstellen:
## Bereitstellung Bereitstellungsprozess so einfach wie möglich: Erforderliche Software: – Terminal zum Ausführen von Bash-Skripten – Docker – Docker-Compose zum Bereitstellen der Anwendung, wechseln Sie zum erforderlichen Zweig und führen Sie das Bash-Skript aus: $ bash start.sh ${bot_username} ${bot_token } Das ist alles.
Natürlich ist alles auf Englisch geschrieben. Wie üblich erstellen wir in unserem neu erstellten Zweig STEP_4_JRTB-13 einen neuen Commit mit dem Namen: JRTB-13: Implementierungsprozess über Docker implementieren und pushen. Ich höre auf, mich ausführlich mit Dingen zu befassen, die ich bereits in früheren Artikeln beschrieben habe. Ich sehe keinen Sinn darin, dasselbe zu wiederholen. Außerdem werden diejenigen, die es selbst herausgefunden und durchgeführt haben, keine Fragen haben. Ich spreche davon, wie man einen neuen Zweig erstellt, wie man einen Commit erstellt und wie man einen Commit in das Repository überträgt.
GO TO FULL VERSION