JavaRush /وبلاگ جاوا /Random-FA /ما استقرار برنامه را اجرا می کنیم - "پروژه جاوا از A تا Z...
Roman Beekeeper
مرحله

ما استقرار برنامه را اجرا می کنیم - "پروژه جاوا از A تا Z"

در گروه منتشر شد
سلام به همه. ما به مجموعه مقالات در مورد نوشتن پروژه شما ادامه می دهیم. "پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 1

شاخه ها را مرتب کنید

نکته مهم این است که برای گم نشدن در شعب و ترتیب آنها در مخزن، تصمیم گرفتم با اضافه کردن پیشوند STEP_{number} نام آنها را تغییر دهم . به عنوان مثال، ما علاوه بر شاخه اصلی، سه شاخه داریم:
  • JRTB-0
  • JRTB-2
  • JRTB-3
شما فوراً متوجه نخواهید شد که کدام یک باید بعد از آن بروید. بنابراین نام آنها را به صورت زیر تغییر می دهم:
  • STEP_1_JRTB-0 - مرحله اول
  • STEP_2_JRTB-2 - مرحله دوم
  • STEP_3_JRTB-3 - مرحله سوم
و به همین ترتیب برای مقالات بعدی. برای تغییر نام شاخه ها، به صفحه مخزن بروید، کادر شاخه ها را پیدا کنید ، آن را دنبال کنید: "پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 2در زیر هر شاخه، روی مداد کلیک کنید و نام شاخه را تغییر دهید: "پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 3و در نتیجه دریافت می کنیم: اتفاقاً، هرکسی که در کانال تلگرام من"پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 4 مشترک شد، پیدا کرد. بلافاصله که من شاخه ها را تغییر نام دادم.

کمی در مورد داکر

داکر چیست؟ به طور خلاصه، این ابزاری است که با آن می توانید به سرعت و ایمن برنامه ها را مستقر کنید (استقرار دهید) و یک زیرساخت بسته برای آنها ایجاد کنید که فقط برای آنها ضروری است. هنوزم سخته میفهمم به طور کلی، Docker را می توان به عنوان یک پلت فرم توسعه که در آن می توانید سریع و کارآمد کار کنید، درک کرد. Docker را می توان به عنوان برنامه ای درک کرد که روی یک سرور اجرا می شود. این برنامه قابلیت ذخیره کانتینرهای دارای اپلیکیشن را دارد. ظرف چیست؟ این یک زیرساخت جداگانه است که می توانید هر آنچه را که نیاز دارید به آن اضافه کنید. به عنوان مثال، برای یک برنامه جاوا ما به یک JRE برای اجرای برنامه نیاز داریم، کانتینر این را خواهد داشت، ما به نرم افزار دیگری نیاز داریم - می توانیم این را اضافه کنیم. یا شاید ما به لینوکس و یک ظرف سرولت تامکت نیاز داشته باشیم. این نیز قابل انجام است. کانتینرها بر اساس یک تصویر ایجاد می شوند: یعنی این یک الگوی خاص است که شامل همه چیزهایی است که برای ایجاد یک ظرف Docker لازم است. چگونه این تصویر را ایجاد کنیم؟ در مورد ما، باید یک Dockerfile در ریشه پروژه ایجاد کنیم که توضیح دهد چه چیزی باید در ظرف باشد. از آنجایی که نمی‌خواهیم توکن ربات را در هر جایی افشا کنیم، باید هر بار که می‌خواهیم برنامه را اجرا کنیم، آن را ارسال کنیم. در اینجا و اینجا می توانید اطلاعات بیشتری در مورد این موضوع بخوانید .

ما JRTB-13 می نویسیم

ما باید یک فرآیند استقرار سریع و آسان را برای برنامه خود در سرور تنظیم کنیم. یعنی برای ماشینی که 24/7 کار می کند. بیایید داکر را به عنوان پایه در نظر بگیریم. اما هیچ وظیفه ای در لیست ما وجود ندارد که مسئول اضافه کردن این قابلیت باشد. به نوعی هنگام ایجاد آن از دست دادم. مشکلی نیست، اکنون آن را ایجاد می کنیم. به تب ایجاد مشکل در GitHub بروید و Feature Request را انتخاب کنید: "پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 5شرح کار، معیارهای پذیرش آن را اضافه کنید، تعیین کنید که این موضوع به کدام پروژه تعلق دارد و می توانید یک شماره جدید ایجاد کنید: "پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 6اکنون، برای نشان دادن اینکه کار پذیرفته شده است. برای کار، وضعیت کار را از To do on In Progress تغییر دهید: "پروژه جاوا از A تا Z": پیاده سازی استقرار برنامه - 7این مقاله دشواری خواهد بود. اگر مشکلی دارید در نظرات بنویسید: من در حد توانم آنها را رصد و پاسخ خواهم داد. این یک پشتیبانی مشتری کوچک خواهد بود :D

ایجاد یک Dockerfile

dockerfile چیست؟ برای Docker، این یک اسکریپت (دستورالعمل های گام به گام) در مورد نحوه ایجاد یک تصویر برای یک ظرف Docker است. برای اینکه برنامه ما کار کند، به JDK نسخه 11 نیاز داریم. یعنی باید تصویر docker JDK 11 را پیدا کرده و به تصویر خود اضافه کنیم. این چیزی شبیه به نحوه اضافه کردن یک وابستگی به یک حافظه است. Docker برای این منظور DockerHub دارد . برای دانلود تصاویر به صورت محلی، باید در آنجا ثبت نام کنید. پس از ثبت نام، بیایید به دنبال JDK11 بگردیم. از آنچه من پیدا کردم، این ظرف است: adoptopenjdk/openjdk11 . توضیحات این کانتینر دارای مواردی است که برای dockerfile نیاز است:
FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
بیایید پوشه ای را که فایل jar را از آن می گیریم درست کنیم. بعد از اجرای mvn package maven آن را در پوشه target داریم. قبل از انجام همه این کارها، بر اساس شاخه اصلی به روز شده، یک شاخه جدید برای وظیفه خود ایجاد می کنیم: STEP_4_JRTB-13 . حالا می توانید کار کنید. در روت پروژه یک فایل بدون پسوند Dockerfile ایجاد کنید و موارد زیر را داخل آن اضافه کنید:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
خط اول چیزی است که تصویر بر اساس آن خواهد بود - adoptopenjdk/openjdk11. خط دوم اضافه کردن آرگومان به تصویر با نام JAR_FILE است که در پوشه هدف قرار دارد. علاوه بر این، پوشه فعلی توسط محل Dockerfile تعیین می شود. خط سوم - شیشه پروژه ما را در تصویر داکر کپی کنید. خط آخر اساساً حاوی آرایه ای است که از دستور در ترمینال ایجاد شده است که با فاصله از هم جدا شده است. یعنی در نهایت موارد زیر اجرا می‌شود: “java -jar /app.jar” برای مخفی نگه داشتن رمز ربات، هنگام راه‌اندازی ظرف، باید دو متغیر را ارسال کنیم - نام ربات و توکن آن. برای انجام این کار، یک پرس و جو می نویسیم که باید پروژه ما را با متغیرها راه اندازی کند. و چگونه آن را انجام دهیم؟ شما باید آن را در گوگل جستجو کنید: این اولین لینک با توضیحات عادی است. می خواهیم چه کار کنیم؟ ما دو متغیر در فایل application.properties داریم که در آنجا تعریف می کنیم:
  • نام کاربری bot
  • bot.token
من می‌خواهم یک داکر کانتینر را اجرا کنم و هر بار مقدار خود را به آنجا منتقل کنم تا کسی نتواند این مقادیر را ببیند. می دانم که در SpringBoot، متغیرهای محیطی که هنگام راه اندازی پروژه jar تنظیم می شوند، بر متغیرهای موجود در فایل application.properties اولویت دارند. برای ارسال یک متغیر در یک درخواست، باید ساختار زیر را اضافه کنید: -D{variable name}=”{variable value}” . ما بریس های فرفری اضافه نمی کنیم ؛) درخواستی دریافت می کنیم که برنامه ما را با مقادیر از پیش تعریف شده راه اندازی می کند - نام و نشانه ربات: java -jar -Dbot.username=”test.javarush.community_bot” -Dbot. token=”dfgkdjfglkdjfglkdjfgk” *.jar حالا باید این متغیرها را داخل محفظه docker پاس کنیم. این یک متغیر محیطی است. برای اطمینان از اینکه در آینده پایگاه داده ما به خوبی و بدون مشکل با برنامه ما کار می کند، از docker-compose استفاده خواهیم کرد. این یک ابزار جداگانه است که در آن می توانید کار، راه اندازی و وابستگی ها را بین کانتینرها سازماندهی کنید. به عبارت دیگر، یک افزونه در بالای Docker برای مدیریت کانتینرهای یک زیرساخت است. به علاوه، قبل از اجرای docker-compose، باید مطمئن شویم که همه تغییرات کد را از سرور خارج کرده ایم، برنامه را ساخته ایم و نسخه قدیمی را متوقف کرده ایم. برای این کار از اسکریپت bash استفاده می کنیم. وای... همه چیز سخت به نظر می رسد، موافقم. اما کار با راه اندازی استقرار برنامه همیشه یک فرآیند خسته کننده و پیچیده است. بنابراین، ما یک طرح بسیار خوب داریم:
  1. بیایید اسکریپت bash را اجرا کنیم.
  2. اسکریپت bash docker-compose را اجرا می کند.
  3. Docker-compose یک داکر کانتینر را با برنامه ما راه اندازی می کند.
  4. ظرف Docker برنامه ما را اجرا می کند.
و اکنون باید مطمئن شویم که دو متغیر - نام ربات و توکن آن - از نقطه 1 به نقطه 4 می روند. و به این ترتیب که این دو متغیر هنگام راه اندازی برنامه جاوا ما استفاده شوند. از آخر به اول برویم. ما قبلاً می دانیم که برای شروع jarnik چه دستوری باید اجرا شود. بنابراین، ما Dockerfile را طوری پیکربندی می کنیم که یاد بگیرد دو متغیر را بپذیرد و آنها را به درخواست ارسال کند. برای انجام این کار، اجازه دهید Dockerfile را به شکل زیر کاهش دهیم:
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"]
می بینید که ما دو خط اضافه کردیم و ENTRYPOINT را به روز کردیم. خطوط:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
متغیرها را در داخل فایل رمزگذار اعلام کنید. آنها به طور پیش فرض دارای یک مقدار مشخص هستند. اگر هنگام ایجاد یک تصویر از این dockerfile، متغیرهای محیطی با چنین نام هایی ارسال شوند، مقادیر متفاوت خواهند بود. و در ENTRYPOINT چند عنصر دیگر اضافه کردیم که این متغیرهای محیطی را می‌خوانند:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
در اینجا می بینید که در داخل خط، با استفاده از ساختار ${}، مقادیر BOT_NAME و BOT_TOKEN ارسال می شود. در مرحله بعد، باید نحوه دریافت و ارسال این متغیرها به docker-compose را آموزش دهیم.

docker-compose.yml را ایجاد کنید

خوب است که در مورد فرمت YAML به طور جداگانه مطالعه کنید، در غیر این صورت مقاله در حال رشد است. برای ما، این فقط توضیح دیگری از متغیرهای نوع .properties است. فقط در ویژگی ها از طریق نقطه نوشته می شود، اما در YAML این کار کمی زیباتر انجام می شود. مثلا اینجوری دو متغیر در .properties: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin اما در .yaml (همان .yml) به این صورت خواهد بود:
javarush:
	telegram:
		bot:
		  name: ivan
		  token: pupkin
گزینه دوم زیباتر و قابل فهم تر است. فضاها باید دقیقاً همانطور که در بالا نشان داده شده باشد. بیایید application.properties و application.yml خود را به نحوی ترجمه کنیم. ابتدا باید آن را ایجاد کنید. در ریشه پروژه، یک فایل docker-compose.yml ایجاد کنید و موارد زیر را در آنجا بنویسید:
version: '3.1'

services:
 jrtb:
   build:
     context: .
   environment:
     - BOT_NAME=${BOT_NAME}
     - BOT_TOKEN=${BOT_TOKEN}
   restart: always
خط اول نسخه docker-compose است. services: می گوید که تمام خطوط زیر بعد از این (تغییر خواهد شد) به سرویس هایی که در حال پیکربندی هستیم اشاره دارد. ما تا کنون تنها یکی از اینها را داریم - یک برنامه جاوا به نام jrtb . و در حال حاضر در زیر آن تمام تنظیمات آن خواهد بود. برای مثال build: context: . می گوید که ما به دنبال Dockerfile در همان دایرکتوری docker-compose.yml خواهیم بود. اما بخش محیط: وظیفه اطمینان از اینکه متغیرهای محیطی لازم را به Dockerfile منتقل می کنیم، خواهد بود. فقط چیزی که ما نیاز داریم بنابراین، متغیرهای زیر را پاس می کنیم. Docker-compose آنها را در متغیرهای محیط عامل سرور جستجو می کند. بیایید آنها را به اسکریپت bash اضافه کنیم.

ایجاد اسکریپت های bash

آخرین مرحله ایجاد یک اسکریپت bash است. یک فایل به نام start.sh در ریشه پروژه ایجاد کنید و موارد زیر را در آنجا بنویسید:
#!/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
خط اول برای همه اسکریپت های bash مورد نیاز است: بدون آن کار نخواهد کرد. و سپس - فقط مجموعه ای از دستورات در ترمینال که باید اجرا شوند. من نظراتی را در هر دستور اضافه کرده ام بنابراین باید واضح باشد. تنها چیزی که می خواهم توضیح دهم این است که $1 و $2 به چه معناست. این دو متغیر هستند که هنگام راه‌اندازی اسکریپت bash پاس داده می‌شوند. با استفاده از دستور صادرات، آنها به متغیرهای سرور اضافه می شوند و در docker-compose خوانده می شوند. این برای اوبونتو کار می کند، احتمالا برای ویندوز نیست، اما من مطمئن نیستم. اکنون باید اسکریپت stop.sh را اضافه کنید که کار را متوقف می کند. این شامل چندین خط خواهد بود:
#!/bin/bash

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

# Ensure, that the old application won't be deployed again.
mvn clean
در اینجا ما Docker-compose را متوقف می کنیم و پروژه jarnik را که از آخرین ساخته شده در اطراف وجود دارد، تمیز می کنیم. ما این کار را انجام می دهیم تا اطمینان حاصل کنیم که پروژه ما با دقت بازسازی شده است. پیشینه هایی وجود داشت، به همین دلیل است که اضافه می کنم) در نتیجه، ما به 4 فایل جدید می رسیم:
  • Dockerfile - فایلی برای ایجاد تصویری از برنامه ما.
  • docker-compose.yml - فایلی با تنظیماتی برای نحوه راه‌اندازی کانتینرهای خود.
  • start.sh - اسکریپت bash برای استقرار برنامه ما.
  • stop.sh یک اسکریپت bash برای توقف برنامه ما است.
ما همچنین نسخه برنامه خود را از 0.2.0-SNAPSHOT به 0.3.0-SNAPSHOT به روز خواهیم کرد. بیایید شرحی از نسخه جدید را به RELEASE_NOTES اضافه کنیم و آنچه در آنجا بود را کمی اصلاح کنیم:
# یادداشت های انتشار ## 0.3.0-SNAPSHOT * JRTB-13: فرآیند استقرار اضافه شده به پروژه ## 0.2.0-SNAPSHOT * JRTB-3: الگوی فرمان پیاده سازی شده برای مدیریت دستورات ربات تلگرام ## 0.1.0-SNAPSHOT * JRTB -2: ربات خرد تلگرام اضافه شد * JRTB-0: پروژه اسکلت SpringBoot اضافه شد
و در README یک پاراگراف جدید اضافه می کنیم که نحوه استقرار برنامه را توضیح می دهد:
## استقرار فرآیند استقرار تا حد امکان آسان: نرم افزار مورد نیاز: - ترمینال برای اجرای اسکریپت های bash - docker - docker-compose برای استقرار برنامه، تغییر به شاخه مورد نیاز و اجرای اسکریپت bash: $ bash start.sh ${bot_username} ${bot_token } همین است.
البته همه چیز به زبان انگلیسی نوشته شده است. طبق معمول، در شعبه جدید STEP_4_JRTB-13 ما یک commit جدید با نام: JRTB-13: پیاده سازی فرآیند استقرار از طریق docker ایجاد می کنیم و آن را فشار می دهیم. من از پرداختن به جزئیات در مورد چیزهایی که قبلاً در مقالات قبلی توضیح داده ام، دست نمی کشم. من در تکرار همین موضوع فایده ای نمی بینم. علاوه بر این، کسانی که آن را فهمیدند و خودشان انجام دادند، هیچ سوالی نخواهند داشت. این من در مورد چگونگی ایجاد یک شعبه جدید، نحوه ایجاد یک commit، نحوه فشار دادن یک commit به مخزن صحبت می کنم.

خط پایین

امروز تعداد زیادی اطلاعات جدید را نشان دادم که باید با دقت مورد توجه قرار گیرد و با مطالعه بیشتر آنها را گسترش دهید. مهمترین چیز: با کمک دستور ONE (!!!) هر کاری که برای استقرار اپلیکیشن ما لازم است انجام می شود. این خیلی باحال است که حتی نمی توانم به شما بگویم. بله، من مجبور شدم زمان مناسبی را در مستندات Docker صرف کنم تا بفهمم چگونه متغیرها را به درستی ارسال کنم. ربات تلگرام از این پس همیشه بر روی آخرین نسخه شعبه اصلی کار خواهد کرد . لینک ربات تلگرام. امروز هیچ پیوندی به مطالبی که خواندن آنها خوب است وجود نخواهد داشت: مسئولیت با شماست. شما باید جستجوی اطلاعات را بیاموزید. همه کسانی که در کانال تلگرام من مشترک شدند تقریباً بلافاصله در مورد استقرار ربات مطلع شدند. دوستان پروژه را دوست دارید؟ به او ستاره بدهید ! به این ترتیب محبوبیت بیشتری پیدا می کند و افراد بیشتری می توانند در مورد آن بیاموزند و از آن بیاموزند. طبق معمول، پیشنهاد می‌کنم در GitHub ثبت نام کنید و حساب کاربری من را دنبال کنید تا این مجموعه و پروژه‌های دیگری که در آنجا کار می‌کنم را دنبال کنید. اکنون آماده اتصال پایگاه داده هستیم. مقاله بعدی طولانی تر خواهد بود و در آن ما تمام کارهای لازم برای کار با پایگاه داده را انجام خواهیم داد. همه توضیحات در JRTB-1 هستند .

فهرستی از تمام مواد این مجموعه در ابتدای این مقاله است.

نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION