ورشة عمل تعديل التطبيقات

1. مقدمة

تاريخ آخر تعديل: 2024-11-01

كيف يمكننا تحديث تطبيق PHP قديم ليصبح متوافقًا مع Google Cloud؟

(📽️ شاهِد فيديو تعريفيًا مدته 7 دقائق عن هذا الدرس التطبيقي حول الترميز)

من الشائع أن تكون هناك تطبيقات قديمة تعمل في المؤسسة وتحتاج إلى التحديث. وهذا يعني جعلها قابلة للتوسّع وآمنة وقابلة للنشر في بيئات مختلفة.

في ورشة العمل هذه، ستتمكّن من:

  1. تضمين تطبيق PHP في حاوية
  2. الانتقال إلى خدمة قاعدة بيانات مُدارة ( Cloud SQL)
  3. النشر على Cloud Run (بديل GKE/Kubernetes الذي لا يتطلّب أي عمليات)
  4. تأمين التطبيق باستخدام خدمة "إدارة الهوية وإمكانية الوصول" (IAM) وSecret Manager
  5. تحديد مسار التكامل المستمر/التسليم المستمر من خلال Cloud Build يمكن ربط Cloud Build بمستودع Git المستضاف على مزوّدي Git المعروفين، مثل GitHub أو GitLab، ويمكن تشغيله عند إجراء أي عملية دفع إلى الفرع الرئيسي، على سبيل المثال.
  6. استضافة صور التطبيق على Cloud Storage ويتم تحقيق ذلك من خلال التثبيت، ولا يلزم استخدام أي رمز لتغيير التطبيق.
  7. تقديم وظائف الذكاء الاصطناعي التوليدي من خلال Gemini، ويتم تنسيقها عبر Cloud Functions (بدون خادم)
  8. تعرَّف على اتفاقيات مستوى الخدمة وتشغيل تطبيقك الذي تم تحديثه حديثًا.

باتّباع هذه الخطوات، يمكنك تحديث تطبيق PHP تدريجيًا، ما يؤدي إلى تحسين قابلية التوسّع والأمان ومرونة النشر. بالإضافة إلى ذلك، يتيح لك الانتقال إلى Google Cloud الاستفادة من بنيته الأساسية وخدماته الفعّالة لضمان تشغيل تطبيقك بسلاسة في بيئة مستنِدة إلى السحابة الإلكترونية.

نرى أنّ ما ستتعلّمه من خلال اتّباع هذه الخطوات البسيطة يمكن تطبيقه على تطبيقك ومؤسستك باستخدام لغة/حزمة مختلفة وحالات استخدام مختلفة.

لمحة عن التطبيق

التطبيق ( الرمز، بموجب ترخيص MIT) الذي ستجري له عملية تفريع هو تطبيق PHP 5.7 أساسي يتضمّن مصادقة MySQL. الفكرة الرئيسية للتطبيق هي توفير منصة يمكن للمستخدمين من خلالها تحميل الصور، ويمكن للمشرفين الإبلاغ عن الصور غير الملائمة. يحتوي التطبيق على جدولَين:

  • المستخدمون يأتي مجمَّعًا مسبقًا مع المشرفين. يمكن للمستخدمين الجدد التسجيل.
  • الصور يتضمّن بعض الصور النموذجية. يمكن للمستخدمين الذين سجّلوا الدخول تحميل صور جديدة. سنضيف بعض السحر هنا.

هدفك

نريد تطوير التطبيق القديم ليكون متاحًا في Google Cloud. سنستفيد من أدواتها وخدماتها لتحسين قابلية التوسع وتعزيز الأمان وأتمتة إدارة البنية الأساسية ودمج الميزات المتقدّمة، مثل معالجة الصور والرصد وتخزين البيانات باستخدام خدمات مثل Cloud SQL وCloud Run وCloud Build وSecret Manager وغيرها.

445f7a9ae37e9b4d.png

والأهم من ذلك، نريد أن نقدّم لك هذه المعلومات خطوة بخطوة لتتمكّن من فهم عملية التفكير الكامنة وراء كل خطوة، وعادةً ما تتيح كل خطوة إمكانات جديدة للخطوات التالية (مثال: الوحدتان 2 و3، والوحدتان 6 و7).

ألم نقنعك بعد؟ يمكنك مشاهدة هذا الفيديو الذي تبلغ مدته 7 دقائق على YouTube.

المتطلبات

  • جهاز كمبيوتر مزوّد بمتصفّح ومتصل بالإنترنت
  • بعض الاعتمادات في Google Cloud Platform اطّلِع على الخطوة التالية لمعرفة المزيد.
  • ستستخدِم Cloud Shell. يأتي مزوّدًا بجميع الأوامر المثبَّتة مسبقًا التي ستحتاج إليها وبيئة تطوير متكاملة.
  • حساب GitHub يجب توفّر هذا الرمز لتفريغ الرمز الأصلي 🧑🏻‍💻 gdgpescara/app-mod-workshop باستخدام مستودع git الخاص بك. هذا الإجراء مطلوب لإنشاء مسار الدمج المتواصل/النشر المتواصل (التنفيذ التلقائي -> الإنشاء -> النشر).

يمكنك الاطّلاع على حلول نموذجية هنا:

تم تصميم ورشة العمل هذه ليتم إكمالها على Cloud Shell (في المتصفّح).

ومع ذلك، يمكن أيضًا محاولة تنفيذها من جهاز الكمبيوتر المحلي.

2. إعداد الائتمان وFork

6dafc658860c0ce5.png

تحصيل قيمة رصيد Google Cloud Platform وإعداد بيئة Google Cloud Platform [اختياري]

لإجراء ورشة العمل هذه، يجب أن يكون لديك حساب فوترة يتضمّن بعض الرصيد. استخدِم الرصيد من البانر في أعلى هذا الدرس التطبيقي للبدء. إذا كنت مرتبطًا بحساب فوترة، يمكنك تخطّي هذه الخطوة.

بعد الانتهاء من ذلك، افتح Google Cloud Console وأنشئ مشروعًا جديدًا من خلال النقر على "أداة اختيار المشاريع" في القائمة المنسدلة أعلى يمين الصفحة حيث يظهر "لا توجد مؤسسة". انظر أدناه

bd7548f78689db0b.png

أنشِئ مشروعًا جديدًا إذا لم يكن لديك مشروع، كما هو موضّح في لقطة الشاشة أدناه. يتوفّر خيار "مشروع جديد" في أعلى يسار الصفحة.

6c82aebcb9f5cd47.png

احرص على ربط المشروع الجديد بحساب فوترة الفترة التجريبية في Google Cloud Platform على النحو التالي.

f202527d254893fb.png

يمكنك الآن استخدام Google Cloud Platform. إذا كنت مبتدئًا أو أردت إجراء كل شيء في بيئة سحابية، يمكنك الوصول إلى Cloud Shell والمحرّر الخاص به من خلال الزر التالي في أعلى يسار الصفحة كما هو موضّح أدناه.

7d732d7bf0deb12e.png

تأكَّد من اختيار مشروعك الجديد في أعلى يمين الصفحة:

لم يتم اختيارها (سيئة):

c2ffd36a781b276a.png

تم الاختيار (جيد):

594563c158f4f590.png

إنشاء نسخة من التطبيق من GitHub

  1. انتقِل إلى التطبيق التجريبي: https://github.com/gdgpescara/app-mod-workshop
  2. انقر على 🍴 fork.
  3. إذا لم يكن لديك حساب على GitHub، عليك إنشاء حساب جديد.
  4. عدِّل المحتوى كما تريد.

734e51bfc29ee5df.png

  1. استنساخ رمز التطبيق باستخدام
  2. git clone https://github.com/YOUR-GITHUB-USER/YOUR-REPO-NAME
  1. افتح مجلد المشروع المستنسخ باستخدام محرّر النصوص المفضّل لديك. إذا اخترت Cloud Shell، يمكنك إجراء ذلك من خلال النقر على فتح المحرّر كما هو موضّح أدناه.

40f5977ea4c1d1cb.png

يتوفّر لديك كل ما تحتاجه باستخدام "محرِّر Google Cloud Shell" كما هو موضّح في الشكل التالي

a4e5ffb3e9a35e84.png

يمكنك إجراء ذلك بشكل مرئي من خلال النقر على "فتح المجلد" واختيار المجلد، والذي من المحتمل أن يكون app-mod-workshop في مجلدك الرئيسي.

3- الوحدة 1: إنشاء مثيل SQL

645902e511a432a6.png

إنشاء مثيل Google Cloud SQL

سيرتبط تطبيق PHP بقاعدة بيانات MySQL، لذا علينا تكرارها في Google Cloud لإجراء عملية نقل سلسة. ‫Cloud SQL هي الخيار الأمثل لأنّها تتيح لك تشغيل قاعدة بيانات MySQL مُدارة بالكامل في السحابة الإلكترونية. في ما يلي الخطوات التي يجب اتّباعها:

  1. انتقِل إلى صفحة Cloud SQL: https://console.cloud.google.com/sql/instances
  2. انقر على "إنشاء آلة افتراضية".
  3. فعِّل واجهة برمجة التطبيقات (إذا لزم الأمر). قد يستغرق ذلك بضع ثوانٍ.
  4. اختَر MySQL.
  5. (نحاول أن نقدّم لك أرخص إصدار حتى يدوم لفترة أطول):
  • الإصدار: Enterprise
  • الضبط المُسبَق: تطوير (جرّبنا Sandbox ولم ينجح معنا)
  • إصدار Mysql: 5.7 (يا له من إصدار قديم!)
  1. معرّف المثيل: اختَر appmod-phpapp (إذا غيّرت هذا المعرّف، تذكَّر تغيير النصوص البرمجية والحلول المستقبلية أيضًا وفقًا لذلك).
  2. كلمة المرور: أي كلمة مرور تريدها، ولكن يجب تدوينها باسم CLOUDSQL_INSTANCE_PASSWORD
  3. المنطقة: احتفظ بالمنطقة نفسها التي اخترتها لبقية التطبيق (مثلاً، ميلانو = europe-west8)
  4. Zonal avail: Single Zone (نوفّر المال للعرض التوضيحي)

انقر على الزر "إنشاء مثيل" لنشر قاعدة بيانات Cloud SQL. ⌛ يستغرق إكمال هذه العملية حوالي 10 دقائق⌛. في هذه الأثناء، واصِل قراءة المستندات، ويمكنك أيضًا البدء في حلّ الوحدة التالية ("تضمين تطبيق PHP في حاوية") لأنّها لا تعتمد على هذه الوحدة في الجزء الأول (إلى أن تحلّ مشكلة الاتصال بقاعدة البيانات).

ملاحظة من المفترض أن تكلّفك هذه الآلة الافتراضية حوالي 7 دولارات أمريكية في اليوم. احرص على إيقافها بعد انتهاء ورشة العمل.

إنشاء قاعدة بيانات image_catalog ومستخدم في Cloud SQL

يأتي مشروع التطبيق مع مجلد db/ يحتوي على ملفَي sql:

  1. 01_schema.sql : يحتوي على رمز SQL لإنشاء جدولَين يتضمّنان بيانات المستخدمين والصور.
  2. 02_seed.sql: يحتوي على رمز SQL لتعبئة البيانات في الجداول التي تم إنشاؤها سابقًا.

سيتم استخدام هذه الملفات لاحقًا بعد إنشاء قاعدة بيانات image_catalog. يمكنك إجراء ذلك من خلال اتّباع الخطوات التالية:

  1. افتح مثيلك وانقر على علامة التبويب "قواعد البيانات":
  2. انقر على "إنشاء قاعدة بيانات"
  3. أطلِق عليه اسم image_catalog (كما هو الحال في إعدادات تطبيق PHP).

997ef853e5ebd857.png

بعد ذلك، ننشئ مستخدم قاعدة البيانات. باستخدام هذا المعرّف، يمكننا المصادقة على قاعدة بيانات image_catalog.

  1. انقر الآن على علامة التبويب المستخدمون.
  2. انقر على "إضافة حساب مستخدم".
  3. المستخدم: لننشئ واحدًا:
  • اسم المستخدم: appmod-phpapp-user
  • كلمة المرور: اختَر كلمة مرور يمكنك تذكُّرها، أو انقر على "إنشاء"
  • احتفِظ بالإعداد "السماح بأي مضيف (%)".
  1. انقر على "إضافة".

افتح قاعدة البيانات لعناوين IP المعروفة.

يُرجى العِلم أنّ جميع قواعد البيانات في Cloud SQL تكون "معزولة" منذ إنشائها. عليك إعداد شبكة بشكل صريح لتتمكّن من الوصول إليها.

  1. انقر على الآلة الافتراضية
  2. فتح القائمة "عمليات الربط"
  3. انقر على علامة التبويب "الشبكات".
  4. انقر على "الشبكات المعتمَدة". الآن، أضِف شبكة (أي شبكة فرعية).
  • في الوقت الحالي، لنختر إعدادات سريعة ولكنها غير آمنة من أجل السماح للتطبيق بالعمل. يمكنك حصرها لاحقًا على عناوين IP التي تثق بها:
  • الاسم: "الجميع في العالم - غير آمن".
  • الشبكة: "0.0.0.0/0" (ملاحظة: هذا هو الجزء غير الآمن!)
  • انقر على "تم".
  1. انقر على "حفظ".

ينبغي أن تظهر لك على النحو التالي:

5ccb9062a7071964.png

ملاحظة هذا الحلّ هو حلّ وسط جيد لإنهاء ورشة العمل في غضون ساعات. ومع ذلك، يُرجى الاطّلاع على مستند الأمان للمساعدة في تأمين الحلّ الذي ستستخدمه في مرحلة الإنتاج.

حان الوقت لاختبار اتصال قاعدة البيانات!

لنتحقّق مما إذا كان حساب المستخدم image_catalog الذي أنشأناه سابقًا يعمل.

يمكنك الوصول إلى "Cloud SQL Studio" داخل المثيل وإدخال قاعدة البيانات والمستخدم وكلمة المرور ليتمّ إثبات هويتك كما هو موضّح أدناه:

d56765c6154c11a4.png

بعد ذلك، يمكنك فتح "محرّر SQL" والمتابعة إلى القسم التالي.

استيراد قاعدة البيانات من قاعدة الرموز

استخدِم "محرّر SQL" لاستيراد جداول image_catalog مع بياناتها. انسخ رمز SQL من الملفات في المستودع ( 01_schema.sql ثم 02_seed.sql) ونفِّذها واحدًا تلو الآخر بترتيب تسلسلي.

بعد ذلك، من المفترض أن يظهر لك جدولان في image_catalog، وهما users وimages كما هو موضّح أدناه:

65ba01e4c6c2dac0.png

يمكنك اختبارها من خلال تنفيذ ما يلي في المحرّر: select * from images;

تأكَّد أيضًا من تدوين عنوان IP العلني لمثيل Cloud SQL، لأنّك ستحتاج إليه لاحقًا. للحصول على عنوان IP، انتقِل إلى صفحة Cloud SQL الرئيسية ضمن صفحة نظرة عامة. (نظرة عامة > الربط بهذه الآلة الافتراضية > عنوان IP العام).

4. الوحدة 2: إنشاء حاوية لتطبيق PHP

e7f0e9979d8805f5.png

نريد إنشاء هذا التطبيق على السحابة الإلكترونية.

وهذا يعني تجميع الرمز في نوع من ملفات ZIP التي تحتوي على جميع المعلومات اللازمة لتشغيله في السحابة الإلكترونية.

هناك بضع طرق لتغليفها:

  • Docker شائعة جدًا، ولكنّها معقّدة إلى حدّ ما عند إعدادها بشكل صحيح.
  • حِزم الإنشاء أقل شيوعًا، ولكنّه يميل إلى "التخمين التلقائي" لما يجب إنشاؤه وما يجب تنفيذه. وفي كثير من الأحيان، ينجح ذلك.

في سياق ورشة العمل هذه، سنفترض أنّك تستخدم Docker.

إذا اخترت استخدام Cloud Shell، عليك إعادة فتحه الآن (انقر على أعلى يسار وحدة تحكّم السحابة الإلكترونية).

ec6a6b90b39e03e.png

سيؤدي ذلك إلى فتح نافذة shell ملائمة في أسفل الصفحة، حيث من المفترض أن تكون قد أنشأت نسخة من الرمز في خطوة الإعداد.

6999b906c0dedeb7.png

Docker

إذا كنت تريد التحكّم في هذه العملية، هذا هو الحلّ المناسب لك. يكون ذلك منطقيًا عندما تحتاج إلى ضبط مكتبات معيّنة وإدخال سلوكيات غير واضحة (مثل chmod في عمليات التحميل، أو ملف تنفيذي غير عادي في تطبيقك، وما إلى ذلك).

بما أنّنا نريد في النهاية نشر تطبيقنا الذي يعمل ضمن حاوية على Cloud Run، راجِع المستندات التالية. كيف يمكن نقلها من الإصدار 8 من PHP إلى الإصدار 5.7 من PHP؟ ربما يمكنك استخدام Gemini لإجراء ذلك. بدلاً من ذلك، يمكنك استخدام هذا الإصدار المُعدّ مسبقًا:

# Use the official PHP image: https://hub.docker.com/_/php
FROM php:5.6-apache

# Configure PHP for Cloud Run.
# Precompile PHP code with opcache.
# Install PHP's extension for MySQL
RUN docker-php-ext-install -j "$(nproc)" opcache mysqli pdo pdo_mysql && docker-php-ext-enable pdo_mysql

RUN set -ex; \
  { \
    echo "; Cloud Run enforces memory & timeouts"; \
    echo "memory_limit = -1"; \
    echo "max_execution_time = 0"; \
    echo "; File upload at Cloud Run network limit"; \
    echo "upload_max_filesize = 32M"; \
    echo "post_max_size = 32M"; \
    echo "; Configure Opcache for Containers"; \
    echo "opcache.enable = On"; \
    echo "opcache.validate_timestamps = Off"; \
    echo "; Configure Opcache Memory (Application-specific)"; \
    echo "opcache.memory_consumption = 32"; \
  } > "$PHP_INI_DIR/conf.d/cloud-run.ini"

# Copy in custom code from the host machine.
WORKDIR /var/www/html

COPY . .

# Setup the PORT environment variable in Apache configuration files: https://cloud.google.com/run/docs/reference/container-contract#port
ENV PORT=8080

# Tell Apache to use 8080 instead of 80.
RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf

# Note: This is quite insecure and opens security breaches. See last chapter for hardening ideas.
# Uncomment at your own risk:
#RUN chmod 777 /var/www/html/uploads/

# Configure PHP for development.
# Switch to the production php.ini for production operations.
# RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
# https://github.com/docker-library/docs/blob/master/php/README.md#configuration
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"

# Expose the port
EXPOSE 8080

يتوفّر أحدث إصدار من Dockerfile هنا.

لاختبار تطبيقنا محليًا، علينا تغيير ملف config.php بطريقة تتيح لتطبيق PHP الاتصال بقاعدة بيانات MySQL المتوفّرة على Google CloudSQL. استنادًا إلى ما سبق أن أعددته، املأ الفراغات:

<?php
// Database configuration
$db_host = '____________';
$db_name = '____________';
$db_user = '____________';
$db_pass = '____________';

try {
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Errore di connessione: " . $e->getMessage());
}

session_start();
?>
  • DB_HOST هو عنوان IP العام لـ Cloud SQL، ويمكنك العثور عليه في وحدة تحكّم SQL:

bd27071bf450a8d0.png

  • يجب أن يبقى DB_NAME بدون تغيير: image_catalog
  • يجب أن يكون DB_USER هو appmod-phpapp-user
  • DB_PASS هو شيء اخترته. اضبطها بين علامتَي اقتباس مفردتَين واضبطها حسب الحاجة.

يمكنك أيضًا ترجمة بعض المحتوى 🇮🇹 الإيطالي إلى اللغة الإنجليزية بمساعدة Gemini.

حسنًا، بعد أن حصلت على Dockerfile وأعددت تطبيق PHP للاتصال بقاعدة البيانات، لنختبر ذلك.

ثبِّت Docker إذا لم يكن مثبّتًا بعد ( رابط). لا تحتاج إلى ذلك إذا كنت تستخدم Cloud Shell (أليس هذا رائعًا؟).

الآن، حاوِل إنشاء تطبيق PHP المستنِد إلى الحاويات وتشغيله باستخدام أوامر الإنشاء والتشغيل المناسبة في Docker.

# Build command - don't forget the final . This works if Dockerfile is inside the code folder:
$ docker build -t my-php-app-docker .   

# Local Run command: most likely ports will be 8080:8080
$ docker run -it -p <CONTAINER_PORT>:<LOCAL_MACHINE_PORT> my-php-app-docker

إذا كان كل شيء يعمل، من المفترض أن تتمكّن من رؤية صفحة الويب التالية عند الاتصال بالمضيف المحلي. الآن يتم تشغيل تطبيقك على المنفذ 8080، انقر على رمز "معاينة الويب" (متصفح مع عين) ثم على المعاينة على المنفذ 8080 (أو "تغيير المنفذ" لأي منفذ آخر).

33a24673f4550454.png

اختبار النتيجة على المتصفّح

يجب أن يبدو تطبيقك الآن على النحو التالي:

2718ece96b1f18b6.png

وإذا سجّلت الدخول باستخدام Admin/admin123، سيظهر لك ما يلي.

68b62048c2e86aea.png

رائع!!! باستثناء النص الإيطالي، تعمل الميزة بشكل جيد. 🎉🎉🎉

إذا كانت عملية إنشاء الحاويات جيدة ولكن بيانات اعتماد قاعدة البيانات غير صحيحة، قد يظهر لك ما يلي:

e22f45b79bab86e1.png

أعِد المحاولة، أنت قريب من اللفظ الصحيح.

الحفظ في Artifact Registry [اختياري]

في هذه المرحلة، يجب أن يكون لديك تطبيق PHP يعمل ضمن حاوية وجاهز للنشر على السحابة الإلكترونية. بعد ذلك، نحتاج إلى مساحة على السحابة الإلكترونية لتخزين صورة Docker وإتاحتها للنشر على خدمات Google Cloud، مثل Cloud Run. يُطلق على حلّ التخزين هذا اسم Artifact Registry، وهو خدمة مُدارة بالكامل من Google Cloud ومصمَّمة لتخزين عناصر التطبيقات، بما في ذلك نُسخ حاويات Docker وحِزم Maven ووحدات npm وغير ذلك.

لننشئ مستودعًا في Google Cloud Artifact Registry باستخدام الزر المناسب.

e1123f0c924022e6.png

اختَر اسمًا صالحًا والتنسيق والمنطقة المناسبة لتخزين العناصر.

4e516ed209c470ee.png

ارجع إلى علامة بيئة التطوير المحلية وادفع صورة حاوية التطبيق إلى مستودع Artifact Registry الذي تم إنشاؤه للتو. أدخِل الأوامر التالية لإجراء ذلك.

  • docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
  • docker push TARGET_IMAGE[:TAG]

يجب أن تبدو النتيجة مثل لقطة الشاشة التالية.

1e498feb4e88be9f.png

تهانينا 🎉🎉🎉 يمكنك الانتقال إلى المستوى التالي. قبل ذلك، يمكنك قضاء دقيقتَين في محاولة التحميل أو تسجيل الدخول أو تسجيل الخروج والتعرّف على نقاط نهاية التطبيق، لأنّك ستحتاج إليها لاحقًا.

الأخطاء المحتملة

إذا ظهرت لك أخطاء في إنشاء الحاويات، جرِّب استخدام Gemini لشرح الخطأ وحلّه، مع تقديم ما يلي:

  • ملف Dockerfile الحالي
  • الخطأ الذي تم تلقّيه
  • [إذا لزم الأمر] رمز PHP الذي يتم تنفيذه

أذونات التحميل جرِّب أيضًا نقطة النهاية /upload.php وحاوِل تحميل صورة. قد يظهر لك الخطأ أدناه. في هذه الحالة، عليك إجراء بعض التعديلات في Dockerfile.chmod/chown

Warning: move_uploaded_file(uploads/image (3).png): failed to open stream: Permission denied in /var/www/html/upload.php on line 11

PDOException "could not find driver" (أو "Errore di connessione: could not find driver"). تأكَّد من أنّ ملف Dockerfile يتضمّن مكتبات PDO المناسبة لـ mysql (pdo_mysql) من أجل الاتصال بقاعدة البيانات. يمكنك استلهام أفكار من الحلول في هذا الرابط.

يتعذّر إعادة توجيه طلبك إلى نظام الخلفية. تعذّر الاتصال بخادم على المنفذ 8080. وهذا يعني على الأرجح أنّك تعرض المَنفَذ غير الصحيح. تأكَّد من أنّك تعرض المنفذ الذي يتم من خلاله عرض المحتوى باستخدام Apache/Nginx. هذا ليس بالأمر البسيط. إذا كان ذلك ممكنًا، حاوِل ضبط هذا المنفذ على 8080 (لتسهيل استخدام Cloud Run). إذا أردت الاحتفاظ بالمنفذ 80 (على سبيل المثال، لأنّ Apache يتطلّب ذلك)، استخدِم أمرًا مختلفًا لتشغيله:

$ docker run -it -p 8080:80 # force 80

# Use the PORT environment variable in Apache configuration files.

# https://cloud.google.com/run/docs/reference/container-contract#port

RUN sed -i 's/80/${PORT}/g' /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf

5- الوحدة 3: نشر التطبيق على Cloud Run

9ffca42774f6c5d1.png

لماذا Cloud Run؟

هذا سؤال وجيه. قبل سنوات، كنت ستختار بالتأكيد Google App Engine.

ببساطة، تتضمّن خدمة Cloud Run اليوم حزمة التكنولوجيا الأحدث، كما أنّها أسهل في التفعيل وأقل تكلفة، ويمكنها التوسّع إلى 0 عندما لا تستخدمها. وبفضل مرونته في تشغيل أي حاوية عديمة الحالة وتكامله مع العديد من خدمات Google Cloud، يُعدّ هذا المنتج مثاليًا لنشر الخدمات المصغّرة والتطبيقات الحديثة بأقل تكلفة وأعلى كفاءة.

على وجه التحديد، ‫Cloud Run هي منصة مُدارة بالكامل من Google Cloud تتيح لك تشغيل تطبيقات لا يتم تسجيل بياناتها ضمن حاويات في بيئة بدون خادم. تتعامل تلقائيًا مع جميع البنى الأساسية، وتتوسّع من الصفر لتلبية عدد الزيارات الواردة وتنخفض عند عدم النشاط، ما يجعلها فعّالة من حيث التكلفة والأداء. تتيح Cloud Run استخدام أي لغة أو مكتبة طالما أنّها مضمّنة في حاوية، ما يوفّر مرونة كبيرة في عملية التطوير. تتكامل هذه الخدمة بشكل جيد مع خدمات Google Cloud الأخرى، وهي مناسبة لإنشاء الخدمات الدقيقة وواجهات برمجة التطبيقات والمواقع الإلكترونية والتطبيقات المستندة إلى الأحداث بدون الحاجة إلى إدارة البنية الأساسية للخادم.

المتطلبات الأساسية

لإكمال هذه المهمة، يجب أن يكون gcloud مثبّتًا على جهازك المحلي. إذا لم تظهر لك، اطّلِع على التعليمات هنا. بدلاً من ذلك، إذا كنت تستخدم Google Cloud Shell، ليس عليك اتّخاذ أي إجراء.

قبل نشر...

إذا كنت تعمل في بيئتك المحلية، عليك إثبات ملكيتك لحساب Google Cloud باستخدام ما يلي

  • $ gcloud auth login –update-adc # not needed in Cloud Shell

من المفترض أن تتم مصادقتك من خلال تسجيل الدخول إلى OAuth على المتصفّح. تأكَّد من تسجيل الدخول من خلال Chrome باستخدام المستخدم نفسه (مثل vattelapesca@gmail.com) الذي سجّل الدخول إلى Google Cloud مع تفعيل الفوترة.

فعِّل Cloud Run API باستخدام الأمر التالي:

  • $ gcloud services enable run.googleapis.com cloudbuild.googleapis.com

في هذه المرحلة، يكون كل شيء جاهزًا للنشر على Cloud Run.

نشر تطبيقك على Cloud Run من خلال gcloud

الأمر الذي يتيح لك نشر التطبيق على Cloud Run هو gcloud run deploy. تتوفّر عدّة خيارات يمكنك ضبطها لتحقيق هدفك. في ما يلي الحد الأدنى من الخيارات (التي يمكنك تقديمها عبر سطر الأوامر، أو سيطلب منك الأداة تقديمها من خلال طلب تفاعلي):

  1. اسم خدمة Cloud Run التي تريد نشرها لتطبيقك، إذ ستعرض لك خدمة Cloud Run عنوان URL يوفّر نقطة نهاية لتطبيقك.
  2. منطقة Google Cloud التي سيتم تشغيل تطبيقك فيها (--region المنطقة)
  3. صورة الحاوية التي تغلف تطبيقك
  4. متغيرات البيئة التي يحتاج تطبيقك إلى استخدامها أثناء تنفيذه
  5. علامة Allow-Unauthenticated التي تسمح للجميع بالوصول إلى تطبيقك بدون مصادقة إضافية

راجِع المستندات (أو انتقِل للأسفل للاطّلاع على حلّ محتمل) لمعرفة كيفية تطبيق هذا الخيار على سطر الأوامر.

ستستغرق عملية النشر بضع دقائق. إذا كانت كل المعلومات صحيحة، من المفترض أن يظهر لك ما يلي في Google Cloud Console.

ef1029fb62f8de81.png

f7191d579c21ca3e.png

انقر على عنوان URL الذي يوفّره Cloud Run واختبِر تطبيقك. بعد المصادقة، من المفترض أن يظهر لك ما يلي.

d571a90cd5a373f9.png

"gcloud run deploy" بدون وسيطات

ربما لاحظت أنّ gcloud run deploy يطرح عليك الأسئلة المناسبة ويملأ الفراغات التي تركتها. هذا مدهش.

ومع ذلك، سنضيف هذا الأمر إلى مشغّل Cloud Build في بعض الوحدات، لذا لا يمكننا طرح أسئلة تفاعلية. يجب ملء كل خيار في الأمر. لذا، عليك صياغة gcloud run deploy --option1 blah --foo bar --region your-fav-region الذهبية. كيف تنفّذ ذلك؟

  1. كرِّر الخطوات 2 و3 و4 إلى أن يتوقف gcloud عن طرح الأسئلة:
  2. [LOOP] gcloud run deploy مع الخيارات التي تم العثور عليها حتى الآن
  3. تطلب أنظمة [LOOP] الخيار X
  4. [LOOP] ابحث في المستندات المتاحة للجميع عن كيفية إعداد X من واجهة سطر الأوامر مع إضافة الخيار --my-option [my-value].
  5. ارجع إلى الخطوة 2 الآن، ما لم يكتمل gcloud بدون طرح المزيد من الأسئلة.
  6. هذا الأمر gcloud run deploy BLAH BLAH BLAH رائع! احفظ الأمر في مكان ما، ستحتاج إليه لاحقًا في خطوة Cloud Build.

يمكنك الاطّلاع على حلّ محتمل هنا. يمكنك الاطّلاع على المستندات هنا.

تهانينا 🎉🎉🎉 لقد تمكّنت من نشر تطبيقك على Google Cloud، وبذلك تكون قد أنجزت الخطوة الأولى من عملية التحديث.

6. الوحدة 4: كلمة المرور النظيفة باستخدام Secret Manager

95cd57b03b4e3c73.png

في الخطوة السابقة، تمكّنا من نشر تطبيقنا وتشغيله بنجاح في Cloud Run. ومع ذلك، نفّذنا ذلك باتّباع ممارسة سيئة للأمان: توفير بعض الأسرار بنص غير مرمّز.

التكرار الأول: تعديل ملف config.php لاستخدام ENV

ربما لاحظت أنّنا وضعنا كلمة مرور قاعدة البيانات مباشرةً في الرمز في ملف config.php. هذا الإجراء مناسب لأغراض الاختبار ومعرفة ما إذا كان التطبيق يعمل. ولكن لا يمكنك إرسال/استخدام الرمز البرمجي بهذه الطريقة في بيئة الإنتاج. يجب قراءة كلمة المرور (ومَعلمات اتصال قاعدة البيانات الأخرى) بشكل ديناميكي وتوفيرها للتطبيق في وقت التشغيل. غيِّر ملف config.php ليقرأ مَعلمات قاعدة البيانات من متغيّرات ENV. في حال تعذُّر ذلك، عليك ضبط القيم التلقائية. يفيد ذلك في حال تعذّر تحميل ENV، وبالتالي ستخبرك مخرجات الصفحة ما إذا كانت تستخدم القيم التلقائية. املأ الفراغات واستبدِل الرمز في ملف config.php.

<?php
// Database configuration with ENV variables. Set default values as well 
$db_host = getenv('DB_HOST') ?: 'localhost';
$db_name = getenv('DB_NAME') ?: 'image_catalog';
$db_user = getenv('DB_USER') ?: 'appmod-phpapp-user';
$db_pass = getenv('DB_PASS') ?: 'wrong_password';
// Note getenv() is PHP 5.3 compatible
try {
    $pdo = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die("Errore di connessione: " . $e->getMessage());
}

session_start();
?>

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

  • في وقت الإنشاء، في الملف الشامل أضِف المَعلمات الأربع إلى ملف Dockerfile السابق باستخدام البنية ENV DB_VAR=ENV_VAR_VALUE. سيؤدي ذلك إلى إعداد القيم التلقائية التي يمكن تجاهلها في وقت التشغيل. على سبيل المثال، يمكن ضبط "DB_NAME" و"DB_USER" هنا فقط.
  • في وقت التنفيذ يمكنك إعداد هذه المتغيّرات لخدمة Cloud Run، سواء من واجهة سطر الأوامر أو من واجهة المستخدم. هذا هو المكان المناسب لوضع جميع المتغيرات الأربعة (ما لم تكن تريد الاحتفاظ بالإعدادات التلقائية المحدّدة في Dockerfile).

في localhost، قد تحتاج إلى وضع متغيرات ENV في ملف .env (راجِع مجلد solutions).

تأكَّد أيضًا من إضافة ملف ‎.env إلى .gitignore، لأنّك لا تريد إرسال أسرارك إلى GitHub.

echo .env >> .gitignore

بعد ذلك، يمكنك اختبار النسخة على جهازك باتّباع الخطوات التالية:

docker run -it -p 8080:8080 --env-file .env my-php-app-docker

لقد حقّقت الآن ما يلي:

  1. سيقرأ تطبيقك المتغير ديناميكيًا من بيئة ENV
  2. لقد حسّنت الأمان لأنّك أزلت كلمة مرور قاعدة البيانات من الرمز البرمجي)

يمكنك الآن نشر مراجعة جديدة على Cloud Run. لننتقل إلى واجهة المستخدم ونضبط متغيرات البيئة يدويًا:

  • انتقِل إلى https://console.cloud.google.com/run
  • انقر على تطبيقك
  • انقر على "تعديل ونشر إصدار جديد".
  • في علامة التبويب الأولى "الحاويات"، انقر على علامة التبويب السفلية "المتغيّرات والأسرار".
  • انقر على "+ إضافة متغيّر" وأضِف جميع المتغيّرات المطلوبة. من المفترض أن يظهر لك ما يلي:

7a5fbfa448544d3.png

f2780c35585388ca.png

هل هذا مثالي؟ لا، سيظل بإمكان معظم المشغّلين رؤية بطاقة PASS. يمكن التخفيف من تأثير ذلك باستخدام Google Cloud Secret Manager.

التكرار الثاني: Secret Manager

اختفت كلمات المرور من الرمز الخاص بك: هذا يعني أنّك نجحت في إزالتها. ولكن مهلاً، هل نحن بأمان الآن؟

ستبقى كلمات المرور مرئية لأي مستخدم يمكنه الوصول إلى Google Cloud Console. في الواقع، إذا وصلت إلى ملف نشر YAML في Cloud Run، ستتمكّن من استرداده. أو إذا حاولت تعديل أو نشر إصدار جديد من Cloud Run، سيظهر رمز المرور في قسم "المتغيرات والأسرار" كما هو موضّح في لقطات الشاشة أدناه.

‫Google Cloud Secret Manager هي خدمة آمنة ومركزية لإدارة المعلومات الحسّاسة، مثل مفاتيح واجهة برمجة التطبيقات وكلمات المرور والشهادات وغيرها من الأسرار.

تتيح لك هذه الخدمة تخزين الأسرار وإدارتها والوصول إليها باستخدام أذونات دقيقة وتشفير قوي. تتيح لك خدمة Secret Manager، المتكاملة مع خدمة "إدارة الهوية وإمكانية الوصول" (IAM) في Google Cloud، التحكّم في المستخدمين الذين يمكنهم الوصول إلى أسرار معيّنة، ما يضمن أمان البيانات والامتثال التنظيمي.

تتيح هذه الخدمة أيضًا تدوير الأسرار وتحديد إصداراتها تلقائيًا، ما يسهّل إدارة مراحل نشاط الأسرار ويحسّن الأمان في التطبيقات على مستوى خدمات Google Cloud.

للوصول إلى Secret Manager، انتقِل من قائمة "الهامبرغر" إلى خدمات الأمان وابحث عنها ضمن قسم حماية البيانات كما هو موضّح في لقطة الشاشة أدناه.

6df83a1c3cb757f6.png

فعِّل Secret Manager API بعد الوصول إلى هناك وفقًا للصورة التالية.

a96c312e2c098db1.png

  • انقر الآن على إنشاء سرّ: لنسمِّه rationally:
  • الاسم: php-amarcord-db-pass
  • قيمة المفتاح السرّي: ‘your DB password' (تجاهل الجزء "تحميل ملف").
  • يجب أن يبدو الرابط السري على النحو التالي: projects/123456789012/secrets/php-amarcord-db-pass. هذا هو المؤشر الفريد إلى سرّك (بالنسبة إلى Terraform وCloud Run وغيرهما). هذا الرقم هو رقم مشروعك الفريد.

ملاحظة: حاوِل استخدام اصطلاحات تسمية متسقة للأسرار، مع التخصيص من اليمين إلى اليسار، على سبيل المثال: cloud-devrel-phpamarcord-dbpass

  • المؤسسة (التي تعمل فيها الشركة)
  • الفريق (داخل المؤسسة)
  • التطبيق (داخل الفريق)
  • اسم المتغيّر (داخل التطبيق)

سيتيح لك ذلك استخدام تعبيرات عادية بسيطة للعثور على جميع الأسرار لتطبيق واحد.

إنشاء إصدار جديد من Cloud Run

بعد إنشاء رمز سرّي جديد، علينا التخلّص من متغيّر بيئة DB_PASS واستبداله بالرمز السرّي الجديد. وبالتالي:

  • الوصول إلى Cloud Run باستخدام "وحدة تحكّم Google Cloud"
  • اختَر التطبيق.
  • انقر على "تعديل ونشر نسخة جديدة".
  • ابحث عن علامة التبويب "المتغيرات والمفاتيح السرية".
  • استخدِم الزر "+ الإشارة إلى سرّ" لإعادة ضبط المتغيّر DB_PASS ENV.
  • استخدِم "DB_PASS" نفسه في الأسرار المشار إليها واستخدِم أحدث إصدار.

9ed4e35be7654dcb.png

بعد الانتهاء، من المفترض أن يظهر لك الخطأ التالي

da0ccd7af39b04ed.png

حاوِل معرفة كيفية حلّ المشكلة. لحلّ هذه المشكلة، عليك الانتقال إلى قسم إدارة الهوية وإمكانية الوصول (IAM) والمشرف وتغيير أذونات المنح. نتمنّى لك تجربة ممتعة في تصحيح الأخطاء.

بعد تحديد المشكلة، ارجع إلى Cloud Run وأعِد نشر مراجعة جديدة. يجب أن تبدو النتيجة كما في الشكل التالي:

e89f9ca780169b6b.png

ملاحظة: إنّ Developer Console (واجهة المستخدم) رائعة في الإشارة إلى مشاكل الأذونات. يجب تخصيص بعض الوقت لاستعراض جميع الروابط الخاصة بكيانات السحابة الإلكترونية.

7. الوحدة 5: إعداد عملية التكامل المستمر/التسليم المستمر باستخدام Cloud Build

ba49b033c11be94c.png

لماذا يجب استخدام مسار CI/CD؟

من المفترض أنّك كتبت gcloud run deploy عدة مرات حتى الآن، وربما أجبت عن السؤال نفسه مرارًا وتكرارًا.

هل سئمت من نشر تطبيقك يدويًا باستخدام gcloud run deploy؟ ألن يكون من الرائع أن يتمكّن تطبيقك من نشر نفسه تلقائيًا في كل مرة تدفع فيها تغييرًا جديدًا إلى مستودع Git؟

لاستخدام مسار CI/CD، ستحتاج إلى ما يلي:

  1. مستودع Git شخصي: من المفترض أنّك أنشأت نسخة من مستودع ورشة العمل في حسابك على GitHub في الخطوة 2. إذا لم يكن كذلك، فارجع وأكمل هذه الخطوة. يجب أن يبدو المستودع المتفرّع على النحو التالي: https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
  2. Cloud Build تتيح لك هذه الخدمة الرائعة والرخيصة ضبط عمليات إنشاء تلقائية لكل شيء تقريبًا: Terraform، والتطبيقات التي تعمل بنظام التشغيل Docker، وما إلى ذلك.

سيركّز هذا القسم على إعداد Cloud Build.

إليك Cloud Build

سنستخدم Cloud Build لتنفيذ ذلك:

  • إنشاء المصدر (باستخدام Dockerfile) يمكنك اعتبار ذلك "ملف zip كبير" يحتوي على كل ما تحتاج إليه لإنشائه وتشغيله (وهو "عنصر الإنشاء").
  • دفع هذا العنصر إلى Artifact Registry (AR).
  • بعد ذلك، نفِّذ عملية نشر من AR إلى Cloud Run للتطبيق "php-amarcord".
  • سيؤدي ذلك إلى إنشاء إصدار جديد ("مراجعة") من التطبيق الحالي (فكِّر في طبقة تحتوي على الرمز الجديد)، وسنضبطه لتوجيه الزيارات إلى الإصدار الجديد في حال نجاح عملية الدفع.

في ما يلي مثال على بعض الإصدارات لتطبيق php-amarcord:

f30f42d4571ad5e2.png

كيف يمكننا تنفيذ كل ذلك؟

  1. من خلال إنشاء ملف YAML مثالي واحد: cloudbuild.yaml
  2. من خلال إنشاء مشغّل Cloud Build
  3. من خلال الاتصال بمستودع github عبر واجهة مستخدم Cloud Build

إنشاء مشغّل (وربط المستودع)

  • انتقِل إلى https://console.cloud.google.com/cloud-build/triggers
  • انقر على "إنشاء عبارة تشغيل".
  • تجميع:
  • الاسم: اسم ذو دلالة مثل on-git-commit-build-php-app
  • الحدث: Push to branch
  • المصدر: "ربط مستودع جديد" النص البديل
  • سيؤدي ذلك إلى فتح نافذة على اليسار: "ربط المستودع"
  • موفّر المصدر: "Github" (الأول)
  • متابعة ("Continue")
  • سيؤدي النقر على "المصادقة" إلى فتح نافذة على GitHub لإجراء المصادقة المتبادلة. اتّبِع الخطوات وتحلَّ بالصبر. إذا كان لديك العديد من المستودعات، قد يستغرق الأمر بعض الوقت.
  • "اختيار المستودع" (Select repo): اختَر حسابك/مستودعك وضع علامة في المربّع بجانب "أتفهّم..." (I understand...).
  • إذا ظهرت لك رسالة الخطأ: لم يتم تثبيت تطبيق GitHub على أي من مستودعاتك، انقر على "تثبيت Google Cloud Build" واتّبِع التعليمات.
  • 23e0e0f1219afea3.pngانقر على "ربط"
  • bafd904ec07122d2.png
  • Bingo! تم الآن ربط المستودع.
  • الرجوع إلى جزء "المشغّل"...
  • الإعداد: تم الرصد التلقائي (*)
  • إعداد متقدّم: اختَر حساب الخدمة "[PROJECT_NUMBER]- compute@developer.gserviceaccount.com".
  • xxxx هو رقم تعريف مشروعك
  • حساب الخدمة التلقائي للخدمات الحسابية مناسب لتجربة معملية، ولكن لا تستخدمه في بيئة الإنتاج. ( مزيد من المعلومات).
  • اترك كل شيء آخر كما هو.
  • انقر على الزر "إنشاء".

(*) هذه هي أبسط طريقة لأنّها تتحقّق من Dockerfile أو cloudbuild.yaml. ومع ذلك، يمنحك cloudbuild.yaml القدرة الحقيقية على تحديد الإجراء الذي يجب اتخاذه في كل خطوة.

أنا الأقوى!

الآن، لن يتم تشغيل المشغّل إلا إذا منحت حساب خدمة Cloud Build (ما هو حساب الخدمة؟ عنوان البريد الإلكتروني الخاص بـ "برنامج" ينفّذ مهمة نيابةً عنك، وفي هذه الحالة، ينشئ عناصر في السحابة الإلكترونية.

لن يتمكّن مهندس الحلول من إنشاء التطبيق ونشره إلا إذا منحته الإذن بذلك. لحسن الحظ، الأمر سهل.

  • انتقِل إلى "Cloud Build" > " الإعدادات".
  • حساب الخدمة "[PROJECT_NUMBER]- compute@developer.gserviceaccount.com"
  • ضَع علامة في المربّعات التالية:
  • Cloud Run
  • Secret Manager
  • حسابات الخدمة
  • Cloud Build
  • ضَع أيضًا علامة في المربّع "ضبطه كحساب خدمة مفضّل".

8715acca72286a46.png

أين يمكنني العثور على ملف YAML الخاص بخدمة Cloud Build؟

ننصحك بشدة بتخصيص بعض الوقت لإنشاء ملف YAML خاص بك على السحابة الإلكترونية.

ومع ذلك، إذا لم يكن لديك وقت أو لم تكن تريد تخصيص وقت لذلك، يمكنك الحصول على بعض الأفكار في مجلد الحلول هذا: .solutions

يمكنك الآن إرسال تغيير إلى GitHub ومراقبة Cloud Build أثناء تنفيذ دوره.

قد يكون إعداد Cloud Build أمرًا صعبًا. من المتوقّع أن نتواصل معك عدة مرات بحلول:

  • التحقّق من السجلات في https://console.cloud.google.com/cloud-build/builds;region=global
  • العثور على الخطأ
  • إصلاح الخطأ في الرمز وإعادة إصدار git commit / git push
  • في بعض الأحيان، لا يكون الخطأ في الرمز، بل في بعض الإعدادات. في هذه الحالة، يمكنك إصدار إصدار جديد من واجهة المستخدم (الإصدار السحابي > "المشغّلات" > "تشغيل").

97acd16980a144ab.png

يُرجى العِلم أنّه في حال استخدام هذا الحلّ، لا يزال عليك تنفيذ بعض المهام، مثل ضبط متغيّرات ENV لنقاط النهاية الجديدة الخاصة ببيئة التطوير/الإنتاج:

3da8723e4ff80c0a.png

هناك طريقتان لإجراء ذلك:

  • من خلال واجهة المستخدم: عن طريق ضبط متغيرات ENV مرة أخرى
  • من خلال CLI عن طريق إنشاء النص البرمجي "المثالي" لك يمكنك الاطّلاع على مثال هنا: gcloud-run-deploy.sh . عليك تعديل بعض الإعدادات، مثل نقطة النهاية ورقم المشروع. يمكنك العثور على رقم مشروعك في نظرة عامة على Cloud.

كيف يمكنني إرسال الرمز إلى GitHub؟

لا تتناول ورشة العمل هذه أفضل طريقة git push إلى GitHub. ومع ذلك، في حال واجهت مشكلة وكنت تستخدم Cloud Shell، يمكنك اتّباع إحدى الطريقتَين التاليتَين:

  1. CLI أضِف مفتاح ssh محليًا وأضِف جهازًا تحكّمًا عن بُعد باستخدام git@github.com:YOUR_USER/app-mod-workshop.git (بدلاً من http)
  2. VSCode إذا كنت تستخدم محرّر Cloud Shell، يمكنك استخدام علامة التبويب "التحكّم بالمصدر" (ctrl-shift-G)، والنقر على "مزامنة التغييرات" واتّباع التعليمات. يجب أن تتمكّن من مصادقة حسابك على GitHub في VS Code، وسيصبح سحب البيانات ودفعها أمرًا سهلاً.

f0d53f839c7fa3b6.png

تذكَّر git add clodubuild.yaml بين الملفات الأخرى، وإلا لن ينجح ذلك.

المقارنة بين "التطوير/الإنتاج" المتعمّق والسطحي [اختياري]

إذا نسخت إصدار النموذج من هنا، سيكون لديك إصداران متطابقان من DEV وPROD. هذا أمر رائع ويتوافق مع القاعدة 10 من قواعد التطبيقات ذات العوامل الاثني عشر.

ومع ذلك، نحن نستخدم نقطتَي نهاية مختلفتَين على الويب لربط تطبيق بقاعدة البيانات نفسها. هذا الإعداد مناسب لورشة عمل، ولكن في الواقع، عليك تخصيص بعض الوقت لإنشاء بيئة إنتاج مناسبة. وهذا يعني توفير قاعدتَي بيانات (واحدة للتطوير وأخرى للإنتاج) واختيار مكان استضافتهما لاستعادة البيانات عند حدوث كوارث أو ضمان توفّر الخدمة. هذا الموضوع خارج نطاق ورشة العمل هذه، ولكنّه يستحق التفكير فيه.

إذا كان لديك الوقت لإنشاء نسخة "مفصّلة" من الإنتاج، يُرجى مراعاة جميع المراجع التي تحتاج إلى تكرارها، مثل:

  • قاعدة بيانات Cloud SQL (وربما مثيل SQL)
  • حزمة GCS
  • دالة Cloud
  • يمكنك استخدام Gemini 1.5 Flash كنموذج في مرحلة التطوير (أرخص وأسرع)، وGemini 1.5 Pro (أكثر فعالية).

بشكل عام، في كل مرة تفعل فيها شيئًا بشأن التطبيق، فكِّر بشكل نقدي: هل يجب أن يكون للإنتاج هذه القيمة نفسها أم لا؟ وإذا لم يكن كذلك، كرِّر جهودك. بالطبع، يصبح هذا الإجراء أسهل بكثير باستخدام Terraform، حيث يمكنك إدخال بيئتك (-dev أو -prod) كلاحقة لمواردك.

8. الوحدة 6: الانتقال إلى Google Cloud Storage

a680e0f287dd2dfb.png

مساحة التخزين

dc3a4b8ea92aaef6.png

في الوقت الحالي، يخزّن التطبيق الحالة في حاوية Docker. إذا تعطلت الآلة أو حدث خطأ في التطبيق أو إذا دفعت بمراجعة جديدة، ستتم جدولة مراجعة جديدة مع مساحة تخزين فارغة جديدة: 🙈

كيف يمكننا حلّ هذه المشكلة؟ هناك عدد من الطرق.

  1. تخزين الصور في قاعدة البيانات هذا ما فعلته مع تطبيق PHP السابق، وهو الحل الأبسط لأنّه لا يضيف أي تعقيد. ولكنّها ستضيف بالتأكيد وقت استجابة وحِملًا إلى قاعدة البيانات.
  2. نقل تطبيق Cloud Run إلى حلّ متوافق مع التخزين: GCE + قرص ثابت؟ ربما GKE + Storage؟ ملاحظة: كلما زادت سيطرتك على عملية التحديث، قلّت سرعة تنفيذها.
  3. انتقِل إلى GCS. تقدّم خدمة Google Cloud Storage أفضل مساحة تخزين في Google Cloud، وهي الحلّ الأكثر ملاءمةً للسحابة الإلكترونية. ومع ذلك، يتطلّب ذلك استخدام مكتبات PHP. هل لدينا مكتبات PHP 5.7 لخدمة GCS؟ هل تتوافق PHP 5.7 مع Composer (يبدو أنّ PHP 5.3.2 هو أقدم إصدار يتوافق مع Composer)؟
  4. ربما يمكنك استخدام حاوية جانبية في Docker؟
  5. أو يمكنك استخدام عمليات ربط وحدات التخزين في Cloud Run من GCS. يبدو هذا رائعًا.

🤔 نقل بيانات مساحة التخزين (سؤال مفتوح)

[Open Ended] في هذا التمرين، نريد منك إيجاد حلّ لنقل صورك بطريقة يتم الاحتفاظ بها بطريقة ما.

اختبار القبول

لا أريد أن أخبرك بالحل، ولكن أريد أن يحدث ما يلي:

  1. تحميل newpic.jpg سيظهر لك في التطبيق.
  2. ترقية التطبيق إلى إصدار جديد
  3. لا يزال newpic.jpg متاحًا ومرئيًا.

💡 الحلّ المحتمل (عمليات ربط وحدات التخزين في GCS Cloud Run)

هذا حلّ أنيق جدًا يتيح لنا تحقيق عمليات تحميل ملفات ذات حالة بدون تعديل الرمز البرمجي على الإطلاق (باستثناء عرض وصف الصورة، ولكن هذا أمر بسيط ويهدف فقط إلى إرضاء العين).

من المفترض أن يتيح لك ذلك ربط مجلد من Cloud Run بحزمة GCS، لذا:

  1. ستظهر كل عمليات التحميل إلى GCS في تطبيقك.
  2. سيتم تحميل جميع عمليات التحميل إلى تطبيقك على GCS
  3. سيحدث السحر في الكائنات التي تم تحميلها في GCS (الفصل 7).

ملاحظة يُرجى قراءة التفاصيل والأحكام المتعلقة ببرنامج FUSE. لا يُنصح بذلك إذا كان الأداء يمثّل مشكلة.

إنشاء حزمة GCS

‫Google Cloud Storage هي خدمة التخزين الشاملة في Google Cloud. تم اختبارها في ظروف قاسية، وتستخدمها كل خدمة من خدمات GCP التي تحتاج إلى مساحة تخزين.

يُرجى العِلم أنّ Cloud Shell يصدّر PROJECT_ID كـ GOOGLE_CLOUD_PROJECT:

$ export PROJECT_ID=$GOOGLE_CLOUD_PROJECT

#!/bin/bash

set -euo pipefail

# Your Cloud Run Service Name, eg php-amarcord-dev
SERVICE_NAME='php-amarcord-dev'
BUCKET="${PROJECT_ID}-public-images"
GS_BUCKET="gs://${BUCKET}"

# Create bucket
gsutil mb -l "$GCP_REGION" -p "$PROJECT_ID" "$GS_BUCKET/"

# Copy original pictures there - better if you add an image of YOURS before.
gsutil cp ./uploads/*.png "$GS_BUCKET/"

ضبط Cloud Run لتركيب الحزمة في المجلد /uploads/ ‎

لننتقل الآن إلى الجزء الأنيق. ننشئ وحدة تخزين php_uploads ونطلب من Cloud Run إجراء عملية ربط FUSE على MOUNT_PATH (مثل /var/www/html/uploads/):

#!/bin/bash

set -euo pipefail

# .. keep variables from previous script..

# Uploads folder within your docker container.
# Tweak it for your app code.
MOUNT_PATH='/var/www/html/uploads/'

# Inject a volume mount to your GCS bucket in the right folder.
gcloud --project "$PROJECT_ID" beta run services update "$SERVICE_NAME" \
    --region $GCP_REGION \
    --execution-environment gen2 \
    --add-volume=name=php_uploads,type=cloud-storage,bucket="$BUCKET"  \
    --add-volume-mount=volume=php_uploads,mount-path="$MOUNT_PATH"

كرِّر هذه الخطوة الآن لجميع نقاط النهاية التي تريد توجيهها إلى Cloud Storage.

يمكنك أيضًا تحقيق ذلك من واجهة المستخدم

  1. ضمن علامة التبويب "وحدات التخزين"، أنشئ عمليات ربط وحدات التخزين التي تشير إلى حزمتك، من النوع "حزمة Cloud Storage"، مثلاً بالاسم "php_uploads".
  2. ضمن "الحاويات" (Container(s)) > "وحدات تخزين مثبّتة" (Volume Mounts)، ثبِّت وحدة التخزين التي أنشأتها للتو على نقطة وحدة التخزين التي طلبها تطبيقك. يعتمد ذلك على ملف Dockerfile، ولكن قد يبدو على النحو التالي: var/www/html/uploads/ .

في كلتا الحالتين، إذا نجحت العملية، من المفترض أن يظهر لك ما يلي عند تعديل المراجعة الجديدة في Cloud Run:

6c2bb98fc1b0e077.png

اختبِر الآن التطبيق الجديد من خلال تحميل صورة جديدة واحدة إلى نقطة النهاية /upload.php.

يجب أن تتدفق الصور بسلاسة على "خدمة التخزين السحابي من Google" بدون كتابة سطر واحد من PHP:

70032b216afee2d7.png

ما الذي حدث للتو؟

حدث شيء سحري للغاية.

لا يزال تطبيق قديم يتضمّن رمزًا قديمًا يؤدي وظيفته. تتيح لنا حزمة جديدة ومحدّثة أن نحفظ جميع الصور في تطبيقنا بسهولة في حزمة Cloud Bucket ذات الحالة. أصبح بإمكانك الآن تحقيق ما يلي:

  • هل تريد تلقّي رسالة إلكترونية في كل مرة تصلك فيها صورة تتضمّن محتوًى "خطيرًا" أو "عُريًا"؟ يمكنك إجراء ذلك بدون تعديل رمز PHP.
  • هل تريد استخدام نموذج Gemini المتعدّد الوسائط في كل مرة تصلك فيها صورة لوصفها وتحميل قاعدة البيانات مع وصفها؟ يمكنك إجراء ذلك بدون تعديل رمز PHP. ألا تصدقني؟ يمكنك مواصلة القراءة في الفصل 7.

لقد فتحنا للتو مساحة كبيرة من الفرص هنا.

9- الوحدة 7: تعزيز إمكانات تطبيقك باستخدام Google Gemini

c00425f0ad83b32c.png

أصبح لديك الآن تطبيق PHP جديد ومحدّث ورائع (مثل Fiat 126 لعام 2024) مع مساحة تخزين مستندة إلى السحابة الإلكترونية.

ما استخداماته؟

المتطلبات الأساسية

في الفصل السابق، أتاح لنا حلّ نموذجي تحميل الصور /uploads/ على GCS، ما أدّى إلى الفصل بحكم الواقع بين منطق التطبيق وتخزين الصور.

يتطلّب هذا التمرين ما يلي:

  • أكملت التمرين في الفصل 6 (التخزين) بنجاح.
  • أن يكون لديك حزمة GCS تتضمّن عمليات تحميل الصور، حيث يحمّل المستخدمون الصور على تطبيقك وتنتقل الصور إلى حزمتك.

إعداد دالة Cloud (بلغة Python)

هل تساءلت يومًا عن كيفية تنفيذ تطبيق يستند إلى الأحداث؟ على سبيل المثال:

  • عند حدوث <event> => إرسال رسالة إلكترونية
  • عندما يحدث <event> => إذا كانت <condition> صحيحة، عدِّل قاعدة البيانات.

يمكن أن يكون الحدث أي شيء، بدءًا من سجلّ جديد متاح في BigQuery، أو كائن جديد تم تغييره في مجلد في GCS، أو رسالة جديدة تنتظر في قائمة الانتظار في Pub/Sub.

تتيح Google Cloud نماذج متعددة لتحقيق ذلك. أبرزها:

  • EventArc تعرَّف على كيفية تلقّي أحداث GCS. إنّها رائعة لإنشاء الرسوم البيانية الموجّهة غير الدورية (DAG) وتنظيم الإجراءات استنادًا إلى عبارات if-then-else في السحابة الإلكترونية.
  • Cloud Scheduler وهي رائعة لتنفيذ مهمة cron في منتصف الليل في السحابة الإلكترونية، على سبيل المثال.
  • Cloud Workflows على غرار Event Arc، تتيح لك هذه الخدمة
  • دوال Cloud Run (المعروفة باسم lambdas)
  • ‫Cloud Composer: هي في الأساس إصدار Google من Apache Airflow، وهي رائعة أيضًا DAG.

في هذا التمرين، سنتعمّق في Cloud Function لتحقيق نتيجة رائعة. وسنقدّم لك تمارين اختيارية.

يُرجى العِلم أنّ الرمز النموذجي متوفّر بموجب .solutions/

إعداد دالة Cloud (🐍 Python)

نحاول إنشاء إطار عمل GCF طموح للغاية.

  1. عند إنشاء صورة جديدة على GCS.. (ربما لأنّ أحد المستخدمين حمّله على التطبيق، ولكن ليس فقط)
  2. .. الاتصال بـ Gemini لوصف الصورة والحصول على وصف نصي لها .. (من المفيد التحقّق من نوع MIME والتأكّد من أنّ الملف هو صورة وليس ملف PDF أو MP3 أو ملف نصي)
  3. .. وتعديل قاعدة البيانات بهذا الوصف (قد يتطلّب ذلك تعديل قاعدة البيانات لإضافة عمود description إلى جدول images).

تعديل قاعدة البيانات لإضافة description إلى الصور

  1. افتح Cloud SQL Studio:

b92b07c4cba658ef.png

  1. أدخِل اسم المستخدم وكلمة المرور لقاعدة بيانات الصور.
  2. أدخِل عبارة SQL التالية التي تضيف عمودًا لوصف الصورة:

ALTER TABLE images ADD COLUMN description TEXT;

3691aced78a6389.png

وهكذا! جرِّب الآن التحقّق مما إذا نجحت العملية:

SELECT * FROM images;

يجب أن يظهر عمود الوصف الجديد على النحو التالي:

bed69d6ad0263114.png

اكتب Gemini f(x)

ملاحظة تم إنشاء هذه الدالة بمساعدة Gemini Code Assist.

ملاحظة عند إنشاء هذه الدالة، قد تواجه أخطاء في أذونات "إدارة الهوية وإمكانية الوصول". بعضها موضّح أدناه في الفقرة "الأخطاء المحتملة".

  1. تفعيل واجهات برمجة التطبيقات
  2. انتقِل إلى https://console.cloud.google.com/functions/list
  3. انقر على "إنشاء دالة".
  4. تفعيل واجهات برمجة التطبيقات من معالج واجهة برمجة التطبيقات:

d22b82658cfd4c48.png

يمكنك إنشاء GCF من واجهة المستخدم أو من سطر الأوامر. سنستخدم هنا سطر الأوامر.

يمكن العثور على رمز محتمل ضمن .solutions/

  1. أنشئ مجلدًا لاستضافة الرمز، مثل "gcf/". انتقِل إلى المجلد.
  2. إنشاء ملف requirements.txt:
google-cloud-storage
google-cloud-aiplatform
pymysql
  1. أنشئ دالة Python. نموذج الرمز البرمجي هنا: gcf/main.py.
#!/usr/bin/env python

"""Complete this"""

from google.cloud import storage
from google.cloud import aiplatform
import vertexai
from vertexai.generative_models import GenerativeModel, Part
import os
import pymysql
import pymysql.cursors

# Replace with your project ID
PROJECT_ID = "your-project-id"
GEMINI_MODEL = "gemini-1.5-pro-002"
DEFAULT_PROMPT = "Generate a caption for this image: "

def gemini_describe_image_from_gcs(gcs_url, image_prompt=DEFAULT_PROMPT):
    pass

def update_db_with_description(image_filename, caption, db_user, db_pass, db_host, db_name):
    pass

def generate_caption(event, context):
    """
    Cloud Function triggered by a GCS event.
    Args:
        event (dict): The dictionary with data specific to this type of event.
        context (google.cloud.functions.Context): The context parameter contains
                                                event metadata such as event ID
                                                and timestamp.
    """
    pass
  1. اضغط على الدالة. يمكنك استخدام نص برمجي مشابه لما يلي: gcf/push-to-gcf.sh.

ملاحظة 1. احرص على توفير قيم صحيحة لمتغيرات البيئة، أو يمكنك إضافتها في الأعلى (GS_BUCKET=blah، وما إلى ذلك):

ملاحظة 2: سيؤدي هذا الإجراء إلى إرسال كل الرموز المحلية (.)، لذا احرص على وضع الرمز في مجلد معيّن واستخدام .gcloudignore بشكل احترافي لتجنُّب إرسال مكتبات كبيرة. ( مثال).

#!/bin/bash

set -euo pipefail

# add your logic here, for instance:
source .env || exit 2 

echo "Pushing ☁️ f(x)☁ to 🪣 $GS_BUCKET, along with DB config.. (DB_PASS=$DB_PASS)"

gcloud --project "$PROJECT_ID" functions deploy php_amarcord_generate_caption \
    --runtime python310 \
    --region "$GCP_REGION" \
    --trigger-event google.cloud.storage.object.v1.finalized \
    --trigger-resource "$BUCKET" \
    --set-env-vars "DB_HOST=$DB_HOST,DB_NAME=$DB_NAME,DB_PASS=$DB_PASS,DB_USER=$DB_USER" \
    --source . \
    --entry-point generate_caption \
    --gen2

ملاحظة: في هذا المثال، ستكون generate_caption هي الطريقة التي تم استدعاؤها، وستمرّر "دالة Cloud" حدث GCS إليها مع جميع المعلومات ذات الصلة (اسم الحزمة واسم العنصر وما إلى ذلك). لذا، خذ بعض الوقت لتصحيح أخطاء قاموس Python الخاص بهذا الحدث.

اختبار الدالة

اختبارات الوحدات

تتضمّن الدالة العديد من الأجزاء المتحركة. قد تحتاج إلى اختبار جميع الأجهزة الفردية.

يمكنك الاطّلاع على مثال في gcf/test.py.

واجهة مستخدم Cloud Functions

خصِّص بعض الوقت أيضًا لاستكشاف وظيفتك في واجهة المستخدِم. ننصحك باستكشاف كل علامة تبويب، لا سيما Source (المفضّلة لديّ) وVariables وTrigger وLogs، إذ ستقضي وقتًا طويلاً في Logs لتحديد المشاكل وحلّها (يمكنك أيضًا الاطّلاع على الأخطاء المحتملة في أسفل هذه الصفحة). احرص أيضًا على مراجعة Permissions.

cf3ded30d532a2c7.png

اختبار شامل

حان الوقت لاختبار الدالة يدويًا.

  1. انتقِل إلى تطبيقك وسجِّل الدخول
  2. حمِّل صورة (يجب ألا يكون حجمها كبيرًا جدًا، فقد واجهنا مشاكل مع الصور الكبيرة)
  3. تحقَّق من تحميل الصورة في واجهة المستخدم.
  4. تأكَّد من تعديل الوصف في Cloud SQL Studio. سجِّل الدخول ونفِّذ طلب البحث هذا: SELECT * FROM images.

43a680b12dbbdda0.png

وهي فعّالة. قد نريد أيضًا تعديل الواجهة الأمامية لعرض هذا الوصف.

تعديل PHP لعرض [اختياري]

لقد أثبتنا أنّ التطبيق يعمل. ومع ذلك، سيكون من الجيد أن يتمكّن المستخدمون أيضًا من رؤية هذا الوصف.

لا نحتاج إلى أن نكون خبراء في PHP لإضافة الوصف إلى index.php. من المفترض أن ينفّذ هذا الرمز الإجراءات التالية (نعم، لقد كتبه Gemini أيضًا):

<?php if (!empty($image['description'])): ?>
    <p class="font-bold">Gemini Caption:</p>
    <p class="italic"><?php echo $image['description']; ?></p>
<?php endif; ?>

يمكنك وضع هذا الرمز داخل foreach حسب ذوقك.

في الخطوات التالية، نرى أيضًا إصدارًا أكثر جاذبية من واجهة المستخدم، وذلك بفضل Gemini Code Assist. قد تبدو النسخة الجميلة على النحو التالي:

fdc12de0c88c4464.png

الاستنتاجات

لقد حصلت على دالة Cloud Function تم تشغيلها عند وصول عناصر جديدة إلى GCS، وهي قادرة على إضافة تعليقات توضيحية إلى محتوى الصورة كما يفعل الإنسان، وتعديل قاعدة البيانات تلقائيًا. رائع!

ما هي الخطوات التالية؟ يمكنك اتّباع الأسلوب نفسه لتحقيق وظيفتَين رائعتَين.

[اختياري] إضافة المزيد من دوال Cloud Functions [مفتوح]

تتبادر إلى الذهن بعض الميزات الإضافية.

📩 مشغّل البريد الإلكتروني

مشغّل البريد الإلكتروني الذي يرسل إليك رسالة إلكترونية في كل مرة يرسل فيها مستخدم صورة

  • مرات كثيرة جدًا؟ أضِف قيدًا آخر: صورة كبيرة أو صورة يتضمّن محتواها على Gemini الكلمات "عُري/عُري/عنيف".
  • ننصحك بالتحقّق من EventArc لمعرفة ذلك.

🚫 الإشراف التلقائي على الصور غير الملائمة

في الوقت الحالي، يبلغ مشرف عن الصور التي تم تصنيفها على أنّها "غير ملائمة". ما رأيك في أن يتولّى Gemini المهام الصعبة والإشراف على المساحة؟ أضِف اختبارًا للإبلاغ عن المحتوى غير الملائم الذي يؤدي إلى تشغيل الإجراء، وعدِّل قاعدة البيانات كما تعلّمنا في الدالة السابقة. يعني ذلك بشكل أساسي أخذ الدالة السابقة وتغيير الطلب وتعديل قاعدة البيانات استنادًا إلى الإجابة.

ملاحظة يقدّم الذكاء الاصطناعي التوليدي نتائج لا يمكن التنبؤ بها. يجب التأكّد من أنّ "الناتج الإبداعي" من Gemini يتم وضعه "في مساره الصحيح". يمكنك طلب إجابة قطعية، مثل درجة ثقة من 0 إلى 1 أو ملف JSON أو غير ذلك. ويمكنك تحقيق ذلك بعدة طرق، مثلاً: * استخدام مكتبات Python pydantic وlangchain وغير ذلك * استخدام الناتج المنظَّم من Gemini

ملاحظة: يمكنك استخدام عدة دوال أو طلب واحد يفرض إجابة بتنسيق JSON (يعمل بشكل رائع مع "الناتج المنظَّم من Gemini" كما هو موضّح أعلاه)، مثل:

ما هو الطلب الذي يجب تقديمه لإنشاء هذا المحتوى؟

{
    "description": "This is the picture of an arrosticino",
    "suitable": TRUE
}

يمكنك إضافة حقول إضافية في الطلب للحصول على إحصاءات مثل: هل هناك أي شيء جيد في هذا المنتج؟ هل هناك أي سلبيات؟ هل تعرف هذا المكان؟ هل هناك بعض النصوص (أصبحت تقنية التعرّف البصري على الأحرف أسهل من أي وقت مضى):

  • goods: "يبدو الطعام شهيًا"
  • bads: "يبدو أنّها أطعمة غير صحية"
  • OCR: "Da consumare preferibilmente prima del 10 Novembre 2024"
  • location: "Pescara, Lungomare"

على الرغم من أنّه من الأفضل عادةً أن يكون لديك دالة N لنتائج N، إلا أنّه من المفيد جدًا أن يكون لديك دالة واحدة تؤدي 10 مهام. يمكنك الاطّلاع على هذه المقالة التي كتبها ريكاردو لمعرفة كيفية إجراء ذلك.

الأخطاء المحتملة (معظمها متعلقة بإدارة الهوية وإمكانية الوصول / الأذونات)

عندما بدأت بتطوير هذا الحل، واجهت بعض المشاكل المتعلّقة بأذونات إدارة الهوية وإمكانية الوصول (IAM). سأضيفها هنا للتعاطف مع المستخدمين وتقديم بعض الأفكار حول كيفية حلّها.

خطأ: ليس لديك أذونات كافية لحساب الخدمة

  1. يُرجى العِلم أنّه لتفعيل وظيفة GCF تستمع إلى حزمة GCS، عليك إعداد الأذونات المناسبة لحساب الخدمة الذي تستخدمه في المهمة، كما هو موضّح في الشكل:

22f51012fa6b4a24.png

قد تحتاج أيضًا إلى تفعيل واجهات برمجة تطبيقات EventArc قبل بضع دقائق من إتاحتها بالكامل.

خطأ: لم يتم العثور على برنامج استدعاء Cloud Run

  1. تعليق آخر من واجهة المستخدم بشأن أذونات "وظائف السحابة الإلكترونية" هو هذا ( دور المشغّل في Cloud Run):

be72e17294f2d3f3.png

يمكن إصلاح هذا الخطأ من خلال تنفيذ الأمر في الصورة، وهو يشبه fix-permissions.sh.

يمكنك الاطّلاع على وصف لهذه المشكلة هنا: https://cloud.google.com/functions/docs/securing/authenticating

خطأ: تم تجاوز الحدّ الأقصى للذاكرة

في المرة الأولى التي شغّلت فيها هذا التطبيق، قد تظهر في السجلات الرسالة التالية: "تم تجاوز الحدّ الأقصى للذاكرة البالغ 244 ميغابايت، وتم استخدام 270 ميغابايت". ننصحك بزيادة الحدّ الأقصى للذاكرة، يمكنك الاطّلاع على https://cloud.google.com/functions/docs/configuring/memory". أضِف ذاكرة وصول عشوائي (RAM) إلى GCF مرة أخرى. يمكن إجراء ذلك بسهولة بالغة في واجهة المستخدم. إليك أحد الأسباب المحتملة:

bed69d6ad0263114.png

بدلاً من ذلك، يمكنك أيضًا إصلاح نص برمجي لنشر Cloud Run لزيادة MEM/CPU. يستغرق ذلك وقتًا أطول قليلاً.

خطأ: تم نشر PubSub

حدث الخطأ التالي مرة واحدة عند إنشاء مشغّل باستخدام الإصدار 1 من "وظائف السحابة الإلكترونية من Google":

e5c338ee35ad4c24.png

يمكنك حلّ هذه المشكلة بسهولة من خلال الانتقال إلى إدارة الهوية وإمكانية الوصول ومنح حساب الخدمة دور "ناشر Pub/Sub".

خطأ: لم يتم استخدام Vertex AI

إذا ظهرت لك رسالة الخطأ هذه:

Permission Denied: 403 لم يتم استخدام Vertex AI API في المشروع YOUR_PROJECT من قبل أو أنّها غير مفعّلة. يمكنك تفعيلها من خلال الانتقال إلى https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT

ما عليك سوى تفعيل واجهات برمجة التطبيقات في Vertex AI. أسهل طريقة لتفعيل جميع واجهات برمجة التطبيقات المطلوبة هي:

  1. https://console.cloud.google.com/vertex-ai
  2. انقر على "تفعيل جميع واجهات برمجة التطبيقات المقترَحة".

492f05ac377f3630.png

خطأ: لم يتم العثور على مشغّل EventArc.

في حال ظهور هذه الرسالة، يُرجى إعادة نشر الدالة.

8ec4fc11833d7420.png

الخطأ: 400 يتم توفير موظفي دعم الخدمة

يتم توفير 400 من وكلاء الخدمة ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents ). هناك حاجة إلى وكلاء الخدمة لقراءة ملف Cloud Storage المقدَّم. لذا يُرجى إعادة المحاولة بعد بضع دقائق.

في حال حدوث ذلك، انتظِر بعض الوقت أو اطلب المساعدة من أحد موظفي Google.

10. الوحدة 8: إنشاء مؤشرات SLO لمدى التوفّر

في هذا الفصل، نحاول تحقيق ما يلي:

  1. إنشاء مؤشرات مستوى الخدمة
  2. إنشاء أهداف SLO استنادًا إلى مؤشرات SLI
  3. إنشاء تنبيهات استنادًا إلى أهداف مستوى الخدمة

f63426182c052123.png

هذا الموضوع يهمّ الكاتب كثيرًا، لأنّ ريكاردو يعمل في مجال هندسة موثوقية الموقع (SRE) / عمليات التطوير (DevOps) في Google Cloud.

(مفتوحة) إنشاء مؤشرات أداء الخدمة (SLI) وأهداف مستوى الخدمة (SLO) لهذا التطبيق

ما فائدة تطبيق لا يمكنك معرفة ما إذا كان متوقفًا عن العمل؟

ما هو هدف مستوى الخدمة (SLO)؟

هذا أمر شاق. Google هي من ابتكرت أهداف مستوى الخدمة. للاطّلاع على مزيد من المعلومات حول هذا الموضوع، يمكنني اقتراح ما يلي:

الخطوة 1: إنشاء مؤشر/هدف مستوى الخدمة الخاص بالتوفّر

لنبدأ بمستوى SLO الخاص بالتوفّر، لأنّه الأسهل وربما الأكثر أهمية الذي تريد قياسه.

لحسن الحظ، تتضمّن Cloud Run ميزة دعم أهداف مستوى الخدمة (SLO) المُنشأة مسبقًا، وذلك بفضل Istio.

بعد نشر تطبيقك على Cloud Run، يصبح تحقيق ذلك بسيطًا للغاية، ويستغرق مني 30 ثانية.

  • انتقِل إلى صفحة Cloud Run.
  • انقر على تطبيقك أو اختَره.
  • انقر على علامة التبويب SLOs.
  • انقر على "+ إنشاء هدف مستوى الخدمة".
  • مدى التوفّر، حسب الطلب
  • متابعة
  • الشهر التقويمي / %99
  • انقر على "إنشاء هدف مستوى الخدمة".

e471c7ebdc56cdf6.png

الخطوة 2: إعداد التنبيهات بشأن مستوى الخدمة هذا

ننصحك بإنشاء تنبيهَين:

  1. إشعار بمعدّل استهلاك منخفض ("Slowburn") لتنبيهك عبر البريد الإلكتروني (يحاكي تذكرة ذات أولوية منخفضة).
  2. إشعار ذو معدّل استهلاك مرتفع ("Fastburn") لتنبيهك عبر رسالة SMS (يحاكي تذكرة / جهاز نداء عالي الأولوية)

انتقِل إلى SLO tab من قبل.

نفِّذ ما يلي مرّتين:

314bfd6b9ef0a260.png

  • انقر على "إنشاء تنبيه بشأن هدف مستوى الخدمة" (زر 🔔 مع علامة جمع في الداخل، على اليمين)
  • مدة المراجعة، حدّ معدّل الاستنفاد:
  • [FAST]. أولاً: 60 دقيقة / 10 مرة
  • [SLOW]. الثانية: 720 دقيقة / 2 x
  • قناة الإشعارات: انقر على "إدارة قنوات الإشعارات"
  • أولاً، "البريد الإلكتروني" -> إضافة جديد -> ..
  • ثانيًا، "رسائل SMS" -> إضافة رقم جديد -> تأكيد الرقم على الهاتف.
  • ملاحظة: أحب استخدام رموز الإيموجي في الأسماء. إنّها ممتعة للعروض التوضيحية.
  • عند الانتهاء، انقر على علامة X الكبيرة في أعلى يسار الشاشة.
  • اختَر الهاتف أولاً (بسرعة)، ثم البريد الإلكتروني (ببطء).
  • أضِف بعض المستندات النموذجية، مثل:
  • [PHP Amarcord] Riccardo told me to type sudo reboot or to check documentation in http://example.com/playbooks/1.php but I guess he was joking.

Bingo!

النتيجة النهائية

يمكننا اعتبار هذا التمرين منتهيًا بعد أن يكون لديك هدف مستوى خدمة واحد صالح بالإضافة إلى تنبيهَين بشأن مدى التوفّر، وأن يتم إرسال التنبيهات إلى بريدك الإلكتروني وهاتفك.

يمكنك إضافة وقت استجابة (أنصحك بشدة بذلك) أو حتى وقت استجابة أكثر تعقيدًا. بالنسبة إلى وقت الاستجابة، اختَر وقت استجابة تراه مناسبًا. وإذا كنت غير متأكّد، اختَر 200 ملي ثانية.

11. الخطوات التالية

لقد أكملت كل شيء، فما الذي ينقصك؟

إليك بعض الأفكار التي يجب التفكير فيها:

التفاعل مع Gemini

يمكنك استخدام Gemini بإصدارَين:

  1. ‫Vertex AI "طريقة المؤسسات"، المرتبطة بحسابك على Google Cloud Platform، والتي استكشفناها في الفصل 7 (GCF+Gemini) تعمل جميع عمليات المصادقة بشكل سحري، وتتصل الخدمات ببعضها البعض بشكل رائع.
  2. الذكاء الاصطناعي من Google "طريقة المستهلك" يمكنك الحصول على مفتاح Gemini API من هنا والبدء في إنشاء نصوص برمجية صغيرة يمكن ربطها بأي عبء عمل لديك (عمل خاص، أو سُحب أخرى، أو المضيف المحلي، وما إلى ذلك). ما عليك سوى استبدال مفتاح واجهة برمجة التطبيقات وسيبدأ الرمز في العمل بشكل سحري.

ننصحك بتجربة استكشاف (2) مع مشاريعك الخاصة.

UI Lifting

لا أجيد تصميم واجهات المستخدم. لكنّ Gemini يتيح ذلك. يمكنك ببساطة أخذ صفحة PHP واحدة وكتابة ما يلي:

I have a VERY old PHP application. I want to touch it as little as possible. Can you help me:

1. add some nice CSS to it, a single static include for tailwind or similar, whatever you prefer
2. Transform the image print with description into cards, which fit 4 per line in the canvas?

Here's the code:

-----------------------------------
[Paste your PHP page, for instance index.php - mind the token limit!]

يمكنك الحصول على ذلك بسهولة في أقل من 5 دقائق، وذلك من خلال عملية Cloud Build واحدة. :)

كان الردّ من Gemini مثاليًا (أي لم يكن عليّ إجراء أي تغيير):

8a3d5fe37ec40bf8.png

إليك التنسيق الجديد في تطبيق المؤلف الشخصي:

81620eb90ae3229a.png

ملاحظة: تم لصق الرمز كصورة لأنّنا لا نريد تشجيعك على نسخ الرمز، بل على أن يكتبه لك Gemini، مع مراعاة القيود الإبداعية الخاصة بك في واجهة المستخدم أو الواجهة الأمامية. صدّقني، لن تحتاج إلى إجراء سوى تغييرات بسيطة جدًا بعد ذلك.

الأمان

إنّ تأمين هذا التطبيق بشكلٍ صحيح ليس هدفًا من أهداف ورشة العمل هذه التي تستغرق 4 ساعات، لأنّ ذلك سيؤدي إلى زيادة الوقت اللازم لإكمالها بمقدار 1 إلى 2 من مراتب القدر.

مع ذلك، هذا الموضوع مهم للغاية. لقد جمعنا بعض الأفكار في SECURITY.

12. تهانينا!

تهانينا 🎉🎉🎉، لقد نجحت في تحديث تطبيق PHP القديم باستخدام Google Cloud.

24cb9a39b1841fbd.png

في ما يلي ملخّص لما تعلّمته في هذا الدرس التطبيقي حول الترميز:

  • كيفية نشر قاعدة بيانات في Google Cloud SQL وكيفية نقل قاعدة البيانات الحالية إليها
  • كيفية وضع تطبيق PHP في حاوية باستخدام Docker وBuildpacks وتخزين صورته في Google Cloud Artifact Registry
  • كيفية نشر تطبيقك الذي يعمل ضمن حاوية على Cloud Run وتشغيله باستخدام Cloud SQL
  • كيفية تخزين/استخدام مَعلمات الضبط الحسّاسة (مثل كلمة مرور قاعدة البيانات) بشكلٍ سرّي باستخدام Google Secret Manager
  • كيفية إعداد مسارَي التعلّم "الدمج المستمر" (CI) أو "النشر المستمر" (CD) باستخدام Google Cloud Build لإنشاء تطبيق PHP ونشره تلقائيًا عند إرسال أي رمز برمجي إلى مستودع GitHub
  • كيفية استخدام Cloud Storage "لتخزين" موارد تطبيقك في السحابة الإلكترونية
  • كيفية الاستفادة من التقنيات التي لا تتطلّب خادمًا لإنشاء مسارات عمل رائعة على Google Cloud بدون تعديل رمز تطبيقك
  • استخدِم قدرات Gemini المتعدّدة الوسائط في حالة استخدام مناسبة.
  • تطبيق مبادئ هندسة موثوقية الموقع (SRE) في Google Cloud

هذه بداية رائعة لرحلتك في تحديث التطبيقات باستخدام Google Cloud.

🔁 الملاحظات

إذا أردت إخبارنا بتجربتك في هذه ورشة العمل، يمكنك ملء نموذج الملاحظات هذا.

نرحّب بملاحظاتك وطلبات الدمجs بشأن أجزاء الرمز التي تفخر بها بشكل خاص.

🙏 شكرًا

يودّ المؤلّف شكر ميركو جيليولي وماوريتسيو إبسالي من Datatonic على المساعدة في كتابة المقالة واختبار الحلّ.