ما معنى DevOps؟ دليلك التطبيقي لميكنة مشروعاتك :)

مقدمة

هندسة (DevOps) تعني مجموعة من الممارسات التقنية التي تضم (Dev) أو المعروفة بـDevelopment و (Ops) أو المعروفة بـ IT Operations من أجل عمل ميكنة (automation)، وبالتالي زيادة قدرة الشركات على تسليم الخدمات والتطبيقات في أوقات قياسية وسريعة.

يشترك كل من فرق الـclient-side و الـserver-side ليصبحان فريق واحد تحت مظلة الـDevOps، حيث يقوم المهندسون بالمساهمة في جعل متابعة عملية التطوير تتم بشكل آلي، وفي بعض الحالات، يشارك فريق للجودة وأمن المعلومات خلال دورة التطوير للتطبيق، ما يجعلنا نطلق عليها اسم DevSecOps

مميزات DevOps ونقاط قوتها

  • السرعة الخارقة في تسليم الخدمات أو التطبيقات للعملاء في وقت قياسي:
    تحرك بسرعة عالية حتى تتمكن من الابتكار للعملاء بشكل أسرع ، والتكيف مع الأسواق المتغيرة بشكل أفضل ، وزيادة الكفاءة في تحقيق نتائج. يمكّن نموذج DevOps المطورين وفرق العمليات من تحقيق هذه النتائج. على سبيل المثال ، تتيح الخدمات الصغيرة micro-services والتسليم المستمر Continuous Delivery للفرق امتلاك الخدمات ومن ثم إصدار التحديثات لها بشكل أسرع.

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

  • الدقة والاعتمادية على الكود الأولي للمشروع:
    تأكد من جودة تحديثات التطبيقات وتغييرات البنية الأساسية حتى تتمكن من تقديمها بشكل موثوق به بوتيرة أسرع مع الحفاظ على تجربة إيجابية للمستخدمين.

  • تجهيز نظام للمساهمات بشكل أفضل:
    قم ببناء فرق أكثر فاعلية في إطار نموذج DevOps، والذي يؤكد على قيم مثل الملكية والمساءلة. يتعاون المطورون وفرق العمليات بشكل وثيق ، ويتشاركون في العديد من المسؤوليات ، ويجمعون بين سير العمل. وهذا يقلل من عدم الكفاءة ويوفر الوقت (على سبيل المثال ، تقليل فترات التسليم بين المطورين والعمليات ، وكتابة التعليمات البرمجية التي تأخذ في الاعتبار البيئة التي يتم تشغيلها فيها).

  • ضمان الالتزام بالمعايير الدولية للأمان

أقسام وممارسات DevOps

  • البناء أو التركيب المستمر Continuous Integration
  • التسليم المتواصل Continuous Delivery
  • الخدمات المصغرة Microservices
  • المتابعة والمراقبة Monitoring and Logging
  • التواصل والتعاون Communication and Collaboration

سنقوم بالتركيز على البناء المستمر Continuous Integration، وإذا كنت لا تعرف ماذا يعنى ذلك، لا تقلق :smiley: فالتدوينة ستساعدك خطوة بخطوة :muscle:

نكتفي بالنظريات هنا، ونجرب معا كيفية عمل DevOps ونبدأ بالمتطلبات:
1- حساب Github
2- الرغبة في تجربة شئ جديد

الكثير منا على الأقل جرب استخدام قيت هاب Github لمرة واحدة.
يحتاج المطورون عمل commits لحفظ الأكواد الجديدة من الضياع

مع كل commit يرسل متابعة آلية automated workflow على سيرفر البناء المستمر (CI server)


والذي بدوره يبلغ المطورين بشكل مستمر عن وجود مشاكل بالتحديثات الجديدة على الكود

بهذا الشكل، نستطيع تجنب كوارث قد تحدث عند دمج الأكواد الخاصة بالمشروع، والتي ستكلف وقت ومجهود وهدر للأموال بشكل كبير لحلها :sunglasses:

الخطوات

كما بالشكل، قمت بعمل new repository

رابط المستودع: https://github.com/sniperadmin/gh-actions-tutorial

سأستخدم في هذه التجربة مشروع بسيط بـ vuejs، لكن بالطبع يمكنك رفع أي مشروع بأي تقنية كـ Django أو Rust أو غيرها…

بعد رفع المشروع، نختر Actions


ستظهر لنا نافذة المحرر:

نلاحظ معا أن الملف بصيغة yml أو yaml => هي ليست لغة، هي عبارة عن مجموعة أوامر فقط يستطيع المبرمج فهمها،
هذه الأوامر -كما أشرنا سابقا- تكون لسيرفر البناء المستمر CI server

على سبيل المثال: نستطيع عمل test، أو تشغيل localhost server، أو عمل build أو رفع المشروع على هوست مثلا بشكل آلي

تخيل كم مرة نقوم بهذه الأشياء يدويا باستخدام أوامر الـterminal :tired_face:

الآن لنتصفح المثال المرفق لكيفية كتابة أول workflow:

# This is a basic workflow to help you get started with Actions

name: CI Name  # هنا نضع اسم العملية

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on: # نستخدمها لضبط توقيت بدء العملية
  push: # هنا تبدأ العملية عند رفع الكود على الفرع الرئيسي ماستر
    branches: [ master ]
  pull_request: # وهنا تبدأ العملية عند عمل طلب سحب
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs: # كل عملية تتكون من عدة وظائف
  # This workflow contains a single job called "build"
  build-for-production: # هنا نعطي أي اسم يعبر عن الوظيفة التي سيقوم بها السيرفر
    # The type of runner that the job will run on
    runs-on: ubuntu-latest  # نظام تشغيل السيرفر، وهنا يوجد خيارات كثيرة مرفقة بالصورة أسفل الكود

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps: # هنا الخطوات أو المهمات التي سيقوم بها السيرفر
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v2  # هذه الخطوة مهمة حيث تقوم بتوجيه السيرفر إلى الفولدر أو المشروع الحالي

    # Runs a single command using the runners shell
    - name: Run a one-line script  # اسم المهمة الأولى
      run: echo Hello, world! # الأمر الخاص بالمهمة الأولى

    # Runs a set of commands using the runners shell
    - name: Run a multi-line script  # اسم المهمة الثانية
      run: |
        echo Add other actions to build,    # الأوامر الخاصة بالمهمة الثانية
        echo test, and deploy your project.

هذا المثال يوضح شكل الملف الذي سنكتب فيه التعليمات للسيرفر
نلاحظ الأمر runs-on: – إليكم أنظمة التشغيل المتاحة لسيرفر الـCI


بالمثال قد اخترنا ubuntu-latest

يمكننا كتابة workfow بكل سهولة مع الأخذ في الاعتبار أن ملفات الworkflow تكون في المكان الصحيح وهو:
/.github/workflows
سيقوم السيرفر بالبحث عن فولدر .github ويستطيع التعرف على الملفات الداخلية وتشغيلها

بعد أن تعرفنا على طريقة كتابة الworkflow بشكل مختصر، سأبدأ بكتابة أوامر بسيطة لمستودعي الخاص

كما نعلم، جميع أوامر فريمووركات الجافاسكريبت تكون في ملف package.json
لنلق نظرة على الملف الخاص بي:

سأقوم بعمل build للمشروع من أجل إنتاج نسخة الproduction والتي ستكون في فولدر اسمه dist وفيه صفحة html وملفات الجافاسكريبت

قبل البداية، سنأخذ فرع branch من الماستر حتى لا نتعامل مع الماستر بشكل مباشر

git checkout -b add-yaml

ونكتب الworkflow:

# This is a basic workflow to help you get started with Actions

name: Build CI  # هنا نضع اسم العملية

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on: # نستخدمها لضبط توقيت بدء العملية
  push: # هنا تبدأ العملية عند رفع الكود على الفرع الرئيسي ماستر
    branches: [ master ]
  pull_request: # وهنا تبدأ العملية عند عمل طلب سحب
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs: # كل عملية تتكون من عدة وظائف
  # This workflow contains a single job called "build"
  build-for-production: # هنا نعطي أي اسم يعبر عن الوظيفة التي سيقوم بها السيرفر
    # The type of runner that the job will run on
    runs-on: ubuntu-latest  # نظام تشغيل السيرفر، وهنا يوجد خيارات كثيرة مرفقة بالصورة أسفل الكود

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps: # هنا الخطوات أو المهمات التي سيقوم بها السيرفر
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - uses: actions/checkout@v2  # هذه الخطوة مهمة حيث تقوم بتوجيه السيرفر إلى الفولدر أو المشروع الحالي

    # Runs a single command using the runners shell
    - name: install npm  # اسم المهمة الأولى
      run: npm i # الأمر الخاص بالمهمة الأولى

    # Runs a set of commands using the runners shell
    - name: check npm version and build  # اسم المهمة الثانية
      run: |
        npm --version    # الأوامر الخاصة بالمهمة الثانية
        npm run build

طبعا يمكن كتابة كل أوامر npm في مكان واحد، لكن أردت عرض كيفية كتابتها بأكثر من شكل
الآن نخبر github أن يحفظ لنا التعديلات ويرفعها على المستودع:

git add .
git commit -m "add workflow"
git push -u origin add-yaml

الآن تم رفع الكود الجديد حسب ما ظهر في الـterminal:

$ git push -u origin add-yaml
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 1.26 KiB | 1.26 MiB/s, done.
Total 5 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote:
remote: Create a pull request for 'add-yaml' on GitHub by visiting:
remote:      https://github.com/sniperadmin/gh-actions-tutorial/pull/new/add-yaml
remote:
To https://github.com/sniperadmin/gh-actions-tutorial
 * [new branch]      add-yaml -> add-yaml
Branch 'add-yaml' set up to track remote branch 'add-yaml' from 'origin'.

نتوجه إلى قيت هاب:


كما نرى في الشكل التالي، السيرفر الآن يعمل:

يمكنك النقر على details لمعرفة المزيد
وكما نشاهد قد أتم السيرفر المهمة!
في حالة المثال، المهمة اكتملت بشكل ناجح (نعرفها من العلامة :white_check_mark: )
إذا كان هناك أخطاء، فببساطة نعدل الأخطاء ونقوم بعمل push للكود الجديد على نفس الفرع وننتظر السيرفر :white_check_mark:

بالطبع يمكننا عمل أشياء خرافية بهذه الأداة العبقرية:(كعمل deploy على هوست بشكل آلي، كل ما عليك فقط هو الاهتمام بالكود، وقيت هاب سيتولى تحديث الموقع :wink:)

رابط المستودع: https://github.com/sniperadmin/gh-actions-tutorial

مصادر أخرى للمزيد حول ملفات yaml:
https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions

11 Likes

مقال مره رائع أشكرك كثيرا على شرحك لتقنية مثل هذه فأنا أول مرة أتعرف عليها :heart_eyes: :heart_eyes: :heart_eyes:

1 Like

كفيت و وفيت ي نصر، مقال مفيد جداً :+1:

احنا اصحاب الفرونت مستمتعين مع Netlify يريح رأسنا مع عمليات الـ Devops :rofl:

هذا مثال لعملية الـ build تبع vue :ok_hand:

3 Likes

و أيضا heroku يريحنا كتير :laughing: :laughing:

بس الفكرة في الاختبارات نفسها، ممكن نتأكد ان نسبة الcode coverage لو أقل من 80% مثلا، الdeveloper لا يستطيع عمل merge للكود
بالنسبة للdeploy، يمكننا عمل deploy version لكل pull request على netlify منفصلة عن الماستر بحيث يمكن للمطور رؤية نتائج الcommits في نسخة الproduction

3 Likes

:star_struck: رائع كل شيئ يمشي كما هو متوقع … شكرا نصر على المقال الرائع

3 Likes

الله يا هشام… :smiley:
وحش والله :smiley:

3 Likes

انت @sniperadmin مستعمل اومر npm وانا كنت هسئل عليه، انا متابع مسار فى تعلم java script على udacity اتعلمت بعض الكواد الخاصة بjava script وبعد كدة نبذة عن الاداء كما وضحت وبعد كدة دخلت فى APIs ودخلنى فى Node js واستعملت Express وعملت localhost وتعملت string and json

// Express to run server and routes
const express = require('express');

// Start up an instance of app
const app = express();

/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
//Here we are configuring express to use body-parser as middle-ware.
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Cors for cross origin allowance
const cors = require('cors');
app.use(cors());

خدت شوية المعلومات دى ودماغى عملت كدة :dizzy_face: مش موجود

3 Likes

طبيعي هتعمل كدة :dizzy_face:
ادي فرصة للعقل الباطن يستوعب، حاليا كويس انك أخذت فكرة
وببساطة هشرحلك الموضوع:

كل حاجة من اللي قلتها بتعمل وظيفة مختلفة تماما بس في قصة صغيرة بتحكي عن مصدر الكلام ده:
كل المبرمجين تقريبا كانوا يبنون كل الوظائف والإضافات من الصفر، وده كان بيخلي العمل شاق جدا وصعب،
فقرروا انهم يعملوا مكتبات تكون جاهزة وتوفر عليهم عناء كتابة الكود من الصفر، في نفس الوقت، مكانش في وسيله تخليهم يخزنوا أو يرسلو المكتبات دي عن طريقها، ومن هنا جات فكرة Node Package Manager (NPM)

التطور في لغة جافاسكريبت سريع جدا ورهيب لدرجة ان في فريمووركات بتحاول تسابق الزمن عشان تواكب السرعة الرهيبة دي!
هل سألت نفسك في مرة: “كيف يعمل الـconsole.log” في المتصفحات؟

في محرك javascript رئيسي بيشغل المتصفحات وبيخليها تقدر تستوعب الكود المكتوب وتحوله لـnodes و بعدين Tree عشان يظهر شكل الصفحة النهائي بالأماكن والألوان المكتوبين في الكود، المحرك ده اسمه Nodejs

عشان نقدر نشغل الكود بتاعنا على الجهاز (في برنامج محرر الأكواد) بنحتاج ننزل المحرك ده ونستخدمه زي ما شفت لما بنعمل سيرفر يشغل كود الnode عن طريق الأمر node file-name

كدة أظن الصورة وضحت شوية، خلينا نتكلم عن باقي الحاجات في تعليق تاني

4 Likes

مقال جميل جدا أخي نصر، أهنيك عليه :balloon::heart_eyes:.
كانت لي أيضا تجربة متواضعة مع ال DevOps وبالخصوص Gitlab CI/CD. حقا شيء خرافي ويسهل عليك العمل. بصفتك كمطور برامج يكون تركيزك كله أن تبدع في كودك دون أن تتعب عقلك في التفكير في الDeployment وما إلى ذلك لأنها تتم بشكل تلقائي.

4 Likes

رائع جدا يا نصر
شكرا جزيلا و بارك الله فيك على مجهوداتك
اصبح التدوين في المجتمع مبهر فعلا و ممتع جدا
ما شاء الله

3 Likes

يعطيك العافية نصر، معلومات مفيدة وشرح عملي رائع

جربت Github Actions وأعجبني تنوع أنظمة السيرفرات المتاحة لتنفيذ السكريبت

لكني وجدت Gitlab CI/CD أقل تعقيدًا

كذلك خيار التشغيل اليدوي للسكريبت كان مهم جدًا بالنسبة لي وما وجدته في Github Actions

4 Likes

@TChiOfficiel
@LouayH

فكرة ممتازة أن نكتب تدوينة عن gitlab-ci
يلا، خلونا نشوف الابداعات

4 Likes

وفيك بارك

هي تعتبر التدوينة المدخل إلى عالم الDevOps
وهو بحر كبير

2 Likes

مبارك لك يا نصر على المقال الأكثر من رائع… نشرت المقالة على تويتر وحتى الآن مقالتك تقريبا شافها 25 ألف شخص :astonished:

3 Likes

لم أكن أعلم أن الطلب على مثل هاته التخصصات كبير بهذا الشكل
الحمد لله، مسرور بعودة كورتابز!

سأكمل السلسلة بإذن الله

3 Likes

شكرا لك مقال رائع
:heart:

3 Likes

ما شاء الله
ابدعت حبيبنا @sniperadmin
مقال جميل
نفتقر في الاوساط التقنية العربية لمثل هذه المقالات
استمر … :rose:

1 Like

الحمد لله ان رسالة المقال وصلت
تسلم حبيبي
ان شاء الله أواصل :star_struck: