Cześć wszystkim. Kontynuujemy cykl artykułów na temat pisania Twojego projektu.
Sortuj gałęzie
Co ważne, aby nie zgubić się w gałęziach i ich kolejności w repozytorium, zdecydowałem się zmienić ich nazwy, dodając przedrostek STEP_{number} . Na przykład oprócz głównego mamy trzy gałęzie:- JRTB-0
- JRTB-2
- JRTB-3
- STEP_1_JRTB-0 - pierwszy krok
- STEP_2_JRTB-2 - krok drugi
- STEP_3_JRTB-3 - krok trzeci
Trochę o Dockerze
Co to jest Docker? Krótko mówiąc, jest to narzędzie, za pomocą którego można szybko i bezpiecznie wdrażać (wdrażać) aplikacje, tworząc dla nich zamkniętą infrastrukturę, która jest im tylko niezbędna. Rozumiem, że to nadal trudne. Ogólnie Docker można rozumieć jako platformę programistyczną, na której można pracować szybko i efektywnie. Dockera można rozumieć jako program działający na serwerze. Program ten posiada możliwość przechowywania kontenerów z aplikacjami. Co to jest kontener? To osobna infrastruktura, do której możesz dodać wszystko, czego potrzebujesz. Na przykład dla aplikacji Java potrzebujemy środowiska JRE do uruchomienia aplikacji, kontener będzie to miał, będziemy potrzebować innego oprogramowania - możemy to dodać. A może potrzebujemy Linuksa i kontenera serwletów Tomcat. Można to również zrobić. Kontenery tworzone są na podstawie obrazu: czyli jest to konkretny szablon, który zawiera wszystko co niezbędne do stworzenia kontenera Docker. Jak stworzyć taki obraz? W naszym przypadku będziemy musieli utworzyć plik Dockerfile w katalogu głównym projektu opisujący, co powinno znajdować się w kontenerze. Ponieważ nie chcemy nigdzie ujawniać tokena bota, będziemy musieli uciekać się do przekazywania go za każdym razem, gdy będziemy chcieli wdrożyć aplikację. Więcej na ten temat można przeczytać tutaj i tutaj .Piszemy JRTB-13
Musimy skonfigurować szybki i łatwy proces wdrażania naszej aplikacji na serwer. To znaczy dla maszyny, która pracuje 24 godziny na dobę, 7 dni w tygodniu. Za podstawę weźmy Dockera. Ale na naszej liście nie ma zadania, które byłoby odpowiedzialne za dodanie tej funkcjonalności. Jakoś mi tego umknęło podczas tworzenia. Nie ma problemu, stworzymy to teraz. Przejdź do zakładki tworzenia zgłoszenia w GitHubie i wybierz Prośbę o funkcję: Dodaj opis zadania, kryteria jego akceptacji, ustal, do jakiego projektu należy to zgłoszenie i możesz utworzyć nowe zgłoszenie: Teraz, aby pokazać, że zadanie zostało zaakceptowane do pracy, zmień status zadania z Do zrobienia na W toku: To będzie trudny artykuł. Jeśli masz jakieś problemy, napisz w komentarzach: Będę je monitorować i odpowiadać na nie najlepiej jak potrafię. To będzie mała obsługa klienta :DTworzenie pliku Dockerfile
Co to jest plik docker? W przypadku Dockera jest to skrypt (instrukcje krok po kroku) dotyczące tworzenia obrazu dla kontenera Docker. Aby nasza aplikacja działała potrzebujemy JDK w wersji 11. Oznacza to, że musimy znaleźć obraz okna dokowanego JDK 11 i dodać go do naszego obrazu. Przypomina to sposób dodawania zależności do pamięci. Docker ma w tym celu DockerHub . Aby pobierać obrazy lokalnie, musisz się tam zarejestrować. Po rejestracji przejdźmy do szukania JDK11. Z tego, co znalazłem, jest to kontener: adoptopenjdk/openjdk11 . Opis tego kontenera zawiera informacje potrzebne do pliku dokowanego:FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
Naprawmy folder, z którego bierzemy plik jar. Mamy go w folderze docelowym po uruchomieniu zadania maven pakietu mvn. Zanim to wszystko zrobimy, w oparciu o zaktualizowaną gałąź główną, tworzymy nową dla naszego zadania: STEP_4_JRTB-13 . Teraz możesz pracować. W katalogu głównym projektu utwórz plik bez rozszerzenia Dockerfile i dodaj w nim następujące elementy:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Pierwsza linia określa, na czym będzie oparty obraz - adoptopenjdk/openjdk11. Druga linia polega na dodaniu argumentu do obrazu o nazwie JAR_FILE, który znajduje się w folderze docelowym. Co więcej, bieżący folder jest określany na podstawie lokalizacji pliku Dockerfile. Trzecia linia - skopiuj słoik naszego projektu do obrazu okna dokowanego. Ostatnia linia zasadniczo zawiera tablicę utworzoną na podstawie polecenia w terminalu, oddzieloną spacją. Oznacza to, że na koniec zostanie wykonane: „java -jar /app.jar” Aby zachować token bota w tajemnicy, podczas uruchamiania kontenera będziemy musieli przekazać dwie zmienne - nazwę bota i jego token. W tym celu napiszemy zapytanie, które powinno uruchomić nasz projekt ze zmiennymi. Jak to zrobić? Musisz to sprawdzić w Google: tutaj jest pierwszy link z normalnym opisem. Co chcemy zrobić? W pliku application.properties mamy dwie zmienne, które tam definiujemy:
- bot.nazwa użytkownika
- bot.token
- Uruchommy skrypt bash.
- Skrypt bash uruchamia polecenie docker-compose.
- Docker-compose uruchamia kontener dokowany z naszą aplikacją.
- Kontener Docker uruchamia naszą aplikację.
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"]
Widać, że dodaliśmy dwie linie i zaktualizowaliśmy ENTRYPOINT. Linie:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
zadeklaruj zmienne w pliku kodera. Domyślnie mają określoną wartość. Jeśli podczas tworzenia obrazu z tego pliku dokowanego zostaną przekazane zmienne środowiskowe o takich nazwach, wartości będą inne. W ENTRYPOINT dodaliśmy jeszcze kilka elementów, które będą czytać te zmienne środowiskowe:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
Tutaj widać, że wewnątrz linii za pomocą konstrukcji ${} zostaną przekazane wartości BOT_NAME i BOT_TOKEN. Następnie musimy nauczyć się odbierać i przekazywać te zmienne do narzędzia docker-compose.
Utwórz plik docker-compose.yml
Dobrze byłoby, gdybyś przeczytał o formacie YAML osobno, w przeciwnym razie artykuł już rozrasta się skokowo. Dla nas jest to po prostu kolejny opis zmiennych typu .properties. Tylko we właściwościach jest to zapisane przez kropkę, ale w YAML robi się to trochę ładniej. Na przykład tak. Dwie zmienne w .properties: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin Ale w .yaml (tak samo jak .yml) będzie to wyglądało tak:javarush:
telegram:
bot:
name: ivan
token: pupkin
Druga opcja jest piękniejsza i zrozumiała. Odstępy powinny być dokładnie takie, jak wskazano powyżej. Przetłumaczmy jakoś nasze application.properties i application.yml. Najpierw musisz go stworzyć. W katalogu głównym projektu utwórz plik docker-compose.yml i wpisz tam:
version: '3.1'
services:
jrtb:
build:
context: .
environment:
- BOT_NAME=${BOT_NAME}
- BOT_TOKEN=${BOT_TOKEN}
restart: always
Pierwsza linia to wersja docker-compose. Services: mówi, że wszystkie kolejne wiersze (zostaną przesunięte) odnoszą się do usług, które konfigurujemy. Jak dotąd mamy tylko jedną taką aplikację - aplikację Java o nazwie jrtb . I już pod nim będą wszystkie jego ustawienia. Na przykład build: kontekst: . mówi, że będziemy szukać pliku Dockerfile w tym samym katalogu co docker-compose.yml. Jednak sekcja środowiskowa: będzie odpowiedzialna za zapewnienie przekazania niezbędnych zmiennych środowiskowych do pliku Dockerfile. Tylko to, czego potrzebujemy. Dlatego poniżej przekazujemy zmienne. Docker-compose będzie ich szukać w zmiennych środowiskowych serwera operacyjnego. Dodajmy je do skryptu bash.
Tworzenie skryptów basha
Ostatnim krokiem jest utworzenie skryptu bash. Utwórz plik o nazwie start.sh w katalogu głównym projektu i wpisz tam:#!/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
Pierwsza linia jest potrzebna dla wszystkich skryptów basha: bez niej nie będzie działać. A potem - tylko zestaw poleceń w terminalu, które należy wykonać. Dodałem komentarze do każdego polecenia, więc powinno być jasne. Jedyne, co chcę wyjaśnić, to co oznaczają 1 dolar i 2 dolary. Są to dwie zmienne, które zostaną przekazane po uruchomieniu skryptu bash. Za pomocą polecenia eksportu zostaną one dodane do zmiennych serwera i odczytane w programie docker-compose. Działa to w przypadku Ubuntu, prawdopodobnie nie w przypadku Windows, ale nie jestem pewien. Teraz musisz dodać skrypt stop.sh, który zatrzyma pracę. Będzie zawierał kilka linii:
#!/bin/bash
# Ensure, that docker-compose stopped
docker-compose stop
# Ensure, that the old application won't be deployed again.
mvn clean
W tym miejscu zatrzymujemy tworzenie dokera i sprzątamy jarnik projektu, który leżał od ostatniej kompilacji. Robimy to po to, aby mieć pewność, że nasz projekt zostanie poprawnie odbudowany. Były precedensy, dlatego dodaję) W rezultacie otrzymujemy 4 nowe pliki:
- Dockerfile – plik umożliwiający utworzenie obrazu naszej aplikacji;
- docker-compose.yml - plik z ustawieniami dotyczącymi sposobu uruchamiania naszych kontenerów;
- start.sh - skrypt bashowy do wdrożenia naszej aplikacji;
- stop.sh to skrypt basha zatrzymujący naszą aplikację.
# Informacje o wydaniu ## 0.3.0-SNAPSHOT * JRTB-13: dodano proces wdrażania do projektu ## 0.2.0-SNAPSHOT * JRTB-3: zaimplementowano Wzorzec poleceń do obsługi poleceń Telegram Bot ## 0.1.0-SNAPSHOT * JRTB -2: dodano bota telegramowego * JRTB-0: dodano projekt szkieletu SpringBoot
A w README dodamy nowy akapit opisujący sposób wdrożenia naszej aplikacji:
## Wdrożenie Proces wdrażania tak prosty, jak to możliwe: Wymagane oprogramowanie: - terminal do uruchamiania skryptów bash - docker - docker-compose w celu wdrożenia aplikacji, przejdź do potrzebnej gałęzi i uruchom skrypt bash: $ bash start.sh ${bot_username} ${bot_token } To wszystko.
Oczywiście wszystko jest napisane w języku angielskim. Jak zwykle w naszej nowo utworzonej gałęzi STEP_4_JRTB-13 tworzymy nowy commit o nazwie: JRTB-13: zaimplementuj proces wdrażania poprzez okno dokowane i wypchnij go. Przestaję szczegółowo rozwodzić się nad rzeczami, które opisałem już w poprzednich artykułach. Nie widzę sensu powtarzania tego samego. Poza tym ci, którzy to wymyślili i sami to zrobili, nie będą mieli żadnych pytań. To ja mówię o tym, jak utworzyć nową gałąź, jak utworzyć zatwierdzenie, jak wypchnąć zatwierdzenie do repozytorium.
GO TO FULL VERSION