
في هذه المقالة ، سوف أشارك تجربتي في إعداد 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للنشر.
والمجلد الأخير الذي نهتم به - . يحتوي على نصوص شل للنشر:
deploy.sh- إطلاق الترحيل والنشر. يعمل على الخادم بعد إنشاء الاختبارات وتشغيلها في إجراءات Github ؛rollback.sh- التراجع عن الحاويات إلى الإصدار السابق من التجميع ؛curl_tg.sh- إرسال إخطارات النشر إلى Telegram.
الواجهة على الزاوي
أبسط بكثير من بيك. تتكون الجهة الأمامية من ثلاث صفحات:
- الصفحة الرئيسية مع نموذج لإرسال البريد الإلكتروني وزر الخروج.
- صفحة تسجيل الدخول.
- صفحة التسجيل.
الصفحة الرئيسية تبدو زاهدة:

يوجد ملفان في الجذر Dockerfile и docker-compose.yml، وكذلك المجلد المألوف .ci-cd بنصوص برمجية أقل بقليل من المستودع الخلفي (نصوص تمت إزالتها لإجراء الاختبارات).
بدء مشروع في بليسك
لنبدأ بإعداد Plesk وإنشاء اشتراك لموقعنا.
تثبيت الامتدادات
في Plesk ، نحتاج إلى أربعة ملحقات:
Dockerلإدارة وعرض حالة الحاويات بشكل مرئي في لوحة إدارة Plesk ؛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 ولوحة تحكم مثبتة بليسك سبج 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 على 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. لنقم الآن بإنشاء قاعدة بيانات ، مستخدمين لبيئات 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، وهو وسيط رسائل لـ 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. سيتم استخدامه كخلفية لتخزين نتائج مهام الكرفس.
سنقوم برفع حاويتين من Docker مع Redis لبيئات dev و prod باستخدام الامتداد Docker لبليسك.
- نذهب إلى Plesk ، ونذهب إلى قسم الامتدادات ، ونبحث عن ملحق Docker وقم بتثبيته (نحتاج إلى إصدار مجاني):

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

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

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

وأضف قاعدة لحركة المرور الواردة إلى الحاوية الخاصة بنا:

- نتحقق من أنه يمكننا تسجيل الدخول إلى الحاوية الخاصة بنا من الجهاز المحلي:
$ 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:

عند النقر فوق استعراض المستودعات ، سيعرض المتصفح نافذة ترخيص حيث ستحتاج إلى إدخال اسم المستخدم وكلمة المرور للمستودع. بعد ذلك ، سيتم نقلنا إلى صفحة بها قائمة بالمستودعات (في الوقت الحالي ، ستكون فارغة بالنسبة لك):
فتح المنافذ في Plesk Firewall
بعد تثبيت المكونات وتكوينها ، نحتاج إلى فتح منافذ بحيث يمكن الوصول إلى المكونات من حاويات Docker والشبكة الخارجية.
دعونا نرى كيفية القيام بذلك باستخدام امتداد جدار الحماية لـ Plesk الذي قمنا بتثبيته سابقًا.
- اذهب إلى الأدوات والإعدادات> الإعدادات> جدار الحماية:

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

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

إعداد CI / CD في إجراءات Github
دعنا ننتقل إلى الجزء الأكثر إثارة للاهتمام - إعداد خط أنابيب تكامل مستمر وتسليم مشروعنا إلى الخادم.
يتكون خط الأنابيب هذا من جزأين:
- بناء صورة وإجراء الاختبارات (للواجهة الخلفية) - على جانب Github ؛
- تشغيل عمليات الترحيل (للخلفية) ونشر الحاويات - على الخادم.
انشر في Plesk
دعونا نتعامل مع النقطة الثانية أولاً (لأن النقطة الأولى تعتمد عليها).
سنقوم بتكوين عملية النشر باستخدام امتداد Git لـ Plesk.
ضع في اعتبارك مثالاً مع بيئة Prod لمستودع Backend.
- نذهب إلى الاشتراك في موقع Helloworld الخاص بنا وننتقل إلى القسم الفرعي Git:

- أدخل رابطًا إلى مستودع Github الخاص بنا في الحقل "Remote Git repository" وقم بتغيير المجلد الافتراضي
httpdocsإلى آخر (على سبيل المثال./httpdocs/hw_back):
- انسخ مفتاح SSH العمومي من الخطوة السابقة و في إعدادات جيثب.
- انقر فوق "موافق" على الشاشة في الخطوة 2 ، وبعد ذلك سيتم إعادة توجيهنا إلى صفحة المستودع في Plesk. الآن نحن بحاجة إلى تكوين المستودع ليتم تحديثه عند الالتزام بالفرع الرئيسي. للقيام بذلك ، انتقل إلى إعدادات المستودع وحفظ القيمة
Webhook URL(سنحتاجه لاحقًا عند إعداد إجراءات Github):
- في حقل الإجراءات على الشاشة من الفقرة السابقة ، أدخل البرنامج النصي لبدء النشر:
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 - أضف مستخدمًا من اشتراكنا إلى مجموعة 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 (مثال: :8443 أو : 8443) ؛DEPLOY_BACK_PROD_TOKEN- رمز مميز للنشر في مستودع الإنتاج على الخادم (حصلنا عليه في Deployment in Plesk p.4) ؛DEPLOY_BACK_DEV_TOKEN- رمز للنشر في مستودع dev على الخادم.
عملية النشر بسيطة وتتكون من ثلاث خطوات رئيسية:
- بناء ونشر الصورة في مستودعنا ؛
- إجراء الاختبارات في حاوية بناءً على صورة مبنية حديثًا ؛
- النشر في البيئة المرغوبة اعتمادًا على الفرع (dev / master).
الواجهة
تختلف قليلا عن بيك. يفتقر إلى خطوة في إجراء الاختبارات وتغيير أسماء الرموز المميزة للنشر. بالمناسبة ، يجب ملء أسرار المستودع الأمامي بشكل منفصل.
إعداد الموقع
إنشاء وكلاء لحركة المرور عبر Nginx
حسنًا ، لقد وصلنا إلى النهاية. يبقى فقط تكوين الوكلاء لحركة المرور الواردة والصادرة إلى حاويتنا عبر Nginx. لقد قمنا بالفعل بتغطية هذه العملية في الخطوة 5 من إعداد Docker Registry. يجب تكرار نفس الشيء للأجزاء الخلفية والأمامية في بيئات dev و prod.
سأقدم لقطات شاشة للإعدادات.
الخلفية

الواجهة

ажное уточнение. سيتم إنشاء وكلاء لجميع عناوين URL في حاوية الواجهة الأمامية ، باستثناء تلك التي تبدأ بـ /api/ - سيتم ربطهم بالحاوية الخلفية (هكذا في الحاوية الخلفية ، يجب أن تبدأ جميع المعالجات /api/).
نتائج
الآن يجب أن يكون موقعنا متاحًا على helloworld.ru و dev.helloworld.ru (بيئات prod و dev ، على التوالي).
في المجموع ، تعلمنا كيفية إعداد تطبيق بسيط في Flask و Angular وإعداد خط أنابيب في إجراءات Github لنشره على خادم يقوم بتشغيل Plesk.
سأكرر الروابط إلى المستودعات مع الكود: , .
المصدر: www.habr.com
