CI / CD في إجراءات Github لمشروع Flask + Angular

CI / CD في إجراءات Github لمشروع Flask + Angular
في هذه المقالة ، سوف أشارك تجربتي في إعداد CI / CD باستخدام لوحة التحكم Plesk وإجراءات Github. اليوم سوف نتعلم كيفية نشر مشروع بسيط باسم غير معقد "Helloworld". تمت كتابته في إطار عمل Flask Python ، مع عمال الكرفس وواجهة Angular 8 الأمامية.

روابط المستودعات: الخلفية, نهاية المقدمة.

في الجزء الأول من المقال ، سنلقي نظرة على مشروعنا وأجزائه. في الثانية ، سنكتشف كيفية إعداد Plesk وتثبيت الملحقات والمكونات الضرورية (DB ، RabbitMQ ، Redis ، Docker ، إلخ).

في الجزء الثالث ، سنكتشف أخيرًا كيفية إعداد خط أنابيب لنشر مشروعنا على خادم في بيئة dev و prod. وبعد ذلك سنطلق الموقع على الخادم.

ونعم ، نسيت أن أقدم نفسي. اسمي أوليج بورزوف ، أنا مطور متكامل في فريق CRM لمديري الرهن العقاري في Domclick.

نظرة عامة على المشروع

أولاً ، دعنا نلقي نظرة على مستودعين للمشروع - الواجهة الخلفية والأمامية - وننتقل إلى الكود.

الخلفية: قارورة + كرفس

بالنسبة للجزء الخلفي ، أخذت مجموعة تحظى بشعبية كبيرة بين مطوري Python: إطار عمل Flask (لواجهة برمجة التطبيقات) وكرفس (لقائمة انتظار المهام). يتم استخدام SQLAchemy كـ ORM. يستخدم Alembic للهجرة. للتحقق من صحة JSON في المقابض - Marshmallow.

В مستودعات يوجد ملف Readme.md مع وصف تفصيلي للهيكل والتعليمات الخاصة بتشغيل المشروع.

واجهة برمجة تطبيقات جزء ويب بسيط للغاية ، يتكون من 6 أقلام:

  • /ping - للتحقق من التوافر ؛
  • يتعامل مع التسجيل والترخيص وإلغاء الترخيص والحصول على مستخدم مصرح له ؛
  • مقبض البريد الإلكتروني الذي يضع مهمة في قائمة انتظار الكرفس.

جزء الكرفس أسهل من ذلك ، هناك مشكلة واحدة فقط send_mail_task.

في المجلد / أسيوط هناك نوعان من المجلدات الفرعية:

  • docker مع اثنين من Dockerfiles (base.dockerfile لبناء صورة أساسية نادرًا ما تتغير و Dockerfile للتجمعات الرئيسية) ؛
  • .env_files - بملفات ذات متغيرات بيئة لبيئات مختلفة.

توجد أربعة ملفات إنشاء عامل ميناء في جذر المشروع:

  • docker-compose.local.db.yml لرفع قاعدة بيانات محلية من أجل التنمية ؛
  • docker-compose.local.workers.yml للتربية المحلية للعامل وقاعدة البيانات و Redis و RabbitMQ ؛
  • docker-compose.test.yml لإجراء الاختبارات أثناء النشر ؛
  • docker-compose.yml للنشر.

والمجلد الأخير الذي نهتم به - .ci-مؤتمر نزع السلاح. يحتوي على نصوص شل للنشر:

  • deploy.sh - إطلاق الترحيل والنشر. يعمل على الخادم بعد إنشاء الاختبارات وتشغيلها في إجراءات Github ؛
  • rollback.sh - التراجع عن الحاويات إلى الإصدار السابق من التجميع ؛
  • curl_tg.sh - إرسال إخطارات النشر إلى Telegram.

الواجهة على الزاوي

المستودع مع الجبهة أبسط بكثير من بيك. تتكون الجهة الأمامية من ثلاث صفحات:

  • الصفحة الرئيسية مع نموذج لإرسال البريد الإلكتروني وزر الخروج.
  • صفحة تسجيل الدخول.
  • صفحة التسجيل.

الصفحة الرئيسية تبدو زاهدة:

CI / CD في إجراءات Github لمشروع Flask + Angular
يوجد ملفان في الجذر Dockerfile и docker-compose.yml، وكذلك المجلد المألوف .ci-cd بنصوص برمجية أقل بقليل من المستودع الخلفي (نصوص تمت إزالتها لإجراء الاختبارات).

بدء مشروع في بليسك

لنبدأ بإعداد Plesk وإنشاء اشتراك لموقعنا.

تثبيت الامتدادات

في Plesk ، نحتاج إلى أربعة ملحقات:

  • Docker لإدارة وعرض حالة الحاويات بشكل مرئي في لوحة إدارة Plesk ؛
  • Git لتكوين خطوة النشر على الخادم ؛
  • Let's Encrypt لإنشاء شهادات TLS مجانية (وتجديدها تلقائيًا) ؛
  • Firewall لتكوين تصفية حركة المرور الواردة.

يمكنك تثبيتها من خلال لوحة إدارة Plesk في قسم الإضافات:

CI / CD في إجراءات Github لمشروع Flask + Angular
لن نأخذ في الاعتبار الإعدادات التفصيلية للإضافات ، ستعمل الإعدادات الافتراضية لأغراض العرض التجريبي لدينا.

إنشاء اشتراك وموقع

بعد ذلك ، نحتاج إلى إنشاء اشتراك في موقع helloworld.ru الخاص بنا وإضافة المجال الفرعي dev.helloworld.ru هناك.

  1. قم بإنشاء اشتراك في مجال helloworld.ru وحدد كلمة مرور تسجيل الدخول لمستخدم النظام:

    CI / CD في إجراءات Github لمشروع Flask + Angular
    ضع علامة في المربع أسفل الصفحة قم بتأمين المجال باستخدام Let's Encryptإذا أردنا إعداد HTTPS للموقع:

    CI / CD في إجراءات Github لمشروع Flask + Angular

  2. بعد ذلك ، في هذا الاشتراك ، أنشئ نطاقًا فرعيًا dev.helloworld.ru (يمكنك أيضًا إصدار شهادة TLS مجانية له):

    CI / CD في إجراءات Github لمشروع Flask + Angular

تثبيت مكونات الخادم

لدينا خادم مع OS Debian Stretch 9.12 ولوحة تحكم مثبتة بليسك سبج 18.0.27.

نحتاج إلى التثبيت والتهيئة لمشروعنا:

  • PostgreSQL (في حالتنا ، سيكون هناك خادم واحد به قاعدتي بيانات لبيئات dev و prod).
  • RabbitMQ (نفس المثال مع مضيفات مختلفة للبيئات).
  • مثيلين Redis (لبيئات dev و prod).
  • Docker Registry (للتخزين المحلي لصور Docker المبنية).
  • واجهة المستخدم لتسجيل Docker.

كيو

يأتي Plesk بالفعل مع PostgreSQL DBMS ، ولكن ليس أحدث إصدار (في وقت كتابة Plesk Obsidian أيد إصدارات Postgres 8.4-10.8). نريد أحدث إصدار لتطبيقنا (12.3 وقت كتابة هذا التقرير) ، لذلك سنقوم بتثبيته يدويًا.

هناك الكثير من التعليمات التفصيلية لتثبيت Postgres على دبيان على الشبكة (مثال) ، لذلك لن أصفها بالتفصيل ، سأعطي الأوامر فقط:

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. لنقم الآن بإنشاء قاعدة بيانات ، مستخدمين لبيئات dev- و prod ، ونمنح المستخدمين حقوق إدارة قاعدة البيانات:

$ 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

دعنا ننتقل إلى تثبيت RabbitMQ ، وسيط الرسائل للكرفس. تثبيته على دبيان بسيط للغاية:

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. سيتم استخدامه كخلفية لتخزين نتائج مهام الكرفس.

سنقوم برفع حاويتين من Docker مع Redis لبيئات dev و prod باستخدام الامتداد Docker لبليسك.

  1. نذهب إلى Plesk ، ونذهب إلى قسم الامتدادات ، ونبحث عن ملحق Docker وقم بتثبيته (نحتاج إلى إصدار مجاني):

    CI / CD في إجراءات Github لمشروع Flask + Angular

  2. انتقل إلى الامتداد المثبت ، وابحث عن الصورة من خلال البحث redis bitnami وقم بتثبيت أحدث إصدار:

    CI / CD في إجراءات Github لمشروع Flask + Angular

  3. نذهب إلى الحاوية التي تم تنزيلها ونضبط التكوين: حدد المنفذ ، والحد الأقصى لحجم ذاكرة الوصول العشوائي المخصص ، وكلمة المرور في متغيرات البيئة ، وقم بتركيب وحدة التخزين:

    CI / CD في إجراءات Github لمشروع Flask + Angular

  4. نقوم بتنفيذ الخطوات 2-3 لحاوية prod ، في الإعدادات ، نقوم فقط بتغيير المعلمات: المنفذ وكلمة المرور وحجم ذاكرة الوصول العشوائي والمسار إلى مجلد وحدة التخزين على الخادم:

    CI / CD في إجراءات Github لمشروع Flask + Angular

سجل Docker

بالإضافة إلى الخدمات الأساسية ، سيكون من الجيد وضع مستودع صور 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 للمصادقة الأساسية في مستودع Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. جمع الحاويات ورفعها:
    docker-compose up -d
  5. ونحتاج إلى إعادة توجيه Nginx إلى حاوياتنا. يمكن القيام بذلك من خلال Plesk.

يجب القيام بالخطوات التالية للنطاقات الفرعية docker.helloworld.ru و docker-ui.helloworld.ru:

في القسم أدوات ديف انتقل إلى موقعنا قواعد وكيل Docker:

CI / CD في إجراءات Github لمشروع Flask + Angular
وأضف قاعدة لحركة المرور الواردة إلى الحاوية الخاصة بنا:

CI / CD في إجراءات Github لمشروع 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 لمشروع Flask + Angular
    عند النقر فوق استعراض المستودعات ، سيعرض المتصفح نافذة ترخيص حيث ستحتاج إلى إدخال اسم المستخدم وكلمة المرور للمستودع. بعد ذلك ، سيتم نقلنا إلى صفحة بها قائمة بالمستودعات (في الوقت الحالي ، ستكون فارغة بالنسبة لك):

    CI / CD في إجراءات Github لمشروع Flask + Angular

فتح المنافذ في Plesk Firewall

بعد تثبيت المكونات وتكوينها ، نحتاج إلى فتح منافذ بحيث يمكن الوصول إلى المكونات من حاويات Docker والشبكة الخارجية.

دعونا نرى كيفية القيام بذلك باستخدام امتداد جدار الحماية لـ Plesk الذي قمنا بتثبيته سابقًا.

  1. اذهب إلى الأدوات والإعدادات> الإعدادات> جدار الحماية:
    CI / CD في إجراءات Github لمشروع Flask + Angular
  2. اذهب إلى تعديل قواعد جدار حماية Plesk> إضافة قاعدة مخصصة وافتح منافذ TCP التالية لشبكة Docker الفرعية (172.0.0.0 / 8):
    RabbitMQ: 1883 ، 4369 ، 5671-5672 ، 25672 ، 61613-61614
    ريديس: 32785 ، 32786

    CI / CD في إجراءات Github لمشروع Flask + Angular

  3. سنضيف أيضًا قاعدة ستفتح منافذ PostgreSQL ولوحات إدارة RabbitMQ للعالم الخارجي:

    CI / CD في إجراءات Github لمشروع Flask + Angular

  4. طبق القواعد باستخدام زر تطبيق التغييرات:

    CI / CD في إجراءات Github لمشروع Flask + Angular

إعداد CI / CD في إجراءات Github

دعنا ننتقل إلى الجزء الأكثر إثارة للاهتمام - إعداد خط أنابيب تكامل مستمر وتسليم مشروعنا إلى الخادم.

يتكون خط الأنابيب هذا من جزأين:

  • بناء صورة وإجراء الاختبارات (للواجهة الخلفية) - على جانب Github ؛
  • تشغيل عمليات الترحيل (للخلفية) ونشر الحاويات - على الخادم.

انشر في Plesk

دعونا نتعامل مع النقطة الثانية أولاً (لأن النقطة الأولى تعتمد عليها).

سنقوم بتكوين عملية النشر باستخدام امتداد Git لـ Plesk.

ضع في اعتبارك مثالاً مع بيئة Prod لمستودع Backend.

  1. نذهب إلى الاشتراك في موقع Helloworld الخاص بنا وننتقل إلى القسم الفرعي Git:

    CI / CD في إجراءات Github لمشروع Flask + Angular

  2. أدخل رابطًا إلى مستودع Github الخاص بنا في الحقل "Remote Git repository" وقم بتغيير المجلد الافتراضي httpdocs إلى آخر (على سبيل المثال. /httpdocs/hw_back):

    CI / CD في إجراءات Github لمشروع Flask + Angular

  3. انسخ مفتاح SSH العمومي من الخطوة السابقة و يضيف في إعدادات جيثب.
  4. انقر فوق "موافق" على الشاشة في الخطوة 2 ، وبعد ذلك سيتم إعادة توجيهنا إلى صفحة المستودع في Plesk. الآن نحن بحاجة إلى تكوين المستودع ليتم تحديثه عند الالتزام بالفرع الرئيسي. للقيام بذلك ، انتقل إلى إعدادات المستودع وحفظ القيمة Webhook URL (سنحتاجه لاحقًا عند إعداد إجراءات Github):

    CI / CD في إجراءات Github لمشروع Flask + Angular

  5. في حقل الإجراءات على الشاشة من الفقرة السابقة ، أدخل البرنامج النصي لبدء النشر:
    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} - مضيف مستودع عمال السفن لدينا
    {TG_BOT_TOKEN} - رمز Telegram bot ؛
    {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

دعنا ننتقل إلى إعداد الجزء الأول من خط أنابيب CI / CD في إجراءات 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 - رمز مميز للنشر في مستودع الإنتاج على الخادم (حصلنا عليه في Deployment in Plesk p.4) ؛
  • DEPLOY_BACK_DEV_TOKEN - رمز للنشر في مستودع dev على الخادم.

عملية النشر بسيطة وتتكون من ثلاث خطوات رئيسية:

  • بناء ونشر الصورة في مستودعنا ؛
  • إجراء الاختبارات في حاوية بناءً على صورة مبنية حديثًا ؛
  • النشر في البيئة المرغوبة اعتمادًا على الفرع (dev / master).

الواجهة

ملف publish.yml للمستودع الأمامي تختلف قليلا عن بيك. يفتقر إلى خطوة في إجراء الاختبارات وتغيير أسماء الرموز المميزة للنشر. بالمناسبة ، يجب ملء أسرار المستودع الأمامي بشكل منفصل.

إعداد الموقع

إنشاء وكلاء لحركة المرور عبر Nginx

حسنًا ، لقد وصلنا إلى النهاية. يبقى فقط تكوين الوكلاء لحركة المرور الواردة والصادرة إلى حاويتنا عبر Nginx. لقد قمنا بالفعل بتغطية هذه العملية في الخطوة 5 من إعداد Docker Registry. يجب تكرار نفس الشيء للأجزاء الخلفية والأمامية في بيئات dev و prod.

سأقدم لقطات شاشة للإعدادات.

الخلفية

CI / CD في إجراءات Github لمشروع Flask + Angular

الواجهة

CI / CD في إجراءات Github لمشروع Flask + Angular
ажное уточнение. سيتم إنشاء وكلاء لجميع عناوين URL في حاوية الواجهة الأمامية ، باستثناء تلك التي تبدأ بـ /api/ - سيتم ربطهم بالحاوية الخلفية (هكذا في الحاوية الخلفية ، يجب أن تبدأ جميع المعالجات /api/).

نتائج

الآن يجب أن يكون موقعنا متاحًا على helloworld.ru و dev.helloworld.ru (بيئات prod و dev ، على التوالي).

في المجموع ، تعلمنا كيفية إعداد تطبيق بسيط في Flask و Angular وإعداد خط أنابيب في إجراءات Github لنشره على خادم يقوم بتشغيل Plesk.

سأكرر الروابط إلى المستودعات مع الكود: الخلفية, نهاية المقدمة.

المصدر: www.habr.com

إضافة تعليق