CI/CD در Github Actions برای پروژه Flask+Angular

CI/CD در Github Actions برای پروژه Flask+Angular
در این مقاله، من تجربه خود را از راه اندازی 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 با توضیحات دقیق ساختار و دستورالعمل های اجرای پروژه وجود دارد.

Web Part API کاملاً بدون عارضه، از 6 قلم تشکیل شده است:

  • /ping - برای بررسی در دسترس بودن؛
  • رسیدگی به ثبت نام، مجوز، لغو مجوز و به دست آوردن یک کاربر مجاز؛
  • یک دسته ایمیل که وظیفه ای را در صف کرفس قرار می دهد.

قسمت کرفس حتی ساده تر، فقط یک مشکل وجود دارد send_mail_task.

در پوشه / conf دو پوشه فرعی وجود دارد:

  • 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 برای استقرار

و آخرین پوشه ای که به آن علاقه مندیم - .ci-cd. این شامل اسکریپت های پوسته برای استقرار است:

  • deploy.sh - راه اندازی مهاجرت و استقرار. پس از ساخت و اجرای آزمایشات در Github Actions بر روی سرور اجرا می شود.
  • rollback.sh - برگشت ظروف به نسخه قبلی مونتاژ.
  • curl_tg.sh - ارسال اعلان های استقرار به تلگرام.

Frontend در Angular

مخزن با جلو خیلی ساده تر از بک صفحه اول شامل سه صفحه است:

  • صفحه اصلی با فرمی برای ارسال ایمیل و دکمه خروج.
  • صفحه ورود.
  • صفحه ثبت نام

صفحه اصلی زاهدانه به نظر می رسد:

CI/CD در Github Actions برای پروژه Flask+Angular
دو فایل در ریشه وجود دارد Dockerfile и docker-compose.ymlو همچنین پوشه آشنا .ci-cd با اسکریپت های کمی کمتر از مخزن پشتی (اسکریپت های حذف شده برای آزمایش های در حال اجرا).

شروع پروژه در پلسک

بیایید با راه اندازی Plesk و ایجاد اشتراک برای سایت خود شروع کنیم.

نصب افزونه ها

در پلسک به چهار پسوند نیاز داریم:

  • Docker برای مدیریت و نمایش بصری وضعیت کانتینرها در پنل مدیریت پلسک؛
  • Git برای پیکربندی مرحله استقرار در سرور؛
  • Let's Encrypt برای تولید (و تمدید خودکار) گواهینامه های رایگان TLS؛
  • Firewall برای پیکربندی فیلتر ترافیک ورودی

می توانید آنها را از طریق پنل مدیریت Plesk در بخش افزونه ها نصب کنید:

CI/CD در Github Actions برای پروژه Flask+Angular
ما تنظیمات دقیق را برای برنامه های افزودنی در نظر نخواهیم گرفت، تنظیمات پیش فرض برای اهداف نمایشی ما انجام می شود.

یک اشتراک و سایت ایجاد کنید

در مرحله بعد، ما باید یک اشتراک برای وب سایت helloworld.ru خود ایجاد کنیم و زیر دامنه dev.helloworld.ru را در آنجا اضافه کنیم.

  1. یک اشتراک برای دامنه helloworld.ru ایجاد کنید و رمز ورود به سیستم را برای کاربر سیستم مشخص کنید:

    CI/CD در Github Actions برای پروژه Flask+Angular
    کادر پایین صفحه را علامت بزنید با Let's Encrypt دامنه را ایمن کنیداگر می خواهیم HTTPS را برای سایت راه اندازی کنیم:

    CI/CD در Github Actions برای پروژه Flask+Angular

  2. بعد، در این اشتراک، یک زیر دامنه dev.helloworld.ru ایجاد کنید (برای آن می توانید گواهی TLS رایگان نیز صادر کنید):

    CI/CD در Github Actions برای پروژه Flask+Angular

نصب کامپوننت های سرور

ما یک سرور با OS Debian Stretch 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 برویم. نصب آن در دبیان بسیار ساده است:

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 برای پلسک

  1. ما به Plesk می رویم، به بخش Extensions می رویم، پسوند Docker را جستجو می کنیم و آن را نصب می کنیم (به یک نسخه رایگان نیاز داریم):

    CI/CD در Github Actions برای پروژه Flask+Angular

  2. به افزونه نصب شده بروید، تصویر را از طریق جستجو پیدا کنید redis bitnami و آخرین نسخه را نصب کنید:

    CI/CD در Github Actions برای پروژه Flask+Angular

  3. ما به محفظه بارگیری شده می رویم و پیکربندی را تنظیم می کنیم: پورت، حداکثر اندازه RAM اختصاص داده شده، رمز عبور در متغیرهای محیطی را مشخص کرده و حجم را نصب کنید:

    CI/CD در Github Actions برای پروژه Flask+Angular

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

    CI/CD در Github Actions برای پروژه Flask+Angular

رجیستری داکر

علاوه بر خدمات اولیه، خوب است که مخزن تصویر Docker خود را روی سرور قرار دهید. خوشبختانه فضای سرور در حال حاضر بسیار ارزان است (مطمئناً ارزانتر از اشتراک DockerHub) و فرآیند راه اندازی یک مخزن خصوصی بسیار ساده است.

ما می خواهیم داشته باشیم:

برای این کار:

  1. بیایید در اشتراک خود دو زیر دامنه در Plesk ایجاد کنیم: docker.helloworld.ru و docker-ui.helloworld.ru، و مجوزهای Let's Encrypt را برای آنها پیکربندی کنیم.
  2. فایل را به پوشه ساب دامنه 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'
    

  3. تحت SSH، فایل htpasswd. را برای مجوز اولیه در مخزن داکر تولید می کنیم:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. جمع آوری و بلند کردن ظروف:
    docker-compose up -d
  5. و باید Nginx را به کانتینرهای خود هدایت کنیم. این کار از طریق پلسک قابل انجام است.

مراحل زیر باید برای زیر دامنه‌های docker.helloworld.ru و docker-ui.helloworld.ru انجام شود:

در بخش ابزارهای توسعه دهنده سایت ما به قوانین پروکسی داکر:

CI/CD در Github Actions برای پروژه Flask+Angular
و یک قانون به ترافیک ورودی پراکسی به کانتینر خود اضافه کنید:

CI/CD در Github Actions برای پروژه Flask+Angular

  1. بررسی می کنیم که می توانیم از دستگاه محلی وارد کانتینر خود شویم:
    $ 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
  2. بیایید عملکرد زیر دامنه docker-ui.helloworld.ru را نیز بررسی کنیم:

    CI/CD در Github Actions برای پروژه Flask+Angular
    هنگامی که بر روی Browse Repositories کلیک می کنید، مرورگر یک پنجره مجوز نمایش می دهد که در آن باید نام کاربری و رمز عبور مخزن را وارد کنید. پس از آن، ما به صفحه ای با لیستی از مخازن منتقل می شویم (در حال حاضر برای شما خالی خواهد بود):

    CI/CD در Github Actions برای پروژه Flask+Angular

باز کردن پورت ها در فایروال پلسک

پس از نصب و پیکربندی کامپوننت ها، باید پورت هایی را باز کنیم تا کامپوننت ها از کانتینرهای داکر و شبکه خارجی قابل دسترسی باشند.

بیایید ببینیم که چگونه با استفاده از افزونه فایروال برای Plesk که قبلاً نصب کرده بودیم، این کار را انجام دهیم.

  1. قابل اعتماد و متخصص Tools & Settings > Settings > Firewall:
    CI/CD در Github Actions برای پروژه Flask+Angular
  2. قابل اعتماد و متخصص قوانین فایروال پلسک را تغییر دهید > قانون سفارشی را اضافه کنید و پورت های TCP زیر را برای زیرشبکه Docker باز کنید (172.0.0.0 / 8):
    RabbitMQ: 1883، 4369، 5671-5672، 25672، 61613-61614
    Redis: 32785, 32786

    CI/CD در Github Actions برای پروژه Flask+Angular

  3. ما همچنین یک قانون اضافه می کنیم که پورت های PostgreSQL و پانل های مدیریت RabbitMQ را به دنیای خارج باز می کند:

    CI/CD در Github Actions برای پروژه Flask+Angular

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

    CI/CD در Github Actions برای پروژه Flask+Angular

راه اندازی CI/CD در Github Actions

بیایید به جالب ترین بخش بپردازیم - راه اندازی خط لوله یکپارچه سازی مداوم و تحویل پروژه خود به سرور.

این خط لوله از دو بخش تشکیل خواهد شد:

  • ساختن یک تصویر و اجرای آزمایشات (برای Backend) - در سمت Github.
  • اجرای مهاجرت (برای Backend) و استقرار کانتینرها - روی سرور.

به پلسک مستقر شوید

بیایید ابتدا به نکته دوم بپردازیم (چون مورد اول به آن بستگی دارد).

ما فرآیند استقرار را با استفاده از پسوند Git برای Plesk پیکربندی می کنیم.

مثالی را با محیط Prod برای مخزن Backend در نظر بگیرید.

  1. ما به اشتراک وب سایت Helloworld خود می رویم و به زیربخش Git می رویم:

    CI/CD در Github Actions برای پروژه Flask+Angular

  2. پیوندی به مخزن Github ما در قسمت "Remote Git Repository" وارد کنید و پوشه پیش فرض را تغییر دهید. httpdocs به دیگری (مثلا /httpdocs/hw_back):

    CI/CD در Github Actions برای پروژه Flask+Angular

  3. کلید عمومی SSH را از مرحله قبل کپی کنید و اضافه کردن در تنظیمات Github است.
  4. در مرحله 2 روی صفحه روی OK کلیک کنید، پس از آن به صفحه مخزن در پلسک هدایت می شویم. اکنون باید مخزن را پیکربندی کنیم تا در commit ها به شاخه اصلی به روز شود. برای انجام این کار، به تنظیمات مخزن و ارزش را ذخیره کنید Webhook URL (ما بعداً هنگام تنظیم Github Actions به آن نیاز خواهیم داشت):

    CI/CD در Github Actions برای پروژه Flask+Angular

  5. در قسمت 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
  6. یک کاربر از اشتراک خود را به گروه Docker اضافه کنید (تا بتواند کانتینرها را مدیریت کند):
    sudo usermod -aG docker helloworld_admin

محیط توسعه دهنده برای مخزن باطن و فرانت اند به همین ترتیب تنظیم شده اند.

خط لوله استقرار در Github Actions

بیایید به راه اندازی بخش اول خط لوله CI/CD خود در Github Actions ادامه دهیم.

بخش مدیریت

خط لوله در شرح داده شده است فایل deploy.yml.

اما قبل از تجزیه، بیایید متغیرهای Secret را که در Github نیاز داریم پر کنیم. برای انجام این کار، به تنظیمات -> اسرار:

  • DOCKER_REGISTRY - میزبان مخزن Docker ما (docker.helloworld.ru)؛
  • DOCKER_LOGIN - وارد مخزن Docker شوید.
  • DOCKER_PASSWORD - رمز عبور آن؛
  • DEPLOY_HOST - میزبانی که در آن پنل مدیریت Plesk در دسترس است (مثال: helloworld.com: 8443 یا 123.4.56.78:8443)؛
  • DEPLOY_BACK_PROD_TOKEN - یک نشانه برای استقرار در مخزن prod در سرور (ما آن را در Deployment در Plesk ص 4 دریافت کردیم).
  • DEPLOY_BACK_DEV_TOKEN - توکن برای استقرار در مخزن برنامه نویس در سرور.

فرآیند استقرار ساده است و شامل سه مرحله اصلی است:

  • ساخت و انتشار تصویر در مخزن ما؛
  • اجرای آزمایش ها در یک ظرف بر اساس یک تصویر تازه ساخته شده است.
  • استقرار در محیط مورد نظر بسته به شاخه (dev/master).

ظاهر

فایل deploy.yml برای مخزن جلویی تفاوت کمی با بک دارد. این فاقد یک مرحله با آزمایش های در حال اجرا است و نام نشانه ها را برای استقرار تغییر می دهد. به هر حال، اسرار مخزن جلویی باید به طور جداگانه پر شود.

راه اندازی سایت

پروکسی کردن ترافیک از طریق Nginx

خب به آخرش رسیدیم تنها برای پیکربندی پروکسی ترافیک ورودی و خروجی به کانتینر ما از طریق Nginx باقی مانده است. ما قبلاً این فرآیند را در مرحله 5 تنظیم Docker Registry پوشش داده ایم. همین کار را باید برای قسمت های پشت و جلو در محیط های dev و prod تکرار کرد.

من اسکرین شات از تنظیمات ارائه خواهم کرد.

بخش مدیریت

CI/CD در Github Actions برای پروژه Flask+Angular

ظاهر

CI/CD در Github Actions برای پروژه Flask+Angular
مهم است. همه URL ها به کانتینر frontend پروکسی می شوند، به جز مواردی که با آن شروع می شوند /api/ - آنها به ظرف پشتی پروکسی می شوند (بنابراین در کانتینر پشتی، همه گردانندگان باید با آن شروع کنند /api/).

نمایش نتایج: از

اکنون سایت ما باید در helloworld.ru و dev.helloworld.ru (به ترتیب prod- و dev-vironments) در دسترس باشد.

در مجموع، ما یاد گرفتیم که چگونه یک برنامه ساده را در Flask و Angular آماده کنیم و یک خط لوله در Github Actions راه اندازی کنیم تا آن را در سروری که Plesk اجرا می کند، عرضه کنیم.

من پیوندهای مخازن را با کد کپی می کنم: باطن, پیشانی.

منبع: www.habr.com

اضافه کردن نظر