1. מבוא
העדכון האחרון: 1 בנובמבר 2024
איך מבצעים מודרניזציה לאפליקציית PHP ישנה ב-Google Cloud?
(📽️ כדאי לצפות בסרטון מבוא בן 7 דקות ל-codelab הזה)
בדרך כלל יש אפליקציות מדור קודם שפועלות בפריסה מקומית וצריך לבצע בהן מודרניזציה. כלומר, צריך לוודא שהם ניתנים להרחבה, מאובטחים וניתנים לפריסה בסביבות שונות.
בסדנה הזו תלמדו:
- העברת אפליקציית PHP לקונטיינר.
- מעבר לשירות מסד נתונים מנוהל ( Cloud SQL).
- פריסה ל-Cloud Run (חלופה ללא פעולות ל-GKE/Kubernetes).
- מאבטחים את האפליקציה באמצעות ניהול זהויות והרשאות גישה (IAM) ו-Secret Manager.
- הגדרת צינור CI/CD באמצעות Cloud Build. אפשר לחבר את Cloud Build למאגר Git שמתארח אצל ספקי Git פופולריים כמו GitHub או GitLab, ולהגדיר הפעלה בכל דחיפה ל-main, למשל.
- אירוח תמונות של האפליקציה ב-Cloud Storage. השינוי מתבצע באמצעות טעינה, ולא צריך לשנות את הקוד של האפליקציה.
- הוספנו פונקציונליות של AI גנרטיבי באמצעות Gemini, שמתואמת דרך Cloud Functions (בלי שרת).
- כדאי להכיר את הסכמי רמת השירות (SLO) ואת התפעול של האפליקציה החדשה.
אם תפעלו לפי השלבים האלה, תוכלו לשדרג בהדרגה את אפליקציית ה-PHP שלכם ולשפר את יכולת ההתאמה לעומס, את האבטחה ואת הגמישות של הפריסה. בנוסף, המעבר ל-Google Cloud מאפשר לכם להשתמש בתשתית ובשירותים המתקדמים שלו כדי לוודא שהאפליקציה פועלת בצורה חלקה בסביבה מבוססת-ענן.
אנחנו מאמינים שהידע שתצברו בעקבות השלבים הפשוטים האלה יכול לשמש אתכם באפליקציה ובארגון שלכם עם שפה/סטאק שונים ותסריטי שימוש שונים.
מידע על האפליקציה
האפליקציה ( קוד, במסגרת רישיון MIT) שאתם הולכים לשכפל היא אפליקציית PHP 5.7 בסיסית עם אימות MySQL. הרעיון המרכזי של האפליקציה הוא לספק פלטפורמה שבה משתמשים יכולים להעלות תמונות, ולאדמינים יש אפשרות לתייג תמונות לא הולמות. האפליקציה כוללת שתי טבלאות:
- משתמשים. הוא מגיע עם קומפילציה מראש לאדמינים. אנשים חדשים יכולים להירשם.
- תמונות. כולל כמה תמונות לדוגמה. משתמשים שמחוברים לחשבון יכולים להעלות תמונות חדשות. אנחנו נוסיף קצת קסם.
המטרה שלכם
אנחנו רוצים לעדכן את האפליקציה הישנה כדי להשתמש בה ב-Google Cloud. אנחנו נשתמש בכלים ובשירותים של Google Cloud כדי לשפר את יכולת ההתאמה לעומסים, לחזק את האבטחה, להפוך את ניהול התשתית לאוטומטי ולשלב תכונות מתקדמות כמו עיבוד תמונות, מעקב ואחסון נתונים באמצעות שירותים כמו Cloud SQL, Cloud Run, Cloud Build, Secret Manager ועוד.

חשוב מכך, אנחנו רוצים לעשות את זה שלב אחר שלב כדי שתוכלו ללמוד מה תהליך החשיבה מאחורי כל שלב, ובדרך כלל כל שלב פותח אפשרויות חדשות לשלבים הבאים (לדוגמה: מודול 2 -> 3 ומודול 6 -> 7).
עדיין לא השתכנעתם? כדאי לצפות בסרטון הזה באורך 7 דקות ב-YouTube.
מה תצטרכו
- מחשב עם דפדפן שמחובר לאינטרנט.
- קרדיטים מסוימים ב-GCP. אפשר לראות את השלב הבא.
- תשתמשו ב-Cloud Shell. הוא כולל את כל הפקודות שמותקנות מראש שתצטרכו וסביבת פיתוח משולבת (IDE).
- חשבון GitHub. צריך את זה כדי ליצור הסתעפות של הקוד המקורי 🧑🏻💻 gdgpescara/app-mod-workshop עם מאגר git משלכם. ההרשאה הזו נדרשת כדי ליצור צינור עיבוד נתונים משלכם של CI/CD (ביצוע אוטומטי של קומיט -> בנייה -> פריסה)
פתרונות לדוגמה זמינים כאן:
- מאגר המחבר: https://github.com/Friends-of-Ricc/app-mod-workshop
- מאגר הסדנה המקורי, בתיקיות
.solutions/, לפי פרק.
הסדנה הזו מיועדת לביצוע ב-Cloud Shell (בדפדפן).
עם זאת, אפשר לנסות גם מהמחשב המקומי.
2. הגדרת קרדיט ו-Fork

מימוש הקרדיט ב-GCP והגדרת סביבת GCP [אופציונלי]
כדי להשתתף בסדנה הזו, צריך חשבון לחיוב עם יתרה מסוימת. אם כבר יש לכם חיוב משלכם, אתם יכולים לדלג על השלב הזה.
יוצרים חשבון Gmail חדש לגמרי (*) כדי לקשר אותו לקרדיט ב-GCP. כדאי לבקש מהמורה את הקישור למימוש הקרדיט ב-GCP או להשתמש בקרדיט כאן: bit.ly/PHP-Amarcord-credits .
נכנסים לחשבון החדש שנוצר ופועלים לפי ההוראות.

(
) למה אני צריך חשבון Gmail חדש לגמרי?*
ראינו מקרים שבהם אנשים נכשלו ב-codelab כי החשבון שלהם (במיוחד כתובות אימייל של עבודה או של תלמידים) נחשף בעבר ל-GCP והיו בו מדיניות ארגונית שהגבילה את היכולת שלהם לעשות זאת. מומלץ ליצור חשבון Gmail חדש או להשתמש בחשבון Gmail קיים (gmail.com) שלא נעשה בו שימוש ב-GCP בעבר.
לוחצים על הלחצן כדי לממש את הקרדיט.

ממלאים את הטופס הבא עם השם הפרטי והשם המשפחה ומסכימים לתנאים ולהגבלות.
יכול להיות שתצטרכו לחכות כמה שניות עד שחשבון החיוב יופיע כאן: https://console.cloud.google.com/billing
אחרי שמסיימים, פותחים את מסוף Google Cloud ויוצרים פרויקט חדש. לשם כך, לוחצים על התפריט הנפתח לבחירת פרויקט בפינה הימנית העליונה, שבו מוצגת האפשרות 'אין ארגון'. מופיע בהמשך

אם אין לכם פרויקט, אתם יכולים ליצור פרויקט חדש כמו שמוצג בצילום המסך שלמטה. בפינה השמאלית העליונה, יש אפשרות 'פרויקט חדש'.

חשוב לקשר את הפרויקט החדש לחשבון לחיוב בתקופת הניסיון של GCP באופן הבא.

הכול מוכן לשימוש ב-Google Cloud Platform. אם אתם מתחילים או שאתם פשוט רוצים לעשות הכול בסביבת ענן, אתם יכולים לגשת ל-Cloud Shell ולעורך שלו באמצעות הלחצן הבא בפינה הימנית העליונה, כמו שמוצג למטה.

מוודאים שהפרויקט החדש נבחר בפינה הימנית העליונה:
לא נבחר (לא תקין):

נבחר (טוב):

יצירת העתק של האפליקציה מ-GitHub
- נכנסים לאפליקציית ההדגמה: https://github.com/gdgpescara/app-mod-workshop
- לוחצים על 🍴 fork.
- אם אין לכם חשבון GitHub, אתם צריכים ליצור חשבון חדש.
- עורכים את התכנים לפי הצורך.

- משכפלים את קוד האפליקציה באמצעות
git clonehttps://github.com/YOUR-GITHUB-USER/YOUR-REPO-NAME
- פותחים את תיקיית הפרויקט המשוכפל בעורך המועדף. אם בוחרים ב-Cloud Shell, אפשר לעשות את זה בלחיצה על Open Editor (פתיחת העורך), כמו שמוצג בהמשך.

יש לכם את כל מה שצריך בעורך Google Cloud Shell, כמו שמוצג באיור הבא

כדי לעשות זאת, לוחצים על 'פתיחת תיקייה' ובוחרים את התיקייה, בדרך כלל app-mod-workshop בתיקיית הבית.
3. מודול 1: יצירת מופע SQL
יצירת מכונה של Google Cloud SQL
האפליקציה שלנו ב-PHP תתחבר למסד נתונים מסוג MySQL, ולכן אנחנו צריכים לשכפל אותה ל-Google Cloud כדי להעביר אותה בקלות. Cloud SQL הוא הפתרון המושלם, כי הוא מאפשר להריץ מסד נתונים מנוהל של MySQL בענן. כך עושים את זה:
- עוברים לדף Cloud SQL: https://console.cloud.google.com/sql/instances
- לוחצים על Create Instance (יצירת מופע).
- מפעילים את ה-API (אם צריך). התהליך עשוי להימשך כמה שניות.
- בוחרים באפשרות MySQL.
- (אנחנו מנסים לספק לכם את הגרסה הכי זולה, כדי שהיא תחזיק מעמד יותר זמן):
- מהדורה: Enterprise
- הגדרה מראש: development (ניסינו Sandbox אבל היא לא התאימה לנו)
- Mysql Ver: 5.7 (וואו, חזרה לעבר!)
- מזהה מופע: בוחרים באפשרות
appmod-phpapp(אם משנים את זה, חשוב לזכור לשנות גם סקריפטים ופתרונות עתידיים בהתאם). - סיסמה: כל סיסמה שרוצים, אבל צריך לרשום אותה בתור CLOUDSQL_INSTANCE_PASSWORD
- אזור: משאירים את האזור שבחרתם עבור שאר האפליקציה (לדוגמה, מילאנו =
europe-west8) - זמינות אזורית: אזור יחיד (אנחנו חוסכים כסף לצורך ההדגמה)
לוחצים על הלחצן Create Instance (יצירת מופע) כדי לפרוס מסד נתונים של Cloud SQL. ⌛ התהליך נמשך כ-10 דקות.⌛ בינתיים, אפשר להמשיך לקרוא את התיעוד או להתחיל לפתור את המודול הבא (Containerize your PHP App) כי אין לו תלות במודול הזה בחלק הראשון (עד שתתקנו את חיבור מסד הנתונים).
הערה. העלות של המופע הזה צריכה להיות בערך 7$ ליום. חשוב להקפיד להסיר את המדבקה אחרי הסדנה.
יצירת מסד נתונים ומשתמש image_catalog ב-Cloud SQL
פרויקט האפליקציה מגיע עם תיקייה db/ שמכילה שני קובצי SQL:
- 01_schema.sql : מכיל קוד SQL ליצירת שתי טבלאות שמכילות נתונים של משתמשים ותמונות.
- 02_seed.sql: מכיל קוד SQL להוספת נתונים לטבלאות שנוצרו קודם.
הקבצים האלה ישמשו בהמשך אחרי שתיצור את מסד הנתונים image_catalog. כדי לעשות את זה:
- פותחים את המופע ולוחצים על הכרטיסייה Databases (מסדי נתונים):
- לוחצים על 'יצירת מסד נתונים'.
- קוראים לו
image_catalog(כמו בהגדרות של אפליקציית PHP).

לאחר מכן יוצרים את משתמש מסד הנתונים. כך נוכל לבצע אימות במסד הנתונים image_catalog.
- לוחצים על הכרטיסייה משתמשים.
- לוחצים על 'הוספת חשבון משתמש'.
- משתמש: בוא ניצור אחד:
- שם המשתמש/ת:
appmod-phpapp-user - סיסמה: בוחרים סיסמה שקל לזכור או לוחצים על 'יצירה'.
- משאירים את האפשרות אפשר לכל מארח (%).
- לוחצים על 'הוספה'.
פתיחת מסד הנתונים לכתובות IP מוכרות.
הערה: כל מסדי הנתונים ב-Cloud SQL נוצרים כ'מבודדים'. צריך להגדיר במפורש רשת שאפשר לגשת אליה.
- לוחצים על המופע.
- פותחים את התפריט 'חיבורים'.
- לוחצים על הכרטיסייה 'רשת'.
- לוחצים על האפשרות בקטע 'רשתות מורשות'. עכשיו מוסיפים רשת (כלומר, רשת משנה).
- בשלב הזה, נבחר הגדרות מהירות אבל לא בטוחות כדי לאפשר לאפליקציה לפעול. בהמשך כדאי להגביל את הגישה לאפליקציה רק לכתובות ה-IP שאתם סומכים עליהן:
- שם: 'Everyone in the world - INSECURE'.
- רשת: "
0.0.0.0/0"(הערה: זה החלק הלא מאובטח!) - לוחצים על 'סיום'.
- לוחצים על 'שמירה'.
אתם אמורים לראות משהו כזה:

הערה. הפתרון הזה הוא פשרה טובה כדי לסיים את הסדנה ב-O(hours). עם זאת, כדאי לעיין במסמך אבטחה כדי להבין איך לאבטח את הפתרון שלכם לייצור.
הגיע הזמן לבדוק את החיבור למסד הנתונים!
נבדוק אם המשתמש image_catalog שיצרנו קודם עובד.
נכנסים אל Cloud SQL Studio בתוך המכונה ומזינים את מסד הנתונים, המשתמש והסיסמה כדי לבצע אימות, כמו שמוצג בהמשך:

עכשיו אפשר לפתוח את כלי העריכה של SQL ולהמשיך לחלק הבא.
ייבוא מסד הנתונים מבסיס הקוד
משתמשים בעורך SQL כדי לייבא את הטבלאות image_catalog עם הנתונים שלהן. מעתיקים את קוד ה-SQL מהקבצים במאגר ( 01_schema.sql ואז 02_seed.sql) ומריצים אותם אחד אחרי השני בסדר רציף.
אחרי הפעולה הזו אמורות להתקבל שתי טבלאות בקטלוג התמונות: users ו-images, כמו שמוצג בהמשך:

כדי לבדוק את זה, מריצים את הפקודה הבאה בכלי העריכה: select * from images;
חשוב גם לרשום את כתובת ה-IP הציבורית של מופע Cloud SQL, כי תצטרכו אותה בהמשך. כדי לקבל את כתובת ה-IP, עוברים לדף הראשי של מכונת Cloud SQL בקטע Overview. (סקירה כללית > התחברות למופע הזה > כתובת IP ציבורית).
4. מודול 2: יצירת קונטיינר לאפליקציית PHP

אנחנו רוצים לפתח את האפליקציה הזו לענן.
המשמעות היא לארוז את הקוד בקובץ ZIP כלשהו שמכיל את כל המידע להרצה שלו בענן.
יש כמה דרכים לארוז את האפליקציה:
- Docker. פופולרי מאוד, אבל די מסובך להגדיר אותו בצורה נכונה.
- Buildpacks. פחות פופולרי, אבל נוטה 'לנחש' אוטומטית מה לבנות ומה להריץ. לרוב זה פשוט עובד!
בסדנה הזו נניח שאתם משתמשים ב-Docker.
אם בחרתם להשתמש ב-Cloud Shell, זה הזמן לפתוח אותו מחדש (לוחצים על הפינה השמאלית העליונה של Cloud Console).

אמור להיפתח מעטפת נוחה בתחתית הדף, שבה אמור להיות קוד שהועתק בשלב ההגדרה.

Docker
אם אתם רוצים לשלוט בנתונים, זה הפתרון המתאים לכם. זה הגיוני כשצריך להגדיר ספריות ספציפיות ולהוסיף התנהגויות מסוימות שלא ברורות מאליהן (chmod בהעלאות, קובץ הפעלה לא סטנדרטי באפליקציה וכו')
אנחנו רוצים לפרוס את האפליקציה שלנו בקונטיינר ב-Cloud Run, ולכן כדאי לעיין במסמכים הבאים. איך אפשר לבצע back port מ-php 8 ל-PHP 5.7? אולי תוכל להשתמש ב-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:

DB_NAMEshould be unchanged:image_catalog- הערך של
DB_USERצריך להיותappmod-phpapp-user -
DB_PASSהוא משהו שבחרתם. מגדירים אותו במירכאות בודדות ומבצעים escape לפי הצורך.
בנוסף, אפשר לתרגם את הקטעים באיטלקית לאנגלית בעזרת Gemini.
אוקיי, עכשיו שיש לך את Dockerfile והגדרת את אפליקציית ה-PHP שלך להתחבר למסד הנתונים, בוא ננסה את זה!
אם עדיין לא התקנתם את Docker, אתם יכולים לעשות זאת ( קישור). לא צריך את זה אם משתמשים ב-Cloud Shell (מגניב, נכון?).
עכשיו מנסים ליצור ולהריץ את אפליקציית ה-PHP בקונטיינר באמצעות הפקודות המתאימות של docker build ו-run.
# 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 (או על 'שינוי היציאה' לכל יציאה אחרת).

בדיקת התוצאה בדפדפן
עכשיו האפליקציה אמורה להיראות כך:

אם תתחברו באמצעות Admin/admin123, תראו משהו כזה.

נהדר!!! חוץ מהטקסט באיטלקית, הכול עובד! 🎉🎉🎉
אם תהליך ה-dockerization תקין אבל פרטי הכניסה למסד הנתונים שגויים, יכול להיות שתקבלו הודעה כזו:

כדאי לנסות שוב, כמעט הגעת!
שמירה ב-Artifact Registry [אופציונלי]
בשלב הזה, אמורה להיות לכם אפליקציית PHP בקונטיינר שמוכנה לפריסה בענן. בשלב הבא, אנחנו צריכים מקום בענן לאחסון קובץ האימג' של Docker, כדי שנוכל לפרוס אותו לשירותי Google Cloud כמו Cloud Run. פתרון האחסון הזה נקרא Artifact Registry, שירות מנוהל מלא של Google Cloud שנועד לאחסון ארטיפקטים של אפליקציות, כולל קובצי אימג' לקונטיינרים של Docker, חבילות Maven, מודולים של npm ועוד.
יוצרים מאגר ב-Google Cloud Artifact Registry באמצעות הלחצן המתאים.

בוחרים שם תקין, את הפורמט ואת האזור שמתאימים לאחסון הארטיפקטים.

חוזרים לתג של סביבת הפיתוח המקומית ומעבירים בדחיפה את קובץ האימג' של קונטיינר האפליקציה למאגר ב-Artifact Registry שנוצר זה עתה. כדי לעשות זאת, מריצים את הפקודות הבאות.
- docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- docker push TARGET_IMAGE[:TAG]
התוצאה אמורה להיראות כמו בצילום המסך הבא.

הצלחתם 🎉🎉🎉 אפשר לעבור לשלב הבא. לפני כן, כדאי להקדיש 2 דקות לניסיון להעלות קובץ, להתחבר או לצאת, ולהכיר את נקודות הקצה של האפליקציה.תצטרכו אותן בהמשך.
שגיאות אפשריות
אם מופיעות שגיאות בנוגע לקונטיינר, אפשר להשתמש ב-Gemini כדי לקבל הסבר על השגיאה ולתקן אותה. לשם כך, צריך לספק:
- קובץ Dockerfile הנוכחי
- השגיאה שהתקבלה
- [אם צריך] קוד ה-PHP שמופעל.
הרשאות העלאה. אפשר גם לנסות את נקודת הקצה /upload.php ולהעלות תמונה. יכול להיות שתקבלו את השגיאה שמופיעה למטה. אם כן, צריך לבצע תיקון של chmod/chown ב-Dockerfile.
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), כדי להתחבר למסד הנתונים. כאן אפשר לקבל השראה מפתרונות.
לא ניתן להעביר את הבקשה שלך אל ה-backend. החיבור לשרת ביציאה 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. Module 3: Deploy the App to Cloud Run

למה כדאי להשתמש ב-Cloud Run?
שאלה טובה! לפני כמה שנים, בטח היית בוחר ב-Google App Engine.
במילים פשוטות, היום, ל-Cloud Run יש סטאק תוכנות חדש יותר, קל יותר לפרוס אותה, היא זולה יותר, והיא מצטמצמת ל-0 כשלא משתמשים בה. הגמישות של Cloud Run להריץ כל קונטיינר בלי שמירת מצב, והשילוב שלו עם מגוון שירותי Google Cloud הופך אותו לאידיאלי לפריסת מיקרו-שירותים ואפליקציות מודרניות עם תקורה מינימלית ויעילות מקסימלית.
באופן ספציפי יותר, Cloud Run היא פלטפורמה מנוהלת במלואה של Google Cloud שמאפשרת להריץ אפליקציות בקונטיינרים ללא שמירת מצב בסביבה בלי שרת (serverless). הוא מטפל אוטומטית בכל התשתית, ומתרחב מאפס כדי לעמוד בנפח התנועה הנכנסת, ומתכווץ כשאין פעילות. כך הוא חסכוני ויעיל. Cloud Run תומך בכל שפה או ספרייה, כל עוד הן ארוזות בקונטיינר, מה שמאפשר גמישות רבה בפיתוח. הוא משתלב היטב עם שירותים אחרים של Google Cloud ומתאים לפיתוח מיקרו-שירותים, ממשקי API, אתרים ואפליקציות מבוססות-אירועים, בלי צורך לנהל תשתית שרתים.
דרישות מוקדמות
כדי לבצע את המשימה הזו, צריך להתקין את 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. יש כמה אפשרויות להגדרה כדי להשיג את היעד. אלה האפשרויות המינימליות שצריך לספק (אפשר לספק אותן דרך שורת הפקודה, או שהכלי יבקש אותן באמצעות הנחיה אינטראקטיבית):
- שם שירות Cloud Run שרוצים לפרוס לאפליקציה. שירות Cloud Run יחזיר כתובת URL שמספקת נקודת קצה לאפליקציה.
- אזור Google Cloud שבו האפליקציה תפעל. (
--regionREGION) - קובץ אימג' של קונטיינר שעוטף את האפליקציה.
- משתני סביבה שהאפליקציה צריכה להשתמש בהם במהלך ההפעלה.
- הדגל Allow-Unauthenticated שמאפשר לכולם לגשת לאפליקציה שלכם בלי אימות נוסף.
כדי לדעת איך להשתמש באפשרות הזו בשורת הפקודה, אפשר לעיין במסמכי העזרה (או לגלול למטה כדי לראות פתרון אפשרי).
הפריסה תימשך כמה דקות. אם הכל תקין, אמור להופיע במסוף Google Cloud משהו כזה.


לוחצים על כתובת ה-URL שסופקה על ידי Cloud Run ובודקים את האפליקציה. אחרי האימות, אמור להופיע משהו כזה.

'gcloud run deploy' ללא ארגומנטים
יכול להיות ששמתם לב ש-gcloud run deploy שואל אתכם את השאלות הנכונות וממלא את החסר. זה מדהים!
עם זאת, בכמה מודולים אנחנו הולכים להוסיף את הפקודה הזו לטריגר לפיתוח גרסת Build של Cloud, ולכן אנחנו לא יכולים להרשות לעצמנו שאלות אינטראקטיביות. צריך למלא את כל האפשרויות בפקודה. אז אתה רוצה ליצור את הזהב gcloud run deploy --option1 blah --foo bar --region your-fav-region. איך עושים את זה?
- חוזרים על שלבים 2-3-4 עד שהכלי gcloud מפסיק לשאול שאלות:
- [LOOP]
gcloud run deployעם האפשרויות שנמצאו עד עכשיו - [LOOP] מערכות מבקשות אפשרות X
- [LOOP] Search in public docs how to set up X from CLI adding option
--my-option [my-value]. - חוזרים לשלב 2, אלא אם gcloud מסתיים בלי שאלות נוספות.
- gcloud run deploy BLAH BLAH BLAH rocks! שומרים את הפקודה במקום כלשהו, כי תצטרכו אותה בהמשך בשלב Cloud Build.
פתרון אפשרי מפורט כאן. מסמכי Docs זמינים כאן.
הצלחה 🎉🎉🎉 פרסת את האפליקציה שלך ב-Google Cloud, והשלמת את השלב הראשון בתהליך המודרניזציה.
6. מודול 4: סיסמה נקייה עם Secret Manager

בשלב הקודם הצלחנו לפרוס את האפליקציה שלנו ב-Cloud Run ולהפעיל אותה. עם זאת, עשינו זאת תוך שימוש בשיטת אבטחה לא מומלצת: העברת סודות מסוימים בטקסט גלוי.
איטרציה ראשונה: מעדכנים את הקובץ config.php כדי להשתמש ב-ENV
יכול להיות ששמתם לב שהכנסנו את הסיסמה למסד הנתונים ישירות לקוד בקובץ config.php. זה בסדר למטרות בדיקה ולראות אם האפליקציה פועלת. אבל אי אפשר לבצע קומיט של קוד כזה או להשתמש בו בסביבת ייצור. הסיסמה (ופרמטרים אחרים של חיבור למסד הנתונים) צריכה להיקרא באופן דינמי ולהימסר לאפליקציה בזמן הריצה. משנים את הקובץ config.php כך שהוא יקרא את פרמטרים של מסד הנתונים ממשתני הסביבה. אם ההגדרה נכשלת, כדאי להגדיר ערכי ברירת מחדל. השיטה הזו שימושית במקרה של טעינת 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. מוסיפים ל-Dockerfile הקודם את 4 הפרמטרים באמצעות התחביר ENV DB_VAR=ENV_VAR_VALUE. המערכת תגדיר ערכי ברירת מחדל שאפשר לשנות בזמן הריצה. לדוגמה, אפשר להגדיר כאן את הערכים של DB_NAME ו-DB_USER, ולא בשום מקום אחר.
- בזמן הפעלה. אפשר להגדיר את המשתנים האלה ב-Cloud Run, גם דרך ה-CLI וגם דרך ממשק המשתמש. זה המקום הנכון להציב את כל 4 המשתנים (אלא אם רוצים לשמור את הגדרות ברירת המחדל שמוגדרות ב-קובץ Docker).
ב-localhost, כדאי להוסיף את משתני הסביבה לקובץ .env (אפשר לבדוק בתיקייה solutions).
חשוב גם לוודא שהקובץ .env נוסף ל-.gitignore : לא כדאי להעלות את הסודות שלכם ל-GitHub.
echo .env >> .gitignore
אחרי כן, אפשר לבדוק את המכונה באופן מקומי:
docker run -it -p 8080:8080 --env-file .env my-php-app-docker
עכשיו השגתם את הדברים הבאים:
- האפליקציה תקרא את המשתנה באופן דינמי מה-ENV
- שיפרת את האבטחה כי הסרת את הסיסמה של מסד הנתונים מהקוד)
עכשיו אפשר לפרוס עדכון חדש ב-Cloud Run. נעבור לממשק המשתמש ונגדיר את משתני הסביבה באופן ידני:
- עוברים אל https://console.cloud.google.com/run
- לוחצים על האפליקציה.
- לוחצים על 'עריכה ופריסה של גרסה חדשה'.
- בכרטיסייה הראשונה Container(s) (מאגרי תגים), לוחצים על הכרטיסייה התחתונה Variables and secrets (משתנים וסודות).
- לוחצים על '+ הוספת משתנה' ומוסיפים את כל המשתנים הנדרשים. התוצאה צריכה להיות דומה לזה:


האם זה מושלם? לא. רוב המפעילים עדיין יכולים לראות את כרטיס ה-PASS שלכם. אפשר לצמצם את הסיכון באמצעות Secret Manager של Google Cloud.
איטרציה שנייה: Secret Manager
הסיסמאות נעלמו מהקוד שלכם: ניצחתם! אבל רגע – האם אנחנו כבר בטוחים?
הסיסמאות שלכם עדיין גלויות לכל מי שיש לו גישה למסוף Google Cloud. למעשה, אם תיגשו לקובץ הפריסה של Cloud Run בפורמט YAML, תוכלו לאחזר אותו. או אם מנסים לערוך או לפרוס גרסה חדשה של Cloud Run, הסיסמה גלויה בקטע Variables & Secrets (משתנים וסודות), כפי שמוצג בצילומי המסך שלמטה.
Secret Manager ב-Google Cloud הוא שירות מאובטח ומרכזי לניהול מידע רגיש כמו מפתחות API, סיסמאות, אישורים וסודות אחרים.
השירות מאפשר לכם לאחסן סודות, לנהל אותם ולגשת אליהם באמצעות הרשאות פרטניות והצפנה חזקה. Secret Manager משולב עם ניהול זהויות והרשאות גישה (IAM) של Google Cloud, ומאפשר לכם לקבוע למי תהיה גישה לסודות ספציפיים, כדי להבטיח את אבטחת המידע ועמידה בתקנות.
הוא גם תומך ברוטציה אוטומטית של סודות ובניהול גרסאות, וכך מפשט את ניהול מחזור החיים של הסודות ומשפר את האבטחה באפליקציות בשירותי Google Cloud.
כדי לגשת אל Secret Manager, עוברים מתפריט ההמבורגר אל שירותי האבטחה ומאתרים אותו בקטע הגנה על נתונים, כמו שמוצג בצילום המסך שלמטה.

אחרי שמגיעים לשם, מפעילים את Secret Manager API כמו שמוצג בתמונה הבאה.

- עכשיו לוחצים על יצירת סוד: ניתן לו שם הגיוני:
- שם:
php-amarcord-db-pass - ערך הסוד: 'your DB password' (מתעלמים מהחלק 'upload file').
- תציין את הקישור הסודי הזה, הוא צריך להיראות כך:
projects/123456789012/secrets/php-amarcord-db-pass. זהו המצביע הייחודי לסוד שלכם (ל-Terraform, ל-Cloud Run ולשירותים אחרים). המספר הוא מספר הפרויקט הייחודי שלכם.
טיפ: כדאי להשתמש במוסכמות עקביות למתן שמות לסודות, תוך התמחות משמאל לימין, למשל: cloud-devrel-phpamarcord-dbpass
- ארגון (עם החברה)
- צוות (בתוך הארגון)
- אפליקציה (בתוך הצוות)
- שם המשתנה (באפליקציה)
כך תוכלו ליצור בקלות ביטויי Regex כדי למצוא את כל הסודות שלכם באפליקציה אחת.
יצירת גרסה חדשה של Cloud Run
עכשיו, אחרי שיצרנו סוד חדש, צריך להיפטר ממשתנה הסביבה DB_PASS ולהחליף אותו בסוד החדש. כך:
- גישה ל-Cloud Run באמצעות מסוף Google Cloud
- בוחרים את האפליקציה.
- לוחצים על 'עריכה ופריסה של גרסה חדשה'.
- מאתרים את הכרטיסייה Variables & Secrets (משתנים וסודות).
- משתמשים בלחצן '+ הפניה לסוד' כדי לאפס את משתנה הסביבה DB_PASS.
- צריך להשתמש באותו DB_PASS עבור הסודות שאליהם יש הפניה, ולהשתמש בגרסה העדכנית.

אחרי שמסיימים, אמורה להופיע השגיאה הבאה

מנסים להבין איך לפתור את הבעיה. כדי לפתור את הבעיה, צריך להיכנס לקטע IAM & Admin ולשנות את הרשאות הגישה. ניפוי באגים מהנה!
אחרי שמבינים מה הבעיה, חוזרים ל-Cloud Run ומבצעים פריסה מחדש של עדכון חדש. התוצאה אמורה להיראות כמו באיור הבא:

טיפ: ממשק המשתמש של Developer Console מצוין לזיהוי בעיות שקשורות להרשאות. כדאי להקדיש זמן כדי לעבור על כל הקישורים של ישויות ה-Cloud שלכם.
7. מודול 5: הגדרת CI/CD באמצעות Cloud Build

למה כדאי להשתמש בצינור עיבוד נתונים של CI/CD?
עד עכשיו, בטח הקלדתם gcloud run deploy כמה פעמים, אולי עניתם על אותה שאלה שוב ושוב.
נמאס לכם לפרוס את האפליקציה באופן ידני באמצעות gcloud run deploy? האם לא יהיה נהדר אם האפליקציה שלכם תוכל לפרוס את עצמה באופן אוטומטי בכל פעם שתדחפו שינוי חדש למאגר Git?
כדי להשתמש בצינור עיבוד נתונים של CI/CD, צריך שני דברים:
- מאגר Git אישי: למזלכם, כבר עשיתם Fork למאגר של הסדנה בחשבון GitHub שלכם בשלב 2. אם לא, חוזרים אחורה ומשלימים את השלב הזה. המאגר המפוצל אמור להיראות כך:
https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop - Cloud Build. השירות המדהים והזול הזה מאפשר לכם להגדיר אוטומציה של בנייה כמעט לכל דבר: Terraform, אפליקציות ב-Docker וכו'.
בקטע הזה נתמקד בהגדרת Cloud Build.
היכנסו ל-Cloud Build!
נשתמש ב-Cloud Build כדי לעשות את זה:
- ליצור את המקור (עם Dockerfile). אפשר לחשוב על זה כעל קובץ ZIP גדול שמכיל את כל מה שצריך כדי ליצור ולהפעיל פתרונות חכמים (הארטיפקט של ה-build).
- העלאת הפריט הזה ל-Artifact Registry (AR).
- לאחר מכן, מנפיקים פריסה מ-AR ל-Cloud Run עבור האפליקציה php-amarcord
- כך תיצור גרסה חדשה של האפליקציה הקיימת (כמו שכבה עם הקוד החדש), ואנחנו נגדיר אותה כך שהתנועה תופנה לגרסה החדשה אם הפעולה תצליח.
זו דוגמה לכמה גרסאות של האפליקציה php-amarcord שלי:

איך אנחנו עושים את כל זה?
- על ידי יצירת קובץ YAML מושלם אחד:
cloudbuild.yaml - יצירת טריגר לפיתוח גרסת Build ב-Cloud.
- חיבור למאגר GitHub שלנו דרך ממשק המשתמש של Cloud Build.
יצירת טריגר (ומאגר Connect)
- עוברים אל https://console.cloud.google.com/cloud-build/triggers
- לוחצים על 'יצירת טריגר'.
- לקמפל:
- שם: משהו בעל משמעות כמו
on-git-commit-build-php-app - אירוע: Push to branch
- מקור: Connect new repository (קישור מאגר חדש)

- ייפתח חלון בצד ימין: 'חיבור מאגר'
- ספק המקור: 'Github' (ראשון)
- "Continue" (המשך)
- האפשרות Authenticate (אימות) תפתח חלון ב-GitHub לצורך אימות צולב. פועלים לפי השלבים ומחכים בסבלנות. אם יש לכם הרבה מאגרי מידע, יכול להיות שייקח לכם זמן.
- 'בחירת מאגר' בוחרים את החשבון או המאגר ומסמנים את התיבה 'אני מבין/ה...'.
- אם קיבלתם שגיאה: אפליקציית GitHub לא מותקנת באף אחד מהמאגרים שלכם. לוחצים על Install Google Cloud Build ופועלים לפי ההוראות.
לוחצים על 'חיבור'.
- בינגו! המאגר מקושר עכשיו.
- חוזרים לחלק של הטריגר…
- הגדרה: זיהוי אוטומטי (*)
- מתקדם: בוחרים את חשבון השירות [PROJECT_NUMBER]- compute@developer.gserviceaccount.com
- xxxxx הוא מזהה הפרויקט
- חשבון השירות שמוגדר כברירת מחדל לחישוב מתאים לגישת מעבדה – אל תשתמשו בו בסביבת ייצור! ( מידע נוסף).
- כל שאר ההגדרות יישארו כמו שהן.
- לוחצים על הלחצן 'יצירה'.
(*) זו הדרך הפשוטה ביותר, כי היא בודקת אם יש קובץ Dockerfile או cloudbuild.yaml. עם זאת, הצומת cloudbuild.yaml מאפשרת לכם להחליט מה לעשות בכל שלב.
יש לי את הכוח!
מעכשיו, הטריגר לא יפעל אלא אם תעניקו לחשבון השירות של Cloud Build (מהו חשבון שירות? כתובת האימייל של 'רובוט' שמבצע משימה בשמכם – במקרה הזה, בניית דברים בענן!).
ה-SA לא יוכל ליצור ולפרוס את האפליקציה אלא אם תתנו לו הרשאה לעשות זאת. למזלכם, זה קל!
- עוברים אל Cloud Build > הגדרות.
- חשבון השירות '[PROJECT_NUMBER]- compute@developer.gserviceaccount.com'
- מסמנים את התיבות הבאות:
- Cloud Run
- Secret Manager
- חשבונות שירות
- Cloud Build
- מסמנים גם את התיבה 'הגדרה כחשבון שירות מועדף'.

איפה נמצא קובץ ה-YAML של Cloud Build?
מומלץ מאוד להקדיש זמן ליצירת קובץ YAML משלכם ל-Cloud Build.
עם זאת, אם אין לכם זמן, או שאתם לא רוצים לפנות זמן, תוכלו לקבל השראה בתיקיית הפתרונות הזו: .solutions
עכשיו אפשר להעביר שינוי ל-GitHub ולראות את הפעולה של Cloud Build.
ההגדרה של Cloud Build יכולה להיות מסובכת. צפויים חילופי הודעות עד:
- בדיקת היומנים בכתובת https://console.cloud.google.com/cloud-build/builds;region=global
- איתור השגיאה.
- תיקון בקוד והנפקה מחדש של git commit / git push.
- לפעמים השגיאה לא נמצאת בקוד, אלא בהגדרה כלשהי. במקרה כזה, אפשר להנפיק build חדש מממשק המשתמש (cloud build > Triggers > Run).

חשוב לזכור שאם משתמשים בפתרון הזה, עדיין יש עבודה לעשות. לדוגמה, צריך להגדיר את משתני הסביבה לנקודות הקצה החדשות שנוצרו לפיתוח ולייצור:

תוכל לעשות זאת בשתי דרכים:
- דרך ממשק המשתמש – על ידי הגדרה מחדש של משתני הסביבה
- באמצעות CLI על ידי יצירת סקריפט "מושלם" בשבילכם. דוגמה אפשר למצוא כאן: gcloud-run-deploy.sh . צריך לשנות כמה דברים, למשל את נקודת הקצה ומספר הפרויקט. אפשר למצוא את מספר הפרויקט בסקירה הכללית של Cloud.
איך שולחים קוד ל-GitHub?
הסדנה הזו לא כוללת הסבר על הדרך הכי טובה git push ל-GitHub. עם זאת, אם נתקעתם ואתם ב-Cloud Shell, יש שתי דרכים:
- CLI. מוסיפים מפתח SSH באופן מקומי ומוסיפים מאגר מרוחק עם git@github.com:YOUR_USER/app-mod-workshop.git (במקום http)
- VSCode. אם אתם משתמשים בעורך של Cloud Shell, אתם יכולים להשתמש בכרטיסייה 'ניהול מקורות' (ctrl-shift-G), ללחוץ על 'סנכרון שינויים' ולפעול לפי ההוראות. אפשר לאמת את חשבון GitHub ב-VS Code, ואז פעולות השליפה והדחיפה יהיו קלות מאוד.

חשוב לזכור git add clodubuild.yaml בין קבצים אחרים, אחרת הוא לא יפעל.
השוואה בין עומק ההתאמה בין סביבת הפיתוח לסביבת הייצור [אופציונלי]
אם העתקתם את גרסת המודל מכאן, יהיו לכם שתי גרסאות זהות של DEV ו-PROD. זה מגניב, ומתאים לכלל 10 של The Twelve-Factor App.
עם זאת, אנחנו משתמשים בשתי נקודות קצה שונות באינטרנט כדי שאפליקציה תצביע על אותו מסד נתונים. זה מספיק טוב לסדנה, אבל בחיים האמיתיים כדאי להקדיש זמן ליצירת סביבת ייצור מתאימה. כלומר, צריך שני מסדי נתונים (אחד לפיתוח ואחד לייצור), וגם לבחור איפה למקם אותם לצורך תוכנית התאוששות מאסון (DR) או זמינות גבוהה. זה כבר מעבר להיקף הסדנה הזו, אבל כדאי לחשוב על זה.
אם יש לכם זמן ליצור גרסה מפורטת של ההפקה, חשוב לזכור את כל המשאבים שצריך לשכפל, כמו:
- מסד נתונים של Cloud SQL (וכנראה גם מופע SQL).
- קטגוריית GCS
- פונקציה של Cloud Functions.
- אפשר להשתמש ב-Gemini 1.5 Flash כמודל בפיתוח (זול יותר, מהיר יותר) וב-Gemini 1.5 Pro (חזק יותר).
באופן כללי, בכל פעם שאתם עושים משהו באפליקציה, כדאי לחשוב בצורה ביקורתית: האם הערך הזה צריך להיות זהה בסביבת הייצור או לא? אם לא, כדאי לשכפל את המאמץ. כמובן שהרבה יותר קל לעשות את זה עם Terraform, שבו אפשר להוסיף את הסביבה (-dev, -prod) כסיומת למשאבים.
8. מודול 6: מעבר ל-Google Cloud Storage

אחסון

בשלב הזה, האפליקציה מאחסנת את המצב בקונטיינר של Docker. אם המכונה מתקלקלת, האפליקציה קורסת או אם פשוט מפעילים גרסה חדשה, תתוזמן גרסה חדשה עם אחסון חדש וריק: 🙈
איך פותרים את הבעיה? יש כמה גישות.
- אחסון תמונות במסד הנתונים. בסופו של דבר, זה מה שעשיתי עם אפליקציית PHP הקודמת שלי. זה הפתרון הכי פשוט כי הוא לא מוסיף מורכבות. אבל זה מוסיף בוודאות חביון ועומס למסד הנתונים.
- העברת האפליקציה ב-Cloud Run לפתרון שמתאים לאחסון: GCE + אחסון מתמיד (persistent disk)? אולי GKE + Storage? הערה: ככל שהשליטה גדולה יותר, כך הגמישות קטנה יותר.
- עוברים אל GCS. Google Cloud Storage מציע את האחסון הטוב ביותר מסוגו לכל Google Cloud, והוא הפתרון הכי אופייני לענן. עם זאת, כדי לעשות את זה צריך להשתמש בספריות PHP. האם יש לנו ספריות PHP 5.7 ל-GCS? האם
PHP 5.7בכלל תומך ב-Composer(נראה ש-PHP 5.3.2 היא הגרסה הכי ישנה שנתמכת על ידי Composer)? - אולי כדאי להשתמש ב-docker sidecar?
- אפשר גם להשתמש ב-GCS Cloud Run Volume Mounts. זה נשמע מדהים.
🤔 Migrate storage (open ended)
[Open Ended] In this exercise, we want you to find a solution to move your images in a way which is persisted in some way.
בדיקת קבלה
אני לא רוצה לגלות לך את הפתרון, אבל אני רוצה שזה יקרה:
- אתם מעלים את
newpic.jpg. הוא מופיע באפליקציה. - אתם משדרגים את האפליקציה לגרסה חדשה.
- הוא עדיין שם, גלוי.
newpic.jpg
💡 פתרון אפשרי (טעינת נפחים של GCS Cloud Run)
זה פתרון אלגנטי מאוד שמאפשר לנו להעלות קבצים עם שמירת מצב בלי לגעת בקוד בכלל (חוץ מהצגת תיאור תמונה, אבל זה עניין פשוט ורק כדי שיהיה נעים לעין).
הפעולה הזו אמורה לאפשר לכם לטעון תיקייה מ-Cloud Run ל-GCS, כך ש:
- כל ההעלאות ל-GCS יוצגו באפליקציה.
- כל ההעלאות לאפליקציה שלכם יועלו בפועל ל-GCS
- קסם יקרה לאובייקטים שיועלו ב-GCS (פרק 7).
הערה. חשוב לקרוא את האותיות הקטנות של FUSE. אם הביצועים הם בעיה, זה לא בסדר.
יצירת קטגוריה ב-GCS
GCS הוא שירות האחסון בכל מקום ב-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.
אפשר גם לבצע את אותה פעולה דרך ממשק המשתמש
- בכרטיסייה Volumes (נפחים), יוצרים Volume Mounts (נקודות לחיבור נפחים) שמצביעות על הקטגוריה שלכם, מסוג Cloud Storage bucket (קטגוריה של Cloud Storage), לדוגמה עם השם php_uploads.
- בקטע Container(s) > Volume Mounts (מאגרי תגים > נקודות לחיבור נפח אחסון), מחברים את נפח האחסון שיצרתם לנקודת נפח האחסון שהאפליקציה מבקשת. זה תלוי בקובץ ה-Dockerfile, אבל יכול להיות שזה ייראה כך:
var/www/html/uploads/.
בכל מקרה, אם זה עובד, כשעורכים את הגרסה החדשה של Cloud Run אמור להופיע משהו כזה:

עכשיו בודקים את האפליקציה החדשה על ידי העלאת תמונה חדשה אחת לנקודת הקצה /upload.php.
התמונות צריכות לזרום בצורה חלקה ב-GCS בלי לכתוב שורת PHP אחת:

מה קרה עכשיו?
קרה משהו קסום.
אפליקציה ישנה עם קוד ישן עדיין מבצעת את העבודה שלה. סט חדש ומודרני מאפשר לנו להציג את כל התמונות באפליקציה שלנו בנוחות, בקטגוריה של Cloud עם שמירת מצב. עכשיו השמיים הם הגבול:
- רוצים לשלוח אימייל בכל פעם שתמונה עם הכיתוב 'מסוכן' או 'עירום' מתקבלת? אפשר לעשות את זה בלי לגעת בקוד ה-PHP.
- רוצה להשתמש במודל Gemini Multimodal בכל פעם שתמונה מגיעה כדי לתאר אותה, ולהעלות את מסד הנתונים עם התיאור שלה? אפשר לעשות את זה בלי לגעת בקוד ה-PHP. אתה לא מאמין לי? ממשיכים לקרוא בפרק 7.
הרגע פתחנו כאן מרחב גדול של הזדמנויות.
9. מודול 7: שיפור האפליקציה באמצעות Google Gemini

עכשיו יש לכם אפליקציית PHP חדשה ומודרנית (כמו 2024 Fiat 126) עם אחסון בענן.
מה אפשר לעשות איתה?
דרישות מוקדמות
בפרק הקודם, פתרון לדוגמה אפשר לנו לטעון תמונות /uploads/ ב-GCS, ובכך למעשה להפריד את הלוגיקה של האפליקציה מאחסון התמונות.
במסגרת התרגיל הזה תצטרכו:
- השלמת בהצלחה את התרגיל בפרק 6 (אחסון).
- יש לכם קטגוריה ב-GCS עם העלאות של תמונות, שבה אנשים מעלים תמונות באפליקציה שלכם והתמונות מועברות לקטגוריה.
הגדרת פונקציית Cloud (ב-Python)
חשבתם פעם איך מטמיעים אפליקציה מבוססת-אירועים? למשל:
- כשמתרחש <event> => שליחת אימייל
- when <event> happens => if <condition> is true, then update the Database.
אירוע יכול להיות כל דבר, החל מרשומה חדשה שזמינה ב-BigQuery, אובייקט חדש שהשתנה בתיקייה ב-GCS, או הודעה חדשה שממתינה בתור ב-Pub/Sub.
ב-Google Cloud יש תמיכה בכמה פרדיגמות להשגת המטרה הזו. בעיקר:
- EventArc. איך מקבלים אירועים של GCS אפשר ליצור DAG ולתזמן פעולות על סמך if-then-else בענן.
- Cloud Scheduler. לדוגמה, זה מצוין למשימת cron בחצות ב-Cloud.
- Cloud Workflows. בדומה ל-Event Arc, מאפשרת לכם
- פונקציות Cloud Run (שנקרא גם
lambdas). - Cloud Composer. בעצם, זו הגרסה של Google ל-Apache Airflow, והיא מצוינת גם ל-DAG.
בתרגיל הזה נתעמק ב-Cloud Functions כדי להשיג תוצאה מרשימה. בנוסף, נספק לכם תרגילים אופציונליים.
שימו לב שקוד לדוגמה מופיע בקטע .solutions/
הגדרת פונקציית Cloud (🐍 Python)
אנחנו מנסים ליצור GCF שאפתני מאוד.
- כשיוצרים תמונה חדשה ב-GCS.. (כנראה שמישהו העלה אותו לאפליקציה – אבל לא רק)
- .. call Gemini to describe it and get a textual description of the image .. (would be nice to check the MIME and ensure its an image and not a PDF, MP3, or Text)
- .. ולעדכן את מסד הנתונים עם התיאור הזה. (יכול להיות שיהיה צורך להוסיף תיקון למסד הנתונים כדי להוסיף עמודת
descriptionלטבלהimages).
תיקון מסד הנתונים כדי להוסיף description לתמונות
- פותחים את Cloud SQL Studio:

- מזינים את שם המשתמש והסיסמה למסד הנתונים של התמונות
- מזריקים את ה-SQL הזה שמוסיף עמודה לתיאור תמונה:
ALTER TABLE images ADD COLUMN description TEXT;

ובינגו! כדאי לנסות עכשיו לבדוק אם זה עבד:
SELECT * FROM images;
עכשיו אמורה להופיע עמודת התיאור החדשה:

כתיבת Gemini f(x)
הערה. הפונקציה הזו נוצרה בעזרת Gemini Code Assist.
הערה. יכול להיות שתיתקלו בשגיאות הרשאה ב-IAM כשתיצרו את הפונקציה הזו. חלק מהשגיאות מתועדות בהמשך, בקטע 'שגיאות אפשריות'.
- הפעלת ממשקי ה-API
- עוברים אל https://console.cloud.google.com/functions/list
- לוחצים על Create Function (יצירת פונקציה).
- הפעלת ממשקי API באמצעות אשף ה-API:

אפשר ליצור את GCF מממשק המשתמש או משורת הפקודה. במקרה הזה נשתמש בשורת הפקודה.
קוד אפשרי נמצא בשדה .solutions/
- יוצרים תיקייה לאירוח הקוד, למשל gcf/. נכנסים לתיקייה.
- יוצרים קובץ
requirements.txt:
google-cloud-storage
google-cloud-aiplatform
pymysql
- יוצרים פונקציית 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
- דוחפים את הפונקציה. אפשר להשתמש בסקריפט דומה לזה: 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 Function יעביר אליה את אירוע GCS עם כל המידע הרלוונטי (שם הדלי, שם האובייקט וכו'). כדאי להקדיש זמן לניפוי הבאגים במילון האירועים הזה של Python.
בדיקת הפונקציה
בדיקות יחידה
יש בפונקציה הרבה חלקים שמשתנים. יכול להיות שתרצו לבדוק את כל המשימות הבודדות.
דוגמה מופיעה ב-gcf/test.py.
ממשק המשתמש של Cloud Functions
כדאי גם להקדיש זמן ללימוד הפונקציה בממשק המשתמש. מומלץ לעיין בכל הכרטיסיות, במיוחד בכרטיסיות Source (המועדפת עליי), Variables, Trigger ו-Logs. תבלו הרבה זמן בכרטיסייה Logs כדי לפתור שגיאות (אפשר גם לעיין בשגיאות האפשריות בתחתית הדף הזה). כדאי גם לבדוק את Permissions.

בדיקת E2E
הגיע הזמן לבדוק את הפונקציה באופן ידני.
- עוברים לאפליקציה ונכנסים לחשבון.
- מעלים תמונה (לא גדולה מדי, נתקלנו בבעיות עם תמונות גדולות)
- בודקים בממשק המשתמש שהתמונה הועלתה.
- בודקים ב-Cloud SQL Studio שהתיאור עודכן. מתחברים ומריצים את השאילתה הזו:
SELECT * FROM images.

וזה עובד! יכול להיות שנרצה גם לעדכן את ממשק הקצה כדי להציג את התיאור הזה.
עדכון 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. גרסה מעוצבת יכולה להיראות כך:

מסקנות
קיבלתם Cloud Function שהופעל על אובייקטים חדשים שהגיעו ל-GCS, שיכול להוסיף הערות לתוכן של התמונה כמו שאדם יכול לעשות, ולעדכן את מסד הנתונים באופן אוטומטי. וואו!
מה השלב הבא? אפשר להשתמש באותו היגיון כדי להשיג שתי פונקציות שימושיות.
[optional] Add further Cloud Functions [open ended]
יש עוד כמה תכונות שכדאי להזכיר.
📩 טריגר של אימייל
טריגר של אימייל ששולח לכם אימייל בכל פעם שמישהו שולח תמונה.
- בתדירות גבוהה מדי? להוסיף עוד הגבלה: תמונה גדולה, או תמונה שהתוכן שלה ב-Gemini מכיל את המילים 'עירום' או 'אלים'.
- כדאי לבדוק את
EventArc.
🚫 סינון אוטומטי של תמונות בלתי הולמות
כרגע, אדמין אנושי מסמן תמונות כ "לא הולמות". מה דעתך ש-Gemini יעשה את העבודה הקשה וינהל את המרחב? מוסיפים בדיקה לסימון תוכן לא הולם בטריגר ומעדכנים את מסד הנתונים כמו שלמדנו בפונקציה הקודמת. כלומר, לוקחים את הפונקציה הקודמת, משנים את ההנחיה ומעדכנים את מסד הנתונים על סמך התשובה.
הערה. הפלט של ה-AI הגנרטיבי לא צפוי. לוודא ש"התוצרים היצירתיים" של Gemini מוגבלים. אתם יכולים לבקש תשובה דטרמיניסטית כמו ציון רמת סמך מ-0 עד 1, קובץ JSON וכו'. יש הרבה דרכים לעשות את זה, למשל: * שימוש בספריות Python pydantic, langchain וכו'. * שימוש בפלט מובנה של Gemini.
כדאי לדעת. יכול להיות שיש לכם כמה פונקציות או הנחיה אחת שמחייבת תשובת JSON (עובד מצוין עם 'פלט מובנה של Gemini' כמו שצוין למעלה), למשל:
מה תהיה ההנחיה ליצירת התמונה הזו?
{
"description": "This is the picture of an arrosticino",
"suitable": TRUE
}
אפשר להוסיף להנחיה שדות נוספים כדי לקבל תובנות כמו: האם יש משהו טוב בתוצאה? מה לא טוב בו? האם המקום מוכר לך? האם יש טקסט (זיהוי תווים אופטי (OCR) מעולם לא היה קל יותר):
-
goods: 'It looks like yummie food' bads: "נראה כמו אוכל לא בריא"OCR: "Da consumare preferibilmente prima del 10 Novembre 2024"location: "Pescara, Lungomare"
בדרך כלל עדיף להשתמש בפונקציה N ל-N תוצאות, אבל כדאי מאוד ליצור פונקציה אחת שמבצעת 10 פעולות. במאמר הזה של ריקרדו מוסבר איך עושים את זה.
שגיאות אפשריות (בעיקר שגיאות שקשורות ל-IAM או להרשאות)
בפעם הראשונה שפיתחתי את הפתרון הזה נתקלתי בבעיות בהרשאות IAM. אצרף אותן כאן כדי להביע אמפתיה ולתת כמה רעיונות לפתרון.
שגיאה: אין מספיק הרשאות לחשבון השירות
- שימו לב: כדי לפרוס פונקציית GCF שמקשיבה לדלי GCS, צריך להגדיר הרשאות מתאימות לחשבון השירות שבו אתם משתמשים למשימה, כמו באיור:

יכול להיות שתצטרכו גם להפעיל את ממשקי ה-API של EventArc. יכול להיות שיעברו כמה דקות עד שהם יהיו זמינים באופן מלא.
שגיאה: חסר Cloud Run invoker
- תגובה נוספת מממשק המשתמש לגבי הרשאות GCF היא זו ( תפקיד Cloud Run Invoker):

כדי לתקן את השגיאה הזו, מריצים את הפקודה שמופיעה בתמונה, שדומה ל-fix-permissions.sh
הבעיה הזו מתוארת כאן: https://cloud.google.com/functions/docs/securing/authenticating
שגיאה: חריגה ממגבלת הזיכרון
בפעם הראשונה שהרצתי אותו, יכול להיות שבלוגים שלי יופיעו ההודעות הבאות: 'חריגה ממגבלת הזיכרון של 244MB עם שימוש של 270MB. מומלץ להגדיל את מגבלת הזיכרון. מידע נוסף זמין בכתובת https://cloud.google.com/functions/docs/configuring/memory. מוסיפים שוב זיכרון RAM ל-GCF. קל מאוד לעשות את זה בממשק המשתמש. הנה דוגמה לשינוי אפשרי:

לחלופין, אפשר גם לתקן את סקריפט הפריסה של Cloud Run כדי להגדיל את השימוש בזיכרון או במעבד. הפעולה הזו אורכת קצת יותר זמן.
שגיאה: פורסם ב-PubSub
יצירת טריגר באמצעות GCF v1 הניבה פעם אחת את השגיאה הבאה:

שוב, קל לתקן את זה: עוברים אל IAM ומקצים לחשבון השירות את התפקיד 'פרסום הודעות ב-Pub/Sub'.
שגיאה: לא נעשה שימוש ב-Vertex AI
אם מופיעה השגיאה הזו:
Permission Denied: 403 Vertex AI API has not been used in project YOUR_PROJECT before or it is disabled. כדי להפעיל אותו, עוברים אל https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT
צריך רק להפעיל את ממשקי Vertex AI API. הדרך הכי קלה להפעיל את כל ממשקי ה-API הנדרשים היא:
- https://console.cloud.google.com/vertex-ai
- לוחצים על 'הפעלת כל ממשקי ה-API המומלצים'.

שגיאה: לא נמצא טריגר EventArc.
אם זה קורה, צריך לפרוס מחדש את הפונקציה.

שגיאה: 400 סוכני שירות מוקצים
400 סוכני שירות מוקצים ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents ). סוכני שירות נדרשים כדי לקרוא את הקובץ שסופק ב-Cloud Storage. כדאי לנסות שוב בעוד כמה דקות.
אם זה קורה, צריך לחכות קצת או לשאול עובד של Google.
10. מודול 8: יצירת יעדי רמת שירות (SLO) של זמינות
בפרק הזה אנחנו מנסים להשיג את המטרה הבאה:
- יצירת SLI
- יצירת יעדי זמינות (SLO) על סמך מדדי הזמינות (SLI)
- יצירת התראות על סמך SLO

הנושא הזה חשוב מאוד למחבר, כי ריקרדו עובד בתחום SRE / DevOps ב-Google Cloud.
(open-ended) Create SLIs and SLOs for this app
מהי לדעתך איכות האפליקציה אם אי אפשר לדעת מתי היא לא פעילה?
מה זה SLO?
אוי ואבוי! Google המציאה את יעדי ה-SLO! כדי לקרוא מידע נוסף על כך, אני יכול להציע:
- SRE Book - chapter 2 - Implementing SLOs. ( 👉 עוד ספרים בנושא SRE)
- Art of SLOs ( סרטון מעולה). זו הדרכה מצוינת שבה אפשר ללמוד איך ליצור SLO מושלם לשירות שלכם.
- קורס SRE ב-Coursera השתתפתי בזה!
שלב 1: יצירת SLI/SLO של זמינות
נתחיל עם SLO של זמינות, כי זה הכי קל ואולי הכי חשוב למדוד.
למזלנו, Cloud Run מגיע עם תמיכה מובנית ב-SLO, הודות ל-Istio.
אחרי שהאפליקציה שלכם מופעלת ב-Cloud Run, קל מאוד להשיג את זה. זה לוקח לי 30 שניות.
- עוברים לדף Cloud Run.
- לוחצים על האפליקציה או בוחרים אותה.
- בוחרים בכרטיסייה
SLOs. - לוחצים על '+ יצירת SLO'.
- זמינות, על בסיס בקשה
- המשך
- חודש ביומן / 99%.
- לוחצים על 'יצירת SLO'.

שלב 2: הגדרת התראות לגבי ה-SLO הזה
מומלץ ליצור 2 התראות:
- אחת עם קצב שחיקה נמוך (Slowburn) כדי לשלוח לכם התראה באימייל (מדמה כרטיס עם עדיפות נמוכה).
- אחד עם קצב שריפה גבוה ("שריפה מהירה") כדי להזהיר אתכם באמצעות SMS (מדמה כרטיס עם עדיפות גבוהה / ביפר)
עוברים אל SLO tab הקודם.
חוזרים על הפעולה פעמיים:

- לוחצים על 'יצירת התראה על SLO' (הלחצן 🔔 עם סימן הפלוס בתוכו, מימין).
- משך המבט לאחור, סף קצב שריפת המזומנים:
- [FAST]. תקופה ראשונה:
60דקות /10x - [SLOW]. שנייה:
720דקות /2x - ערוץ התראות: לוחצים על 'ניהול ערוצי התראות'
- קודם כל, 'אימייל' -> הוספה -> ..
- בשלב השני, בוחרים באפשרות '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.
בינגו!
תוצאה סופית
נראה שהתרגיל הזה הסתיים ברגע שיהיה לך SLO אחד פעיל + 2 התראות לגבי הזמינות, וההתראות יישלחו לאימייל ולטלפון שלך.
אם רוצים, אפשר להוסיף השהיה (ואני ממליץ מאוד לעשות זאת) או אפילו מורכבת יותר. בקטע 'זמן אחזור', בוחרים זמן אחזור שנראה סביר. אם לא בטוחים, בוחרים באפשרות 200ms.
11. השלבים הבאים
השלמת הכול, מה חסר?
כמה נקודות למחשבה:
איך משחקים עם Gemini
אתם יכולים להשתמש ב-Gemini בשתי דרכים:
- Vertex AI. הדרך של Enterprise, שמשולבת עם GCP, ושהסברנו עליה בפרק 7 (GCF+Gemini). כל האימות פועל בצורה חלקה, והשירותים מתקשרים ביניהם בצורה מושלמת.
- AI מבית Google. הדרך של הצרכן. אתם מקבלים מפתח Gemini API מכאן ומתחילים ליצור סקריפטים קטנים שאפשר לקשר לכל עומס עבודה שכבר יש לכם (עבודה קניינית, עננים אחרים, localhost וכו'). אתם פשוט מחליפים את מפתח ה-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 הייתה מושלמת (כלומר, לא הייתי צריך לשנות כלום):

והנה הפריסה החדשה באפליקציה לשימוש אישי של הסופר:

הערה: הקוד מודבק כתמונה כי אנחנו לא רוצים לעודד אתכם להעתיק את הקוד, אלא להשתמש ב-Gemini כדי לכתוב את הקוד בשבילכם, עם המגבלות שלכם לגבי ממשק המשתמש או הקצה הקדמי. תאמינו לי, אחרי זה נשארים לכם שינויים קלים מאוד.
אבטחה
הגנה על האפליקציה הזו היא לא המטרה של הסדנה הזו בת 4 השעות, כי היא תאריך את הזמן שיידרש להשלמת הסדנה בערך פי 10 עד פי 100.
אבל הנושא הזה חשוב מאוד! ריכזנו כמה רעיונות בSECURITY.
12. מעולה!
מזל טוב 🎉🎉🎉 , הצלחת להפוך את אפליקציית ה-PHP מדור קודם שלך למודרנית באמצעות Google Cloud.

לסיכום, ב-Codelab הזה למדתם:
- איך פורסים מסד נתונים ב-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 כדי להעביר את משאבי האפליקציה לענן
- איך אפשר למנף טכנולוגיות בלי שרת (serverless) כדי לבנות Workflows מדהימים ב-Google Cloud בלי לגעת בקוד האפליקציה.
- שימוש ביכולות מרובות-המוֹדָל של Gemini בתרחיש שימוש מתאים.
- Implement SRE principles within Google Cloud
זוהי התחלה מצוינת של המסע שלכם למודרניזציה של אפליקציות באמצעות Google Cloud.
🔁 משוב
אם אתם רוצים לספר לנו על החוויה שלכם בסדנה הזו, אתם יכולים למלא את טופס המשוב הזה.
נשמח לקבל ממך משוב וגם בקשות למשיכת קוד לגבי קטעי קוד שאתה גאה בהם במיוחד.
🙏 תודה
המחבר רוצה להודות ל-Mirko Gilioli ול-Maurizio Ipsale מ-Datatonic על העזרה בכתיבת המאמר ובבדיקת הפתרון.
