JavaRush /Blog Java /Random-FR /Nous mettons en œuvre le déploiement d'applications - "Pr...
Roman Beekeeper
Niveau 35

Nous mettons en œuvre le déploiement d'applications - "Projet Java de A à Z"

Publié dans le groupe Random-FR
Salut tout le monde. Nous continuons la série d’articles sur l’écriture de votre projet. « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 1

Trier les branches

Point important, afin de ne pas me perdre dans les branches et leur ordre dans le référentiel, j'ai décidé de les renommer en ajoutant le préfixe STEP_{number} . Par exemple, nous avons trois branches en plus de la principale :
  • JRTB-0
  • JRTB-2
  • JRTB-3
Vous ne saurez pas immédiatement lequel choisir, puis lequel. Je vais donc les renommer comme suit :
  • STEP_1_JRTB-0 - première étape
  • STEP_2_JRTB-2 - deuxième étape
  • STEP_3_JRTB-3 - troisième étape
Et ainsi de suite pour les prochains articles. Pour renommer des branches, allez sur la page du référentiel , trouvez la case branches , suivez-la : « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 2Sous chaque branche, cliquez sur le crayon et renommez la branche : « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 3Et le résultat on obtient : « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 4Au fait, tous ceux qui se sont abonnés à ma chaîne télégramme ont trouvé immédiatement que j'ai renommé les branches.

Un peu sur Docker

Qu’est-ce que Docker ? En bref, c'est un outil avec lequel vous pouvez déployer (déployer) des applications rapidement et en toute sécurité, en créant pour elles une infrastructure fermée, nécessaire uniquement pour elles. C'est toujours difficile, je comprends. En général, Docker peut être compris comme une plateforme de développement sur laquelle vous pouvez travailler rapidement et efficacement. Docker peut être compris comme un programme qui s'exécute sur un serveur. Ce programme a la capacité de stocker des conteneurs avec des applications. Qu'est-ce qu'un conteneur ? Il s'agit d'une infrastructure distincte dans laquelle vous pouvez ajouter tout ce dont vous avez besoin. Par exemple, pour une application Java, nous avons besoin d'un JRE pour exécuter l'application, le conteneur l'aura, nous aurons besoin d'un autre logiciel - nous pouvons l'ajouter. Ou peut-être avons-nous besoin de Linux et d'un conteneur de servlets Tomcat. Cela peut également être fait. Les conteneurs sont créés sur la base d'une image : c'est-à-dire qu'il s'agit d'un modèle spécifique dans lequel est écrit tout le nécessaire pour créer un conteneur Docker. Comment créer cette image ? Dans notre cas, nous devrons créer un Dockerfile à la racine du projet décrivant ce qui doit contenir le conteneur. Puisque nous ne voulons exposer le jeton du bot nulle part, nous devrons le transmettre à chaque fois que nous souhaitons déployer l'application. Vous pouvez en savoir plus sur ce sujet ici et ici .

Nous écrivons JRTB-13

Nous devons mettre en place un processus de déploiement rapide et simple de notre application sur le serveur. Autrement dit, pour une machine qui fonctionne 24h/24 et 7j/7. Prenons Docker comme base. Mais aucune tâche sur notre liste ne serait responsable de l’ajout de cette fonctionnalité. D'une manière ou d'une autre, je l'ai manqué lors de sa création. Pas de problème, nous allons le créer maintenant. Nous allons dans l' onglet de création de problème sur GitHub et sélectionnons Demande de fonctionnalité : « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 5ajoutez une description de la tâche, des critères d'acceptation, définissez à quel projet appartient ce problème et vous pouvez créer un nouveau problème : « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 6maintenant, pour montrer que la tâche a été accepté pour le travail, changez le statut de la tâche de À faire à En cours : « Projet Java de A à Z » : Mise en œuvre du déploiement d'applications - 7Cela va être un article difficile. Si vous rencontrez des problèmes, écrivez dans les commentaires : je les surveillerai et y répondrai au mieux de mes capacités. Ce sera un petit support client :D

Création d'un fichier Docker

Qu'est-ce qu'un fichier docker ? Pour Docker, il s'agit d'un script (instructions étape par étape) expliquant comment créer une image pour un conteneur Docker. Pour que notre application fonctionne, nous avons besoin du JDK, version 11 en plus. Autrement dit, nous devons trouver l'image docker JDK 11 et l'ajouter à notre image. Cela ressemble à la façon dont nous ajoutons une dépendance à une mémoire. Docker a DockerHub à cet effet . Pour télécharger des images localement, vous devez vous y inscrire. Après l'enregistrement, allons chercher JDK11. D'après ce que j'ai trouvé, voici le conteneur : adoptopenjdk/openjdk11 . La description de ce conteneur contient ce qui est nécessaire pour le fichier docker :
FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
Corrigeons le dossier à partir duquel nous prenons le fichier jar. Nous l'avons dans le dossier cible après avoir exécuté la tâche maven du package mvn. Avant de faire tout cela, sur la base de la branche principale mise à jour, nous en créons une nouvelle pour notre tâche : STEP_4_JRTB-13 . Maintenant tu peux travailler. À la racine du projet, créez un fichier sans l' extension Dockerfile et ajoutez ce qui suit à l'intérieur :
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
La première ligne indique sur quoi l'image sera basée - adoptopenjdk/openjdk11. La deuxième ligne consiste à ajouter un argument à l'image nommé JAR_FILE, qui se trouve dans le dossier cible. De plus, le dossier actuel est déterminé par l'emplacement du Dockerfile. Troisième ligne - copiez le pot de notre projet dans l'image docker. La dernière ligne contient essentiellement un tableau créé à partir de la commande dans le terminal, séparé par un espace. Autrement dit, à la fin, ce qui suit sera exécuté : « java -jar /app.jar » Pour garder le jeton du bot secret, lors du démarrage du conteneur, nous devrons transmettre deux variables - le nom du bot et son jeton. Pour ce faire, nous allons écrire une requête qui devra lancer notre projet avec des variables. Et comment faire ? Vous devez le rechercher sur Google : voici le premier lien avec une description normale. Que voulons-nous faire ? Nous avons deux variables dans le fichier application.properties que nous y définissons :
  • bot.nom d'utilisateur
  • bot.jeton
Je souhaite exécuter un conteneur Docker et y transmettre ma valeur à chaque fois afin que personne ne puisse voir ces valeurs. Je sais que dans SpringBoot, les variables d'environnement définies lors du lancement du projet jar auront priorité sur celles du fichier application.properties. Pour passer une variable dans une requête, vous devez ajouter la construction suivante : -D{variable name}=”{variable value}” . Nous n'ajoutons pas d'accolades ;) Nous recevrons une requête qui lancera notre application avec des valeurs prédéfinies - le nom et le token du bot : java -jar -Dbot.username=”test.javarush.community_bot” -Dbot. token=”dfgkdjfglkdjfglkdjfgk” *.jar Nous devons maintenant transmettre ces variables dans le conteneur Docker. Il s'agit d'une variable d'environnement. Pour garantir qu'à l'avenir notre base de données fonctionne correctement et sans problème avec notre application, nous utiliserons docker-compose. Il s'agit d'un outil distinct dans lequel vous pouvez organiser le travail, le démarrage et les dépendances entre les conteneurs. En d’autres termes, il s’agit d’un module complémentaire à Docker pour gérer les conteneurs d’une infrastructure. De plus, avant d'exécuter docker-compose, nous devons être sûrs d'avoir extrait toutes les modifications de code du serveur, construit l'application et arrêté l'ancienne version. Pour cela, nous utiliserons un script bash. Wow... Tout cela semble difficile, je suis d'accord. Mais travailler à la configuration du déploiement d’applications est toujours un processus fastidieux et complexe. Par conséquent, nous avons un assez bon schéma :
  1. Exécutons le script bash.
  2. Le script bash exécute docker-compose.
  3. Docker-compose lance un conteneur Docker avec notre application.
  4. Le conteneur Docker exécute notre application.
Et maintenant nous devons nous assurer que deux variables - le nom du bot et son token - passent du point 1 au point 4. Et pour que ces deux variables soient utilisées lors du lancement de notre application java. Allons de la fin au début. Nous savons déjà quelle commande doit être exécutée pour démarrer le jarnik. Par conséquent, nous allons configurer le Dockerfile pour qu'il apprenne à accepter deux variables et à les transmettre à la requête. Pour ce faire, réduisons le Dockerfile à la forme suivante :
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"]
Vous pouvez voir que nous avons ajouté deux lignes et mis à jour ENTRYPOINT. Lignes:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
déclarez les variables dans le fichier de l'encodeur. Par défaut, ils ont une valeur spécifiée. Si, lors de la création d'une image à partir de ce fichier docker, des variables d'environnement portant de tels noms sont transmises, les valeurs seront différentes. Et dans ENTRYPOINT, nous avons ajouté quelques éléments supplémentaires qui liront ces variables d'environnement :
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
Ici, vous pouvez voir qu'à l'intérieur de la ligne, en utilisant la construction ${}, les valeurs de BOT_NAME et BOT_TOKEN seront transmises. Ensuite, nous devons apprendre à recevoir et transmettre ces variables à docker-compose.

Créer docker-compose.yml

Ce serait bien que vous lisiez séparément le format YAML, sinon l'article se développe déjà à pas de géant. Pour nous, il s'agit simplement d'une autre description des variables de type .properties. Uniquement dans les propriétés, il est écrit par un point, mais dans YAML, cela se fait un peu plus joliment. Par exemple, comme ça. Deux variables dans .properties : javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin Mais dans .yaml (le même que .yml) ce sera comme ceci :
javarush:
	telegram:
		bot:
		  name: ivan
		  token: pupkin
La deuxième option est plus belle et plus compréhensible. Les espaces doivent être exactement comme indiqué ci-dessus. Traduisons d'une manière ou d'une autre nos application.properties et application.yml. Vous devez d’abord le créer. À la racine du projet, créez un fichier docker-compose.yml et écrivez-y ce qui suit :
version: '3.1'

services:
 jrtb:
   build:
     context: .
   environment:
     - BOT_NAME=${BOT_NAME}
     - BOT_TOKEN=${BOT_TOKEN}
   restart: always
La première ligne est la version docker-compose. services : indique que toutes les lignes suivantes (seront décalées) font référence aux services que nous configurons. Nous n'en avons qu'un jusqu'à présent : une application Java appelée jrtb . Et déjà en dessous se trouveront tous ses paramètres. Par exemple, build: context: . dit que nous chercherons le Dockerfile dans le même répertoire que docker-compose.yml. Mais la section environnement: sera chargée de garantir que nous transmettons les variables d'environnement nécessaires au Dockerfile. Juste ce dont nous avons besoin. Par conséquent, nous passons les variables ci-dessous. Docker-compose les recherchera dans les variables d'environnement d'exploitation du serveur. Ajoutons-les au script bash.

Création de scripts bash

La dernière étape consiste à créer un script bash. Créez un fichier appelé start.sh à la racine du projet et écrivez-y ce qui suit :
#!/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
La première ligne est nécessaire pour tous les scripts bash : cela ne fonctionnera pas sans elle. Et puis - juste un ensemble de commandes dans le terminal qui doivent être exécutées. J'ai ajouté des commentaires dans chaque commande donc cela devrait être clair. La seule chose que je veux expliquer, c'est ce que signifient 1 $ et 2 $. Ce sont deux variables qui seront transmises au lancement du script bash. A l'aide de la commande export, elles seront ajoutées aux variables du serveur et lues dans docker-compose. Cela fonctionne pour Ubuntu, probablement pas pour Windows, mais je n'en suis pas sûr. Vous devez maintenant ajouter le script stop.sh, qui arrêtera le travail. Il contiendra plusieurs lignes :
#!/bin/bash

# Ensure, that docker-compose stopped
docker-compose stop

# Ensure, that the old application won't be deployed again.
mvn clean
Ici, nous arrêtons docker-compose et nettoyons le projet jarnik, qui traîne depuis la dernière build. Nous faisons cela pour garantir que notre projet est reconstruit avec précision. Il y avait des précédents, c'est pour ça que j'en rajoute) Du coup, on se retrouve avec 4 nouveaux fichiers :
  • Dockerfile - un fichier pour créer une image de notre application ;
  • docker-compose.yml - un fichier avec les paramètres sur la façon dont nous lancerons nos conteneurs ;
  • start.sh - script bash pour déployer notre application ;
  • stop.sh est un script bash pour arrêter notre application.
Nous mettrons également à jour la version de notre application de 0.2.0-SNAPSHOT à 0.3.0-SNAPSHOT. Ajoutons une description de la nouvelle version à RELEASE_NOTES et refactorisons légèrement ce qui s'y trouvait :
# Notes de version ## 0.3.0-SNAPSHOT * JRTB-13 : processus de déploiement ajouté au projet ## 0.2.0-SNAPSHOT * JRTB-3 : modèle de commande implémenté pour gérer les commandes Telegram Bot ## 0.1.0-SNAPSHOT * JRTB -2 : ajout d'un bot de télégramme stub * JRTB-0 : ajout du projet squelette SpringBoot
Et dans le README nous ajouterons un nouveau paragraphe décrivant comment déployer notre application :
## Déploiement Processus de déploiement aussi simple que possible : Logiciels requis : - terminal pour exécuter les scripts bash - docker - docker-compose pour déployer l'application, passer à la branche nécessaire et exécuter le script bash : $ bash start.sh ${bot_username} ${bot_token } C'est tout.
Bien entendu, tout est écrit en anglais. Comme d'habitude, dans notre branche nouvellement créée STEP_4_JRTB-13, nous créons un nouveau commit avec le nom : JRTB-13 : implémentez le processus de déploiement via docker et poussez-le. J'arrête de m'attarder en détail sur des choses que j'ai déjà décrites dans des articles précédents. Je ne vois pas l'intérêt de répéter la même chose. De plus, ceux qui l'ont compris et l'ont fait eux-mêmes n'auront aucune question. C'est moi qui parle de comment créer une nouvelle branche, comment créer un commit, comment pousser un commit vers le référentiel.

Conclusion

Aujourd'hui, j'ai montré une tonne de nouvelles informations qui doivent être soigneusement examinées et développées par des lectures supplémentaires. Le plus important : à l'aide d'UNE commande (!!!), tout le nécessaire au déploiement de notre application sera fait. C'est tellement cool que je ne peux même pas vous le dire. Oui, j'ai dû passer pas mal de temps dans la documentation Docker pour comprendre comment transférer correctement les variables. Désormais, le bot Telegram fonctionnera toujours sur la dernière version de la branche principale. Lien vers le bot de télégramme. Aujourd'hui, il n'y aura pas de liens vers des documents qu'il serait bon de lire : la responsabilité vous incombe. Vous devez apprendre à rechercher des informations. Tous ceux qui se sont abonnés à ma chaîne de télégrammes ont été informés presque immédiatement du déploiement du robot. Les amis, vous aimez le projet ? Donnez-lui une étoile ! De cette façon, il deviendra plus populaire et davantage de personnes pourront en apprendre davantage et en tirer des leçons. Comme d'habitude, je suggère de vous inscrire sur GitHub et de suivre mon compte pour suivre cette série et mes autres projets sur lesquels je travaille. Nous sommes maintenant prêts à connecter la base de données. Le prochain article sera plus long et nous y ferons tout le nécessaire pour travailler avec la base de données. Toutes les descriptions sont dans JRTB-1 .

Une liste de tous les matériaux de la série se trouve au début de cet article.

Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION