
در این مقاله، من تجربه خود را از راه اندازی CI/CD با استفاده از کنترل پنل Plesk و Github Actions به اشتراک می گذارم. امروز می آموزیم که چگونه یک پروژه ساده با نام غیر پیچیده "Helloworld" را اجرا کنیم. این در چارچوب Flask Python، با کارگران Celery و پیشانی Angular 8 نوشته شده است.
پیوند به مخازن: , .
در قسمت اول مقاله به بررسی پروژه خود و قسمت های آن می پردازیم. در مرحله دوم، نحوه راه اندازی Plesk و نصب افزونه ها و اجزای لازم (DB، RabbitMQ، Redis، Docker و غیره) را خواهیم فهمید.
در قسمت سوم، در نهایت نحوه راهاندازی خط لوله برای استقرار پروژه خود در یک سرور در محیط توسعه و تولید را خواهیم فهمید. و سپس سایت را روی سرور راه اندازی می کنیم.
و بله، فراموش کردم خودم را معرفی کنم. نام من اولگ برزوف است، من یک توسعه دهنده کامل در تیم CRM برای مدیران وام مسکن در Domclick هستم.
بررسی اجمالی پروژه
ابتدا، اجازه دهید به دو مخزن پروژه - Backend و Front - نگاه کنیم و کد را مرور کنیم.
پس زمینه: فلاسک + کرفس
برای قسمت پشتی، من یک دسته را انتخاب کردم که در بین توسعه دهندگان پایتون بسیار محبوب است: چارچوب Flask (برای API) و Celery (برای صف وظایف). SQLAchemy به عنوان ORM استفاده می شود. Alembic برای مهاجرت استفاده می شود. برای اعتبارسنجی JSON در دسته ها - Marshmallow.
В یک فایل Readme.md با توضیحات دقیق ساختار و دستورالعمل های اجرای پروژه وجود دارد.
کاملاً بدون عارضه، از 6 قلم تشکیل شده است:
/ping- برای بررسی در دسترس بودن؛- رسیدگی به ثبت نام، مجوز، لغو مجوز و به دست آوردن یک کاربر مجاز؛
- یک دسته ایمیل که وظیفه ای را در صف کرفس قرار می دهد.
حتی ساده تر، فقط یک مشکل وجود دارد send_mail_task.
در پوشه دو پوشه فرعی وجود دارد:
dockerبا دو فایل داکر (base.dockerfileبرای ساختن یک تصویر پایه که به ندرت تغییر می کند وDockerfileبرای مجامع اصلی)؛.env_files- دارای فایل هایی با متغیرهای محیطی برای محیط های مختلف.
چهار فایل docker-compose در ریشه پروژه وجود دارد:
docker-compose.local.db.ymlایجاد یک پایگاه داده محلی برای توسعه؛docker-compose.local.workers.ymlبرای افزایش محلی کارگر، پایگاه داده، Redis و RabbitMQ.docker-compose.test.ymlبرای اجرای تست ها در حین استقرار؛docker-compose.ymlبرای استقرار
و آخرین پوشه ای که به آن علاقه مندیم - . این شامل اسکریپت های پوسته برای استقرار است:
deploy.sh- راه اندازی مهاجرت و استقرار. پس از ساخت و اجرای آزمایشات در Github Actions بر روی سرور اجرا می شود.rollback.sh- برگشت ظروف به نسخه قبلی مونتاژ.curl_tg.sh- ارسال اعلان های استقرار به تلگرام.
Frontend در Angular
خیلی ساده تر از بک صفحه اول شامل سه صفحه است:
- صفحه اصلی با فرمی برای ارسال ایمیل و دکمه خروج.
- صفحه ورود.
- صفحه ثبت نام
صفحه اصلی زاهدانه به نظر می رسد:

دو فایل در ریشه وجود دارد Dockerfile и docker-compose.ymlو همچنین پوشه آشنا .ci-cd با اسکریپت های کمی کمتر از مخزن پشتی (اسکریپت های حذف شده برای آزمایش های در حال اجرا).
شروع پروژه در پلسک
بیایید با راه اندازی Plesk و ایجاد اشتراک برای سایت خود شروع کنیم.
نصب افزونه ها
در پلسک به چهار پسوند نیاز داریم:
Dockerبرای مدیریت و نمایش بصری وضعیت کانتینرها در پنل مدیریت پلسک؛Gitبرای پیکربندی مرحله استقرار در سرور؛Let's Encryptبرای تولید (و تمدید خودکار) گواهینامه های رایگان TLS؛Firewallبرای پیکربندی فیلتر ترافیک ورودی
می توانید آنها را از طریق پنل مدیریت Plesk در بخش افزونه ها نصب کنید:

ما تنظیمات دقیق را برای برنامه های افزودنی در نظر نخواهیم گرفت، تنظیمات پیش فرض برای اهداف نمایشی ما انجام می شود.
یک اشتراک و سایت ایجاد کنید
در مرحله بعد، ما باید یک اشتراک برای وب سایت helloworld.ru خود ایجاد کنیم و زیر دامنه dev.helloworld.ru را در آنجا اضافه کنیم.
- یک اشتراک برای دامنه helloworld.ru ایجاد کنید و رمز ورود به سیستم را برای کاربر سیستم مشخص کنید:

کادر پایین صفحه را علامت بزنید با Let's Encrypt دامنه را ایمن کنیداگر می خواهیم HTTPS را برای سایت راه اندازی کنیم:
- بعد، در این اشتراک، یک زیر دامنه dev.helloworld.ru ایجاد کنید (برای آن می توانید گواهی TLS رایگان نیز صادر کنید):

نصب کامپوننت های سرور
ما یک سرور با OS Debian کشش 9.12 و کنترل پنل را نصب کرد پلسک Obsidian 18.0.27.
ما باید برای پروژه خود نصب و پیکربندی کنیم:
- PostgreSQL (در مورد ما، یک سرور با دو پایگاه داده برای محیط های dev و prod وجود خواهد داشت).
- RabbitMQ (همان، نمونه مشابه با vhost های مختلف برای محیط ها).
- دو نمونه Redis (برای محیط های dev و prod).
- Docker Registry (برای ذخیره محلی تصاویر ساخته شده Docker).
- UI برای رجیستری Docker.
PostgreSQL و
Plesk قبلاً با PostgreSQL DBMS ارائه می شود، اما نه آخرین نسخه (در زمان نوشتن Plesk Obsidian نسخه های Postgres 8.4-10.8). ما آخرین نسخه را برای برنامه خود می خواهیم (12.3 در زمان نوشتن این مقاله)، بنابراین آن را به صورت دستی نصب می کنیم.
دستورالعملهای دقیق در مورد نصب Postgres روی Debian توی اینترنت به وفور پیدا میشه (، بنابراین من آنها را با جزئیات توصیف نمی کنم، فقط دستورات را می دهم:
wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
sudo apt-get update
sudo apt-get install postgresql postgresql-contrib
با توجه به اینکه PostgreSQL تنظیمات پیش فرض نسبتاً متوسطی دارد، لازم است پیکربندی را اصلاح کنید. این به ما کمک خواهد کرد : باید پارامترهای سرور خود را درایو کنید و تنظیمات فایل را جایگزین کنید /etc/postgresql/12/main/postgresql.confبه کسانی که ارائه می شوند. در اینجا لازم به ذکر است که چنین ماشین حساب هایی یک گلوله جادویی نیستند و پایه باید بر اساس سخت افزار، برنامه و پیچیدگی پرس و جو با دقت بیشتری تنظیم شود. اما این برای شروع کافی است.
علاوه بر تنظیمات ارائه شده توسط ماشین حساب، ما نیز تغییر می دهیم postgresql.confپورت پیش فرض 5432 به دیگری (در مثال ما - 53983).
پس از تغییر فایل پیکربندی، postgresql-server را با دستور زیر راه اندازی مجدد کنید:
service postgresql restart
ما PostgreSQL را نصب و پیکربندی کرده ایم. حالا بیایید یک پایگاه داده، کاربران برای محیطهای توسعه و توسعه ایجاد کنیم و به کاربران حقوقی برای مدیریت پایگاه داده بدهیم:
$ su - postgres
postgres:~$ create database hw_dev_db_name;
CREATE DATABASE
postgres:~$ create user hw_dev_db_user with password 'hw_dev_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_dev_db_name to hw_dev_db_user;
GRANT
postgres:~$ create database hw_prod_db_name;
CREATE DATABASE
postgres:~$ create user hw_prod_db_user with password 'hw_prod_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_prod_db_name to hw_prod_db_user;
GRANT
خرگوش ام کیو
بیایید به سراغ نصب RabbitMQ، یک کارگزار پیام برای Celery، برویم. این نرمافزار روی ... نصب شده است. Debian خیلی ساده است:
wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i erlang-solutions_1.0_all.deb
sudo apt-get update
sudo apt-get install erlang erlang-nox
sudo add-apt-repository 'deb http://www.rabbitmq.com/debian/ testing main'
wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -
sudo apt-get update
sudo apt-get install rabbitmq-server
پس از نصب، باید ایجاد کنیم vhosts، کاربران و اعطای حقوق لازم:
sudo rabbitmqctl add_user hw_dev_amqp_user hw_dev_amqp_password
sudo rabbitmqctl set_user_tags hw_dev_amqp_user administrator
sudo rabbitmqctl add_vhost hw_dev_vhost
sudo rabbitmqctl set_permissions -p hw_dev_vhost hw_dev_amqp_user ".*" ".*" ".*"
sudo rabbitmqctl add_user hw_prod_amqp_user hw_prod_amqp_password
sudo rabbitmqctl set_user_tags hw_prod_amqp_user administrator
sudo rabbitmqctl add_vhost hw_prod_vhost
sudo rabbitmqctl set_permissions -p hw_prod_vhost hw_prod_amqp_user ".*" ".*" ".*"
Redis
حالا بیایید آخرین کامپوننت را برای برنامه خود نصب و پیکربندی کنیم - Redis. از آن به عنوان یک Backend برای ذخیره نتایج وظایف Celery استفاده می شود.
ما دو کانتینر Docker را با Redis برای محیطهای توسعهدهنده و prod با استفاده از برنامه افزودنی ایجاد میکنیم Docker برای پلسک
- ما به Plesk می رویم، به بخش Extensions می رویم، پسوند Docker را جستجو می کنیم و آن را نصب می کنیم (به یک نسخه رایگان نیاز داریم):

- به افزونه نصب شده بروید، تصویر را از طریق جستجو پیدا کنید
redis bitnamiو آخرین نسخه را نصب کنید:
- ما به محفظه بارگیری شده می رویم و پیکربندی را تنظیم می کنیم: پورت، حداکثر اندازه RAM اختصاص داده شده، رمز عبور در متغیرهای محیطی را مشخص کرده و حجم را نصب کنید:

- ما مراحل 2-3 را برای کانتینر prod انجام می دهیم، در تنظیمات فقط پارامترها را تغییر می دهیم: پورت، رمز عبور، اندازه RAM و مسیر به پوشه حجم در سرور:

رجیستری داکر
علاوه بر خدمات اولیه، خوب است که مخزن تصویر Docker خود را روی سرور قرار دهید. خوشبختانه فضای سرور در حال حاضر بسیار ارزان است (مطمئناً ارزانتر از اشتراک DockerHub) و فرآیند راه اندازی یک مخزن خصوصی بسیار ساده است.
ما می خواهیم داشته باشیم:
- مخزن Docker محافظت شده با رمز عبور قابل دسترسی در یک زیر دامنه ;
- رابط کاربری برای مشاهده تصاویر در مخزن، موجود در .
برای این کار:
- بیایید در اشتراک خود دو زیر دامنه در Plesk ایجاد کنیم: docker.helloworld.ru و docker-ui.helloworld.ru، و مجوزهای Let's Encrypt را برای آنها پیکربندی کنیم.
- فایل را به پوشه ساب دامنه docker.helloworld.ru اضافه کنید
docker-compose.ymlبا مطالبی مانند این:version: "3" services: docker-registry: image: "registry:2" restart: always ports: - "53985:5000" environment: REGISTRY_AUTH: htpasswd REGISTRY_AUTH_HTPASSWD_REALM: basic-realm REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data volumes: - ./.docker-registry.htpasswd:/auth/.htpasswd - ./data:/data docker-registry-ui: image: konradkleine/docker-registry-frontend:v2 restart: always ports: - "53986:80" environment: VIRTUAL_HOST: '*, https://*' ENV_DOCKER_REGISTRY_HOST: 'docker-registry' ENV_DOCKER_REGISTRY_PORT: 5000 links: - 'docker-registry' - تحت SSH، فایل htpasswd. را برای مجوز اولیه در مخزن داکر تولید می کنیم:
htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password - جمع آوری و بلند کردن ظروف:
docker-compose up -d - و باید Nginx را به کانتینرهای خود هدایت کنیم. این کار از طریق پلسک قابل انجام است.
مراحل زیر باید برای زیر دامنههای docker.helloworld.ru و docker-ui.helloworld.ru انجام شود:
در بخش ابزارهای توسعه دهنده سایت ما به قوانین پروکسی داکر:

و یک قانون به ترافیک ورودی پراکسی به کانتینر خود اضافه کنید:

- بررسی می کنیم که می توانیم از دستگاه محلی وارد کانتینر خود شویم:
$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password WARNING! Using --password via the CLI is insecure. Use --password-stdin. Login Succeeded - بیایید عملکرد زیر دامنه docker-ui.helloworld.ru را نیز بررسی کنیم:

هنگامی که بر روی Browse Repositories کلیک می کنید، مرورگر یک پنجره مجوز نمایش می دهد که در آن باید نام کاربری و رمز عبور مخزن را وارد کنید. پس از آن، ما به صفحه ای با لیستی از مخازن منتقل می شویم (در حال حاضر برای شما خالی خواهد بود):
باز کردن پورت ها در فایروال پلسک
پس از نصب و پیکربندی کامپوننت ها، باید پورت هایی را باز کنیم تا کامپوننت ها از کانتینرهای داکر و شبکه خارجی قابل دسترسی باشند.
بیایید ببینیم که چگونه با استفاده از افزونه فایروال برای Plesk که قبلاً نصب کرده بودیم، این کار را انجام دهیم.
- قابل اعتماد و متخصص Tools & Settings > Settings > Firewall:

- قابل اعتماد و متخصص قوانین فایروال پلسک را تغییر دهید > قانون سفارشی را اضافه کنید و پورت های TCP زیر را برای زیرشبکه Docker باز کنید (172.0.0.0 / 8):
RabbitMQ: 1883، 4369، 5671-5672، 25672، 61613-61614
Redis: 32785, 32786
- ما همچنین یک قانون اضافه می کنیم که پورت های PostgreSQL و پانل های مدیریت RabbitMQ را به دنیای خارج باز می کند:

- قوانین را با استفاده از دکمه اعمال تغییرات اعمال کنید:

راه اندازی CI/CD در Github Actions
بیایید به جالب ترین بخش بپردازیم - راه اندازی خط لوله یکپارچه سازی مداوم و تحویل پروژه خود به سرور.
این خط لوله از دو بخش تشکیل خواهد شد:
- ساختن یک تصویر و اجرای آزمایشات (برای Backend) - در سمت Github.
- اجرای مهاجرت (برای Backend) و استقرار کانتینرها - روی سرور.
به پلسک مستقر شوید
بیایید ابتدا به نکته دوم بپردازیم (چون مورد اول به آن بستگی دارد).
ما فرآیند استقرار را با استفاده از پسوند Git برای Plesk پیکربندی می کنیم.
مثالی را با محیط Prod برای مخزن Backend در نظر بگیرید.
- ما به اشتراک وب سایت Helloworld خود می رویم و به زیربخش Git می رویم:

- پیوندی به مخزن Github ما در قسمت "Remote Git Repository" وارد کنید و پوشه پیش فرض را تغییر دهید.
httpdocsبه دیگری (مثلا/httpdocs/hw_back):
- کلید عمومی SSH را از مرحله قبل کپی کنید و در تنظیمات Github است.
- در مرحله 2 روی صفحه روی OK کلیک کنید، پس از آن به صفحه مخزن در پلسک هدایت می شویم. اکنون باید مخزن را پیکربندی کنیم تا در commit ها به شاخه اصلی به روز شود. برای انجام این کار، به تنظیمات مخزن و ارزش را ذخیره کنید
Webhook URL(ما بعداً هنگام تنظیم Github Actions به آن نیاز خواهیم داشت):
- در قسمت Actions در صفحه پاراگراف قبلی، اسکریپت را برای راه اندازی استقرار وارد کنید:
cd {REPOSITORY_ABSOLUTE_PATH} .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID}که در آن:
{REPOSITORY_ABSOLUTE_PATH}- مسیر به پوشه prod مخزن باطن در سرور؛
{ENV}- محیط (dev / prod)، در مورد ماprod;
{DOCKER_REGISTRY_HOST}- میزبان مخزن docker ما
{TG_BOT_TOKEN}- توکن ربات تلگرام؛
{TG_CHAT_ID}- شناسه چت/کانال برای ارسال اعلان ها.نمونه اسکریپت:
cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/ .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890 - یک کاربر از اشتراک خود را به گروه Docker اضافه کنید (تا بتواند کانتینرها را مدیریت کند):
sudo usermod -aG docker helloworld_admin
محیط توسعه دهنده برای مخزن باطن و فرانت اند به همین ترتیب تنظیم شده اند.
خط لوله استقرار در Github Actions
بیایید به راه اندازی بخش اول خط لوله CI/CD خود در Github Actions ادامه دهیم.
بخش مدیریت
خط لوله در شرح داده شده است .
اما قبل از تجزیه، بیایید متغیرهای Secret را که در Github نیاز داریم پر کنیم. برای انجام این کار، به تنظیمات -> اسرار:
DOCKER_REGISTRY- میزبان مخزن Docker ما (docker.helloworld.ru)؛DOCKER_LOGIN- وارد مخزن Docker شوید.DOCKER_PASSWORD- رمز عبور آن؛DEPLOY_HOST- میزبانی که در آن پنل مدیریت Plesk در دسترس است (مثال: : 8443 یا :8443)؛DEPLOY_BACK_PROD_TOKEN- یک نشانه برای استقرار در مخزن prod در سرور (ما آن را در Deployment در Plesk ص 4 دریافت کردیم).DEPLOY_BACK_DEV_TOKEN- توکن برای استقرار در مخزن برنامه نویس در سرور.
فرآیند استقرار ساده است و شامل سه مرحله اصلی است:
- ساخت و انتشار تصویر در مخزن ما؛
- اجرای آزمایش ها در یک ظرف بر اساس یک تصویر تازه ساخته شده است.
- استقرار در محیط مورد نظر بسته به شاخه (dev/master).
ظاهر
تفاوت کمی با بک دارد. این فاقد یک مرحله با آزمایش های در حال اجرا است و نام نشانه ها را برای استقرار تغییر می دهد. به هر حال، اسرار مخزن جلویی باید به طور جداگانه پر شود.
راه اندازی سایت
پروکسی کردن ترافیک از طریق Nginx
خب به آخرش رسیدیم تنها برای پیکربندی پروکسی ترافیک ورودی و خروجی به کانتینر ما از طریق Nginx باقی مانده است. ما قبلاً این فرآیند را در مرحله 5 تنظیم Docker Registry پوشش داده ایم. همین کار را باید برای قسمت های پشت و جلو در محیط های dev و prod تکرار کرد.
من اسکرین شات از تنظیمات ارائه خواهم کرد.
بخش مدیریت

ظاهر

مهم است. همه URL ها به کانتینر frontend پروکسی می شوند، به جز مواردی که با آن شروع می شوند /api/ - آنها به ظرف پشتی پروکسی می شوند (بنابراین در کانتینر پشتی، همه گردانندگان باید با آن شروع کنند /api/).
نمایش نتایج: از
اکنون سایت ما باید در helloworld.ru و dev.helloworld.ru (به ترتیب prod- و dev-vironments) در دسترس باشد.
در مجموع، ما یاد گرفتیم که چگونه یک برنامه ساده را در Flask و Angular آماده کنیم و یک خط لوله در Github Actions راه اندازی کنیم تا آن را در سروری که Plesk اجرا می کند، عرضه کنیم.
من پیوندهای مخازن را با کد کپی می کنم: , .
منبع: www.habr.com
