سلام به همه. ما به مجموعه مقالات در مورد نوشتن پروژه شما ادامه می دهیم.
شاخه ها را مرتب کنید
نکته مهم این است که برای گم نشدن در شعب و ترتیب آنها در مخزن، تصمیم گرفتم با اضافه کردن پیشوند STEP_{number} نام آنها را تغییر دهم . به عنوان مثال، ما علاوه بر شاخه اصلی، سه شاخه داریم:- JRTB-0
- JRTB-2
- JRTB-3
- STEP_1_JRTB-0 - مرحله اول
- STEP_2_JRTB-2 - مرحله دوم
- STEP_3_JRTB-3 - مرحله سوم
کمی در مورد داکر
داکر چیست؟ به طور خلاصه، این ابزاری است که با آن می توانید به سرعت و ایمن برنامه ها را مستقر کنید (استقرار دهید) و یک زیرساخت بسته برای آنها ایجاد کنید که فقط برای آنها ضروری است. هنوزم سخته میفهمم به طور کلی، Docker را می توان به عنوان یک پلت فرم توسعه که در آن می توانید سریع و کارآمد کار کنید، درک کرد. Docker را می توان به عنوان برنامه ای درک کرد که روی یک سرور اجرا می شود. این برنامه قابلیت ذخیره کانتینرهای دارای اپلیکیشن را دارد. ظرف چیست؟ این یک زیرساخت جداگانه است که می توانید هر آنچه را که نیاز دارید به آن اضافه کنید. به عنوان مثال، برای یک برنامه جاوا ما به یک JRE برای اجرای برنامه نیاز داریم، کانتینر این را خواهد داشت، ما به نرم افزار دیگری نیاز داریم - می توانیم این را اضافه کنیم. یا شاید ما به لینوکس و یک ظرف سرولت تامکت نیاز داشته باشیم. این نیز قابل انجام است. کانتینرها بر اساس یک تصویر ایجاد می شوند: یعنی این یک الگوی خاص است که شامل همه چیزهایی است که برای ایجاد یک ظرف Docker لازم است. چگونه این تصویر را ایجاد کنیم؟ در مورد ما، باید یک Dockerfile در ریشه پروژه ایجاد کنیم که توضیح دهد چه چیزی باید در ظرف باشد. از آنجایی که نمیخواهیم توکن ربات را در هر جایی افشا کنیم، باید هر بار که میخواهیم برنامه را اجرا کنیم، آن را ارسال کنیم. در اینجا و اینجا می توانید اطلاعات بیشتری در مورد این موضوع بخوانید .ما JRTB-13 می نویسیم
ما باید یک فرآیند استقرار سریع و آسان را برای برنامه خود در سرور تنظیم کنیم. یعنی برای ماشینی که 24/7 کار می کند. بیایید داکر را به عنوان پایه در نظر بگیریم. اما هیچ وظیفه ای در لیست ما وجود ندارد که مسئول اضافه کردن این قابلیت باشد. به نوعی هنگام ایجاد آن از دست دادم. مشکلی نیست، اکنون آن را ایجاد می کنیم. به تب ایجاد مشکل در GitHub بروید و Feature Request را انتخاب کنید: شرح کار، معیارهای پذیرش آن را اضافه کنید، تعیین کنید که این موضوع به کدام پروژه تعلق دارد و می توانید یک شماره جدید ایجاد کنید: اکنون، برای نشان دادن اینکه کار پذیرفته شده است. برای کار، وضعیت کار را از To do on In Progress تغییر دهید: این مقاله دشواری خواهد بود. اگر مشکلی دارید در نظرات بنویسید: من در حد توانم آنها را رصد و پاسخ خواهم داد. این یک پشتیبانی مشتری کوچک خواهد بود :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
- بیایید اسکریپت bash را اجرا کنیم.
- اسکریپت bash docker-compose را اجرا می کند.
- Docker-compose یک داکر کانتینر را با برنامه ما راه اندازی می کند.
- ظرف Docker برنامه ما را اجرا می کند.
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.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 به مخزن صحبت می کنم.
GO TO FULL VERSION