1. परिचय
पिछले अपडेट की तारीख: 01-11-2024
हम किसी पुराने PHP ऐप्लिकेशन को Google Cloud पर कैसे अपग्रेड करें?
(📽️ इस कोडलैब के बारे में सात मिनट का शुरुआती वीडियो देखें)
आम तौर पर, ऑन-प्रॉपर्टी (ऑफ़िस में मौजूद) ऐसे लेगसी ऐप्लिकेशन होते हैं जिन्हें आधुनिक बनाना ज़रूरी होता है. इसका मतलब है कि उन्हें अलग-अलग एनवायरमेंट में स्केल किया जा सकता है, सुरक्षित किया जा सकता है, और डिप्लॉय किया जा सकता है.
इस वर्कशॉप में, आपको ये चीज़ें पता चलेंगी:
- PHP ऐप्लिकेशन को कंटेनर में डालें.
- मैनेज की जाने वाली डेटाबेस सेवा ( Cloud SQL) पर माइग्रेट करें.
- Cloud Run पर डिप्लॉय करें. यह GKE/Kubernetes के लिए, बिना किसी ऑपरेशन के काम करने वाला विकल्प है.
- Identity and Access Management (IAM) और Secret Manager की मदद से, ऐप्लिकेशन को सुरक्षित करें.
- Cloud Build की मदद से, सीआई/सीडी पाइपलाइन तय करें. Cloud Build को GitHub या GitLab जैसी लोकप्रिय Git सेवा देने वाली कंपनियों पर होस्ट किए गए आपके Git repo से कनेक्ट किया जा सकता है. उदाहरण के लिए, मुख्य रिपॉज़िटरी में किसी भी पुश पर इसे ट्रिगर किया जा सकता है.
- ऐप्लिकेशन की फ़ोटो को Cloud Storage पर होस्ट करें. ऐसा माउंट करने की सुविधा की मदद से किया जाता है. साथ ही, ऐप्लिकेशन बदलने के लिए किसी कोड की ज़रूरत नहीं होती.
- Gemini की मदद से जेन एआई की सुविधाएं उपलब्ध कराएं. इसे Cloud Functions (सर्वरलेस) की मदद से ऑर्केस्ट्रेट किया जाता है.
- एसएलओ और अपने नए रीफ़्रेश किए गए ऐप्लिकेशन को ऑपरेटिंग करने के बारे में जानें.
यह तरीका अपनाकर, अपने PHP ऐप्लिकेशन को धीरे-धीरे आधुनिक बनाया जा सकता है. इससे, ऐप्लिकेशन को स्केल करने, उसकी सुरक्षा, और डिप्लॉयमेंट में आसानी से मदद मिलती है. इसके अलावा, Google Cloud पर माइग्रेट करने से, आपको इसके बेहतर इंफ़्रास्ट्रक्चर और सेवाओं का फ़ायदा मिलता है. इससे यह पक्का किया जा सकता है कि आपका ऐप्लिकेशन, क्लाउड-नेटिव एनवायरमेंट में आसानी से काम करे.
हमें लगता है कि इन आसान चरणों को अपनाकर, आपको जो जानकारी मिलेगी उसे अपने ऐप्लिकेशन और संगठन के लिए अलग-अलग भाषा/स्टैक और अलग-अलग इस्तेमाल के उदाहरणों के साथ लागू किया जा सकता है.
ऐप्लिकेशन के बारे में जानकारी
आपको जिस ऐप्लिकेशन ( एमआईटी लाइसेंस के तहत कोड) को फ़ॉर्क करना है वह MySQL पुष्टि करने की सुविधा वाला एक बुनियादी PHP 5.7 ऐप्लिकेशन है. इस ऐप्लिकेशन का मुख्य मकसद, लोगों को ऐसा प्लैटफ़ॉर्म उपलब्ध कराना है जहां वे फ़ोटो अपलोड कर सकें. साथ ही, एडमिन के पास आपत्तिजनक इमेज को टैग करने की सुविधा होती है. ऐप्लिकेशन में दो टेबल होती हैं:
- उपयोगकर्ता. यह एडमिन के साथ पहले से कंपाइल किया गया होता है. नए लोग रजिस्टर कर सकते हैं.
- इमेज. इसमें कुछ सैंपल इमेज होती हैं. लॉग इन किए हुए उपयोगकर्ता, नई फ़ोटो अपलोड कर सकते हैं. हम यहां कुछ जादू जोड़ेंगे.
आपका लक्ष्य
हम Google Cloud में पुराने ऐप्लिकेशन को शामिल करने के लिए, उसे आधुनिक बनाना चाहते हैं. हम इसके टूल और सेवाओं का इस्तेमाल करके, स्केलेबिलिटी को बेहतर बनाएंगे, सुरक्षा को बढ़ाएंगे, और इन्फ़्रास्ट्रक्चर मैनेजमेंट को ऑटोमेट करेंगे. साथ ही, Cloud SQL, Cloud Run, Cloud Build, Secret Manager वगैरह जैसी सेवाओं का इस्तेमाल करके, इमेज प्रोसेसिंग, मॉनिटरिंग, और डेटा स्टोरेज जैसी बेहतर सुविधाओं को इंटिग्रेट करेंगे.
सबसे अहम बात यह है कि हम इसे सिलसिलेवार तरीके से करना चाहते हैं, ताकि आप यह जान सकें कि हर चरण के पीछे क्या सोच है. आम तौर पर, हर चरण से अगले चरण के लिए नई संभावनाएं खुलती हैं. उदाहरण के लिए, मॉड्यूल 2 -> 3 और 6 -> 7.
क्या आपको अब भी यकीन नहीं है? YouTube पर यह सात मिनट का वीडियो देखें.
आपको इन चीज़ों की ज़रूरत होगी
- ब्राउज़र वाला कंप्यूटर, जो इंटरनेट से कनेक्ट हो.
- कुछ GCP क्रेडिट. अपने आस-पास मौजूद Google के किसी प्रशंसक से पूछें ;)
gcloud
कमांड काम कर रहा है.- क्या आप लोकल तौर पर काम कर रहे हैं? इसे यहां डाउनलोड करें. इसके लिए, आपको एक अच्छा एडिटर (जैसे, vscode या intellij) भी चाहिए.
- क्या आपको "क्लाउड में" सभी काम करने हैं? इसके बाद, Cloud Shell का इस्तेमाल किया जा सकता है.
- GitHub उपयोगकर्ता. आपको अपने git repo के साथ ओरिजनल कोड 🧑🏻💻 gdgpescara/app-mod-workshop को ब्रैंच करने के लिए, इसकी ज़रूरत होगी. यह आपकी खुद की सीआई/सीडी पाइपलाइन (अपने-आप कमिट होना -> बिल्ड होना -> डिप्लॉय होना) के लिए ज़रूरी है
समस्याओं को हल करने के उदाहरण यहां देखे जा सकते हैं:
- लेखक का रिपॉज़िटरी: https://github.com/Friends-of-Ricc/app-mod-workshop
- हर चैप्टर के लिए,
.solutions/
फ़ोल्डर में मौजूद ओरिजनल वर्कशॉप का रेपो.
इस वर्कशॉप को अपने कंप्यूटर पर या पूरी तरह ब्राउज़र पर भी पूरा किया जा सकता है.
2. क्रेडिट सेट अप करना और फ़ॉर्क करना
GCP क्रेडिट रिडीम करना और अपना GCP एनवायरमेंट सेट अप करना [ज़रूरी नहीं]
यह वर्कशॉप चलाने के लिए, आपके पास कुछ क्रेडिट वाला बिलिंग खाता होना चाहिए. अगर आपके पास पहले से ही बिलिंग की जानकारी है, तो इस चरण को छोड़ा जा सकता है.
अपने GCP क्रेडिट को लिंक करने के लिए, एक नया Google Gmail खाता बनाएं (*). अपने ट्रेनर से GCP क्रेडिट रिडीम करने का लिंक मांगें या यहां क्रेडिट का इस्तेमाल करें: bit.ly/PHP-Amarcord-credits .
नए खाते से साइन इन करें और निर्देशों का पालन करें.
(
) मुझे नया Gmail खाता क्यों चाहिए?*
हमने देखा है कि कुछ लोगों को कोडलैब में समस्या आ रही है. इसकी वजह यह है कि उनके खाते (खास तौर पर, ऑफ़िस या छात्र-छात्राओं के ईमेल खाते) में पहले से GCP का इस्तेमाल किया जा रहा था. साथ ही, संगठन की नीतियों की वजह से, वे कोडलैब में हिस्सा नहीं ले पा रहे थे. हमारा सुझाव है कि आप नया Gmail खाता बनाएं या किसी ऐसे मौजूदा Gmail खाते (gmail.com) का इस्तेमाल करें जिसका इस्तेमाल पहले GCP के लिए न किया गया हो.
क्रेडिट रिडीम करने के लिए, बटन पर क्लिक करें.
नीचे दिया गया फ़ॉर्म भरें. इसमें अपना नाम और सरनेम डालें. साथ ही, नियम और शर्तों को स्वीकार करें.
बिलिंग खाता यहां दिखने में कुछ सेकंड लग सकते हैं: https://console.cloud.google.com/billing
इसके बाद, Google Cloud Console खोलें और सबसे ऊपर बाएं ड्रॉपडाउन मेन्यू में प्रोजेक्ट सिलेक्टर पर क्लिक करके नया प्रोजेक्ट बनाएं. यहां "कोई संगठन नहीं" दिखेगा. नीचे देखें
अगर आपके पास कोई प्रोजेक्ट नहीं है, तो नीचे दिए गए स्क्रीनशॉट में दिखाए गए तरीके से नया प्रोजेक्ट बनाएं. सबसे ऊपर दाएं कोने में, "नया प्रोजेक्ट" विकल्प होता है.
नए प्रोजेक्ट को GCP के ट्रायल बिलिंग खाते से इस तरह लिंक करें.
अब Google Cloud Platform का इस्तेमाल किया जा सकता है. अगर आपने अभी-अभी इस्तेमाल शुरू किया है या आपको सिर्फ़ Cloud के प्लैटफ़ॉर्म पर काम करना है, तो Cloud Shell और उसके एडिटर को ऐक्सेस किया जा सकता है. इसके लिए, सबसे ऊपर बाएं कोने में दिए गए बटन का इस्तेमाल करें.
पक्का करें कि सबसे ऊपर बाईं ओर आपका नया प्रोजेक्ट चुना गया हो:
नहीं चुना गया (गलत):
चुना गया (अच्छा):
GitHub से ऐप्लिकेशन को फ़ॉर्क करना
- डेमो ऐप्लिकेशन पर जाएं: https://github.com/gdgpescara/app-mod-workshop
- 🍴 फ़ॉर्क पर क्लिक करें.
- अगर आपके पास github खाता नहीं है, तो आपको नया खाता बनाना होगा.
- अपनी पसंद के मुताबिक बदलाव करें.
- इनका इस्तेमाल करके, ऐप्लिकेशन कोड को क्लोन करें
git clone
https://github.com/
YOUR-GITHUB-USER/YOUR-REPO-NAME
- क्लोन किए गए प्रोजेक्ट फ़ोल्डर को अपने पसंदीदा एडिटर में खोलें. अगर आपने Cloud Shell चुना है, तो "एडिटर खोलें" पर क्लिक करके ऐसा किया जा सकता है, जैसा कि यहां दिखाया गया है.
Google Cloud Shell Editor में आपको सभी ज़रूरी सुविधाएं मिलती हैं, जैसा कि इस इमेज में दिखाया गया है
"फ़ोल्डर खोलें" पर क्लिक करके और फ़ोल्डर चुनकर, विज़ुअल तौर पर भी ऐसा किया जा सकता है. हो सकता है कि यह फ़ोल्डर आपके होम फ़ोल्डर में app-mod-workshop
हो.
3. मॉड्यूल 1: SQL इंस्टेंस बनाना
Google Cloud SQL इंस्टेंस बनाना
हमारा PHP ऐप्लिकेशन, MySQL डेटाबेस से कनेक्ट होगा. इसलिए, हमें इसे Google Cloud पर कॉपी करना होगा, ताकि माइग्रेशन आसानी से हो सके. Cloud SQL आपके लिए सबसे सही विकल्प है, क्योंकि इसकी मदद से Cloud में पूरी तरह से मैनेज किया जाने वाला MySQL डेटाबेस चलाया जा सकता है. इसके लिए, यह तरीका अपनाएं:
- Cloud SQL पेज पर जाएं: https://console.cloud.google.com/sql/instances
- "इंस्टेंस बनाएं" पर क्लिक करें
- एपीआई चालू करें (अगर ज़रूरी हो). इसमें कुछ सेकंड लग सकते हैं.
- MySQL चुनें.
- (हम आपको सबसे सस्ता वर्शन देने की कोशिश कर रहे हैं, ताकि यह ज़्यादा समय तक चल सके):
- वर्शन: Enterprise
- प्रीसेट: डेवलपमेंट (हमने सैंडबॉक्स आज़माया, लेकिन वह हमारे लिए काम नहीं किया)
- MySQL वर्शन: 5.7 (वाह, पुराने दिनों की यादें!)
- इंस्टेंस आईडी:
appmod-phpapp
चुनें (अगर आपने इसे बदला है, तो आने वाले समय में स्क्रिप्ट और समाधानों को भी उसी हिसाब से बदलना न भूलें). - पासवर्ड: कोई भी पासवर्ड डालें, लेकिन इसे CLOUDSQL_INSTANCE_PASSWORD के तौर पर नोट करें
- क्षेत्र: इसे वही रखें जो आपने ऐप्लिकेशन के बाकी हिस्से के लिए चुना है. उदाहरण के लिए, मिलान =
europe-west8
- ज़ोनल अवेल: सिंगल ज़ोन (हम डेमो के लिए पैसे बचा रहे हैं)
Cloud SQL डेटाबेस को डिप्लॉय करने के लिए, 'इंस्टेंस बनाएं' बटन पर क्लिक करें. ⌛ इसे पूरा होने में करीब 10 मिनट लगते हैं⌛. इस दौरान, दस्तावेज़ पढ़ना जारी रखें. आपके पास अगले मॉड्यूल ("अपने PHP ऐप्लिकेशन को कंटेनर में डालना") को हल करने का विकल्प भी है, क्योंकि पहले हिस्से में इस मॉड्यूल पर कोई डिपेंडेंसी नहीं है (जब तक कि डीबी कनेक्शन ठीक नहीं किया जाता).
ध्यान दें. इस इंस्टेंस की लागत, आपको ~7 डॉलर प्रति दिन हो सकती है. वर्कशॉप के बाद, इसे स्पिन-ऑफ़ करना न भूलें.
Cloud SQL में image_catalog DB और उपयोगकर्ता बनाएं
ऐप्लिकेशन प्रोजेक्ट में एक db/
फ़ोल्डर होता है, जिसमें दो SQL फ़ाइलें होती हैं:
- 01_schema.sql : इसमें उपयोगकर्ताओं और इमेज का डेटा शामिल करने वाली दो टेबल बनाने के लिए SQL कोड शामिल है.
- 02_seed.sql: इसमें, पहले से बनाई गई टेबल में डेटा डालने के लिए एसक्यूएल कोड होता है.
image_catalog
डेटाबेस बन जाने के बाद, इन फ़ाइलों का इस्तेमाल किया जाएगा. ऐसा करने के लिए, यह तरीका अपनाएं:
- अपना इंस्टेंस खोलें और 'डेटाबेस' टैब पर क्लिक करें:
- "डेटाबेस बनाएं" पर क्लिक करें
- इसे
image_catalog
(जैसा कि PHP ऐप्लिकेशन कॉन्फ़िगरेशन में है) कहें.
इसके बाद, हम डेटाबेस उपयोगकर्ता बनाते हैं. इसकी मदद से, image_catalog डेटाबेस में पुष्टि की जा सकती है.
- अब उपयोगकर्ता टैब पर क्लिक करें
- "उपयोगकर्ता खाता जोड़ें" पर क्लिक करें.
- उपयोगकर्ता: आइए, एक नया टैग बनाते हैं:
- उपयोगकर्ता नाम:
appmod-phpapp-user
- पासवर्ड: कोई ऐसा पासवर्ड चुनें जिसे याद रखा जा सके या "जनरेट करें" पर क्लिक करें
- "किसी भी होस्ट को अनुमति दें (%)" को सेट रहने दें.
- 'जोड़ें' पर क्लिक करें.
DB को जाने-पहचाने आईपी के लिए खोलें.
ध्यान दें कि Cloud SQL में सभी डीबी, 'अलग-अलग' होते हैं. आपको साफ़ तौर पर कोई नेटवर्क सेट अप करना होगा, ताकि उससे डिवाइस को ऐक्सेस किया जा सके.
- अपने इंस्टेंस पर क्लिक करें
- "कनेक्शन" मेन्यू खोलें
- "नेटवर्किंग" टैब पर क्लिक करें.
- "अनुमति वाले नेटवर्क" पर क्लिक करें. अब कोई नेटवर्क (जैसे, सबनेट) जोड़ें.
- फ़िलहाल, ऐप्लिकेशन को काम करने देने के लिए, तुरंत सेट की जा सकने वाली, लेकिन असुरक्षित सेटिंग चुनें. बाद में, उन आईपी पर पाबंदी लगाई जा सकती है जिन पर आपको भरोसा है:
- नाम: "दुनिया में कोई भी - असुरक्षित".
- नेटवर्क: "
0.0.0.0/0"
(ध्यान दें: यह असुरक्षित हिस्सा है!) - 'हो गया' पर क्लिक करें
- 'सेव करें' पर क्लिक करें.
आपको कुछ ऐसा दिखेगा:
ध्यान दें. यह तरीका, वर्कशॉप को O(hours) में खत्म करने के लिए एक अच्छा समझौता है. हालांकि, प्रोडक्शन के लिए अपने समाधान को सुरक्षित रखने के लिए, सुरक्षा दस्तावेज़ देखें!
डीबी कनेक्शन की जांच करने का समय आ गया है!
आइए देखें कि पहले से बनाया गया image_catalog
उपयोगकर्ता काम करता है या नहीं.
इंस्टेंस में "Cloud SQL Studio" ऐक्सेस करें. इसके बाद, पुष्टि करने के लिए डेटाबेस, उपयोगकर्ता, और पासवर्ड डालें, जैसा कि यहां दिखाया गया है:
अब आपके पास SQL एडिटर खोलने और अगले सेक्शन पर जाने का विकल्प है.
कोडबेस से डेटाबेस इंपोर्ट करना
image_catalog
टेबल और उनके डेटा को इंपोर्ट करने के लिए, SQL एडिटर का इस्तेमाल करें. रिपॉज़िटरी में मौजूद फ़ाइलों ( 01_schema.sql और फिर 02_seed.sql) से SQL कोड कॉपी करें और उन्हें क्रम से एक के बाद एक चलाएं.
इसके बाद, आपको image_catalog में दो टेबल दिखेंगी. ये टेबल users और images हैं, जैसा कि यहां दिखाया गया है:
इसका टेस्ट करने के लिए, Editor में यह कोड चलाएं: select * from images;
साथ ही, Cloud SQL इंस्टेंस का सार्वजनिक आईपी पता भी नोट कर लें. आपको इसकी ज़रूरत बाद में पड़ेगी. आईपी पता पाने के लिए, खास जानकारी पेज पर जाकर, Cloud SQL इंस्टेंस के मुख्य पेज पर जाएं. (खास जानकारी > इस इंस्टेंस से कनेक्ट करें > सार्वजनिक आईपी पता).
4. मॉड्यूल 2: अपने PHP ऐप्लिकेशन को कंटेनर में डालना
हम इस ऐप्लिकेशन को क्लाउड के लिए बनाना चाहते हैं.
इसका मतलब है कि कोड को किसी ऐसी ZIP फ़ाइल में पैकेज करना जिसमें Cloud में उसे चलाने के लिए पूरी जानकारी हो.
इसे पैकेज करने के कुछ तरीके हैं:
- Docker. यह बहुत लोकप्रिय है, लेकिन इसे सही तरीके से सेट अप करना काफ़ी मुश्किल है.
- बिल्डपैक. यह कम लोकप्रिय है, लेकिन यह अपने-आप यह अनुमान लगा लेता है कि क्या बनाया जाए और क्या चलाया जाए. अक्सर यह आसानी से काम कर जाता है!
इस वर्कशॉप में, हम यह मानकर चलेंगे कि आपने Docker का इस्तेमाल किया है.
अगर आपने Cloud Shell का इस्तेमाल करने का विकल्प चुना है, तो इसे फिर से खोलने का समय आ गया है. इसके लिए, Cloud Console के सबसे ऊपर दाईं ओर मौजूद आइकॉन पर क्लिक करें.
इससे पेज पर सबसे नीचे एक शेल खुल जाएगा. यहां आपको सेट-अप के चरण में कोड को फ़ॉर्क करना होगा.
Docker
अगर आपको अपने खाते को मैनेज करना है, तो यह आपके लिए सही विकल्प है. ऐसा तब करना चाहिए, जब आपको कुछ खास लाइब्रेरी कॉन्फ़िगर करनी हों और कुछ ऐसे काम करने हों जो साफ़ तौर पर न दिखें. जैसे, अपलोड में chmod, आपके ऐप्लिकेशन में कोई ऐसा काम जो स्टैंडर्ड न हो, वगैरह
हम अपने कंटेनर वाले ऐप्लिकेशन को Cloud Run पर डिप्लॉय करना चाहते हैं. इसलिए, यहां दिया गया दस्तावेज़ देखें. इसे PHP 8 से PHP 5.7 में कैसे बैकपोर्ट किया जा सकता है? इसके लिए, Gemini का इस्तेमाल किया जा सकता है. इसके अलावा, पहले से तैयार किए गए इस वर्शन का इस्तेमाल किया जा सकता है:
Dockerfile
का नया वर्शन यहां उपलब्ध है.
अपने ऐप्लिकेशन को स्थानीय तौर पर टेस्ट करने के लिए, हमें config.php फ़ाइल को इस तरह बदलना होगा कि हमारा PHP ऐप्लिकेशन, Google CloudSQL पर उपलब्ध MYSQL डेटाबेस से कनेक्ट हो सके. आपने पहले जो सेट अप किया है उसके आधार पर, खाली जगहों को भरें:
<?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
, Cloud SQL का सार्वजनिक आईपी पता है. इसे SQL कंसोल में देखा जा सकता है:
DB_NAME
में कोई बदलाव नहीं होना चाहिए:image_catalog
DB_USER
की वैल्यूappmod-phpapp-user
होनी चाहिएDB_PASS
वह आइटम है जिसे आपने चुना है. इसे सिंगल कोट में सेट अप करें और ज़रूरत के हिसाब से इसे बाहर निकालें.
इसके अलावा, Gemini की मदद से, 🇮🇹 इटैलियन भाषा के कुछ वाक्यों को अंग्रेज़ी में अनुवाद करें!
ठीक है, अब आपके पास Dockerfile
है और आपने अपने डीबी से कनेक्ट करने के लिए, अपने PHP ऐप्लिकेशन को कॉन्फ़िगर कर लिया है. अब इसे आज़माते हैं!
अगर आपने अब तक docker इंस्टॉल नहीं किया है, तो इसे इंस्टॉल करें ( लिंक). Cloud Shell का इस्तेमाल करने पर, आपको इसकी ज़रूरत नहीं है.
अब, सही docker build और run निर्देशों की मदद से, अपने कंटेनर वाले PHP ऐप्लिकेशन को बनाने और चलाने की कोशिश करें.
# 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 पर झलक देखें (या किसी अन्य पोर्ट के लिए "पोर्ट बदलें")
अपने ब्राउज़र पर नतीजे की जांच करना
अब आपका ऐप्लिकेशन कुछ ऐसा दिखेगा:
अगर एडमिन/admin123 से लॉग इन किया जाता है, तो आपको कुछ ऐसा दिखेगा.
बहुत बढ़िया!!! इटैलियन टेक्स्ट के अलावा, यह सुविधा काम कर रही है! 🎉🎉🎉
अगर आपका डेटा कोड को डकराइज़ किया गया है, लेकिन डीबी क्रेडेंशियल गलत हैं, तो आपको कुछ ऐसा दिख सकता है:
फिर से कोशिश करें, आप काफ़ी करीब पहुंच गए हैं!
Artifact Registry में सेव करना [ज़रूरी नहीं]
अब तक, आपके पास कंटेनर में मौजूद PHP ऐप्लिकेशन होना चाहिए, जो क्लाउड पर डिप्लॉय करने के लिए तैयार हो. इसके बाद, हमें क्लाउड में अपनी Docker इमेज को सेव करने के लिए जगह चाहिए. साथ ही, हमें इसे Cloud Run जैसी Google Cloud की सेवाओं पर डिप्लॉय करने के लिए ऐक्सेस करने की ज़रूरत है. स्टोरेज के इस समाधान को आर्टफ़ैक्ट रजिस्ट्री कहा जाता है. यह Google Cloud की एक पूरी तरह से मैनेज की जाने वाली सेवा है. इसे ऐप्लिकेशन आर्टफ़ैक्ट को स्टोर करने के लिए डिज़ाइन किया गया है. इसमें Docker कंटेनर इमेज, Maven पैकेज, npm मॉड्यूल वगैरह शामिल हैं.
आइए, सही बटन का इस्तेमाल करके Google Cloud Artifact Registry में एक रिपॉज़िटरी बनाएं.
आर्टफ़ैक्ट को स्टोर करने के लिए, कोई मान्य नाम, फ़ॉर्मैट, और क्षेत्र चुनें.
अपने स्थानीय डेवलपमेंट एनवायरमेंट टैग पर वापस जाएं और ऐप्लिकेशन कंटेनर इमेज को, अभी बनाए गए आर्टफ़ैक्ट रजिस्ट्री रिपॉज़िटरी में पुश करें. ऐसा करने के लिए, नीचे दिए गए निर्देशों का पालन करें.
- docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
- docker push TARGET_IMAGE[:TAG]
नतीजा, नीचे दिए गए स्क्रीनशॉट जैसा दिखेगा.
वाह 🎉🎉🎉 अब आपके पास अगले लेवल पर जाने का विकल्प है. इससे पहले, दो मिनट अपलोड/लॉगिन/लॉग आउट करने की कोशिश करें और ऐप्लिकेशन के एंडपॉइंट के बारे में जानें.आपको बाद में इनकी ज़रूरत पड़ेगी.
संभावित गड़बड़ियां
अगर आपको कंटेनर से जुड़ी गड़बड़ियां मिलती हैं, तो गड़बड़ी की जानकारी देने और उसे ठीक करने के लिए Gemini का इस्तेमाल करें. इसके लिए, यह जानकारी दें:
- आपका मौजूदा Dockerfile
- मिली गड़बड़ी
- [अगर ज़रूरी हो] चलाया जा रहा PHP कोड.
अपलोड करने की अनुमतियां. /upload.php
एंडपॉइंट को भी आज़माएं और कोई इमेज अपलोड करें. आपको गड़बड़ी का यह मैसेज दिख सकता है. अगर ऐसा है, तो आपको chmod/chown
में Dockerfile
को ठीक करना होगा.
चेतावनी: move_uploaded_file(uploads/image (3).png): स्ट्रीम को खोलने में गड़बड़ी हुई: /var/www/html/upload.php में लाइन 11 पर अनुमति नहीं दी गई
PDOException "could not find driver" (या "Errore di connessione: could not find driver"). पक्का करें कि आपकी Dockerfile में, डीबी से कनेक्ट करने के लिए, mysql (pdo_mysql
) के लिए सही PDO लाइब्रेरी मौजूद हों. यहां दिए गए समाधानों से प्रेरणा पाएं.
आपके अनुरोध को बैकएंड पर फ़ॉरवर्ड नहीं किया जा सका. पोर्ट 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 पर डिप्लॉय करना
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 पर डिप्लॉय करने के लिए, सब कुछ तैयार है.
gcloud की मदद से, अपने ऐप्लिकेशन को Cloud Run पर डिप्लॉय करना
gcloud run deploy
कमांड की मदद से, Cloud Run पर ऐप्लिकेशन को डिप्लॉय किया जा सकता है. अपने लक्ष्य को हासिल करने के लिए, सेट करने के कई विकल्प हैं. कम से कम ये विकल्प देने होंगे. इन्हें कमांड-लाइन से दिया जा सकता है या टूल आपसे इंटरैक्टिव प्रॉम्प्ट के ज़रिए पूछेगा:
- Cloud Run सेवा का नाम, जिसे आपको अपने ऐप्लिकेशन के लिए डिप्लॉय करना है. Cloud Run सेवा आपको एक यूआरएल देगी, जो आपके ऐप्लिकेशन के लिए एंडपॉइंट उपलब्ध कराती है.
- Google Cloud का वह क्षेत्र जहां आपका ऐप्लिकेशन चलेगा. (
--region
REGION) - आपके ऐप्लिकेशन को रैप करने वाली कंटेनर इमेज.
- एनवायरमेंट वैरिएबल, जिनका इस्तेमाल आपके ऐप्लिकेशन को प्रोसेस के दौरान करना होता है.
- Allow-Unauthenticated flag, जो बिना पुष्टि के सभी को आपके ऐप्लिकेशन को ऐक्सेस करने की अनुमति देता है.
अपनी कमांड लाइन पर इस विकल्प को लागू करने का तरीका जानने के लिए, दस्तावेज़ देखें या संभावित समाधान के लिए नीचे की ओर स्क्रोल करें.
डिप्लॉयमेंट में कुछ मिनट लगेंगे. अगर सब कुछ सही है, तो आपको Google Cloud Console में कुछ ऐसा दिखेगा.
Cloud Run से मिले यूआरएल पर क्लिक करें और अपने ऐप्लिकेशन की जांच करें. पुष्टि हो जाने के बाद, आपको कुछ ऐसा दिखेगा.
बिना किसी आर्ग्युमेंट के"gcloud run deploy"
आपने देखा होगा कि gcloud run deploy
आपसे सही सवाल पूछता है और खाली जगहों को भरता है. यह शानदार है!
हालांकि, हम कुछ मॉड्यूल में इस कमांड को Cloud Build ट्रिगर में जोड़ने जा रहे हैं, ताकि हम इंटरैक्टिव सवालों का जवाब न दे पाएं. हमें कमांड में हर विकल्प भरना होगा. मान लें कि आपको गोल्डन gcloud run deploy --option1 blah --foo bar --region your-fav-region
बनाना है. आप इसे कैसे करते हैं?
- जब तक gcloud सवाल पूछना बंद न कर दे, तब तक दूसरे से लेकर चौथे चरण तक दोहराएं:
- [LOOP] अब तक मिले विकल्पों के साथ
gcloud run deploy
- [LOOP] सिस्टम, विकल्प X के लिए पूछते हैं
- [LOOP] सार्वजनिक दस्तावेज़ों में, CLI से X को सेट अप करने का तरीका खोजें. इसके लिए,
--my-option [my-value]
विकल्प जोड़ें. - अगर gcloud बिना किसी और सवाल के पूरा हो जाता है, तो दूसरे चरण पर वापस जाएं.
- gcloud run deploy BLAH BLAH BLAH rocks! इस निर्देश को कहीं सेव करें, क्योंकि आपको बाद में Cloud Build के चरण के लिए इसकी ज़रूरत पड़ेगी!
इस समस्या को हल करने का तरीका यहां बताया गया है. दस्तावेज़ यहां मौजूद हैं.
वाह 🎉🎉🎉 आपने Google Cloud में अपना ऐप्लिकेशन डिप्लॉय कर लिया है. इससे, ऐप्लिकेशन को आधुनिक बनाने का पहला चरण पूरा हो गया है.
6. मॉड्यूल 4: Secret Manager की मदद से पासवर्ड मिटाना
पिछले चरण में, हमने Cloud Run में अपना ऐप्लिकेशन डिप्लॉय और चलाया था. हालांकि, हमने ऐसा सुरक्षा से जुड़े गलत तरीके से किया: कुछ गोपनीय जानकारी को साफ़ तौर पर उपलब्ध कराना.
पहला चरण: ENV का इस्तेमाल करने के लिए, config.php को अपडेट करें
आपको पता चल गया होगा कि हमने डीबी पासवर्ड को सीधे config.php फ़ाइल के कोड में डाला है. टेस्टिंग के लिए और यह देखने के लिए कि ऐप्लिकेशन काम करता है या नहीं, यह ठीक है. हालांकि, प्रोडक्शन एनवायरमेंट में कोड को इस तरह से इस्तेमाल या कमिट नहीं किया जा सकता. पासवर्ड (और डीबी कनेक्शन के अन्य पैरामीटर) को डाइनैमिक तौर पर पढ़ा जाना चाहिए और रनटाइम के दौरान ऐप्लिकेशन को दिया जाना चाहिए. config.php फ़ाइल में बदलाव करें, ताकि वह ENV वैरिएबल से db पैरामीटर पढ़ सके. अगर ऐसा नहीं होता है, तो आपको डिफ़ॉल्ट वैल्यू सेट करनी चाहिए. अगर 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();
?>
आपका ऐप्लिकेशन कंटेनर में है, इसलिए आपको ऐप्लिकेशन में ENV वैरिएबल की वैल्यू देने का तरीका बताना होगा. ऐसा कुछ तरीकों से किया जा सकता है:
- Dockerfile पर, बिल्ड के समय. ENV DB_VAR=ENV_VAR_VALUE सिंटैक्स का इस्तेमाल करके, अपनी पिछली Dockerfile में चार पैरामीटर जोड़ें. इससे डिफ़ॉल्ट वैल्यू सेट हो जाएंगी. इन्हें रनटाइम के दौरान बदला जा सकता है. उदाहरण के लिए, ‘DB_NAME' और ‘DB_USER' को सिर्फ़ यहां सेट किया जा सकता है, कहीं और नहीं.
- रन के समय. Cloud Run के लिए ये वैरिएबल सेट अप किए जा सकते हैं. इसके लिए, सीएलआई या यूज़र इंटरफ़ेस, दोनों का इस्तेमाल किया जा सकता है. अपने चारों वैरिएबल डालने के लिए यह सही जगह है. हालांकि, अगर आपको Dockerfile में सेट किए गए डिफ़ॉल्ट वैल्यू को ही रखना है, तो ऐसा न करें.
हो सकता है कि आप localhost में, अपने ENV वैरिएबल को .env
फ़ाइल में डालना चाहें. इसके लिए, सलूशन फ़ोल्डर देखें.
यह भी पक्का करें कि .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 पर जाएं
- अपने ऐप्लिकेशन पर क्लिक करें
- "बदलाव करें और नया रिविज़न डिप्लॉय करें" पर क्लिक करें
- पहले टैब "कंटेनर" पर, नीचे मौजूद टैब "वैरिएबल और सीक्रेट" पर क्लिक करें
- "+ वैरिएबल जोड़ें" पर क्लिक करें और ज़रूरी सभी वैरिएबल जोड़ें. आपको कुछ ऐसा दिखेगा:
क्या यह सही है? नहीं. ज़्यादातर ऑपरेटर को अब भी आपका पास दिखेगा. Google Cloud Secret Manager की मदद से, इस समस्या को कम किया जा सकता है.
दूसरा चरण: Secret Manager
आपके पासवर्ड आपके कोड से हट गए हैं: जीत! लेकिन रुकिए - क्या हम अब भी सुरक्षित हैं?
आपके पासवर्ड अब भी उन सभी लोगों को दिखेंगे जिनके पास Google Cloud Console का ऐक्सेस है. असल में, Cloud Run की YAML डिप्लॉयमेंट फ़ाइल को ऐक्सेस करके, उसे वापस पाया जा सकता है. इसके अलावा, अगर Cloud Run के किसी नए वर्शन में बदलाव करने या उसे डिप्लॉय करने की कोशिश की जाती है, तो पासवर्ड 'वैरिएबल और सीक्रेट' सेक्शन में दिखता है. इसकी जानकारी, यहां दिए गए स्क्रीनशॉट में दी गई है.
Google Cloud Secret Manager, एपीआई पासकोड, पासवर्ड, सर्टिफ़िकेट, और अन्य गोपनीय जानकारी को मैनेज करने के लिए, सुरक्षित और एक ही जगह पर मौजूद सेवा है.
इसकी मदद से, गोपनीय जानकारी को सेव, मैनेज, और ऐक्सेस किया जा सकता है. इसके लिए, आपको अलग-अलग अनुमतियां देनी होती हैं और एन्क्रिप्शन (सुरक्षित) की बेहतर सुविधा का इस्तेमाल करना होता है. Secret Manager, Google Cloud के आइडेंटिटी और ऐक्सेस मैनेजमेंट (IAM) के साथ इंटिग्रेट है. इसकी मदद से, यह कंट्रोल किया जा सकता है कि कौनसे खास सीक्रेट ऐक्सेस किए जा सकते हैं. इससे डेटा की सुरक्षा और नियमों का पालन करने में मदद मिलती है.
यह अपने-आप सीक्रेट रोटेशन और वर्शन बनाने की सुविधा भी देता है. इससे, सीक्रेट के लाइफ़साइकल को मैनेज करना आसान हो जाता है. साथ ही, Google Cloud की सभी सेवाओं में मौजूद ऐप्लिकेशन की सुरक्षा को बेहतर बनाया जा सकता है.
Secret Manager को ऐक्सेस करने के लिए, हैम्बर्गर मेन्यू से सुरक्षा सेवाओं पर जाएं. इसके बाद, इसे डेटा की सुरक्षा सेक्शन में ढूंढें, जैसा कि नीचे दिए गए स्क्रीनशॉट में दिखाया गया है.
वहां पहुंचने के बाद, नीचे दी गई इमेज के मुताबिक Secret Manager API को चालू करें.
- अब "सीक्रेट बनाएं" पर क्लिक करें: इसे सही तरीके से बनाएं:
- नाम:
php-amarcord-db-pass
- सीक्रेट वैल्यू: ‘आपका डीबी पासवर्ड' ("फ़ाइल अपलोड करें" वाले हिस्से को अनदेखा करें).
- इस सीक्रेट लिंक पर एनोटेट करें, यह
projects/123456789012/secrets/php-amarcord-db-pass
जैसा दिखना चाहिए. यह आपके पासवर्ड का यूनीक पॉइंटर है. यह Terraform, Cloud Run वगैरह के लिए होता है. यह नंबर आपके प्रोजेक्ट का यूनीक नंबर होता है.
सलाह: अपने पासवर्ड के लिए, नाम रखने के एक ही तरीके का इस्तेमाल करें. जैसे, बाएं से दाएं की ओर लिखें: cloud-devrel-phpamarcord-dbpass
- संगठन (कंपनी के साथ)
- टीम (संगठन में)
- ऐप्लिकेशन (टीम में)
- वैरिएबल का नाम (ऐप्लिकेशन में)
इससे, आपको किसी एक ऐप्लिकेशन के लिए अपने सभी पासवर्ड ढूंढने के लिए, आसान रेगुलर एक्सप्रेशन मिलेंगे.
Cloud Run का नया रिविज़न बनाना
अब हमारे पास एक नया सीक्रेट है. इसलिए, हमें DB_PASS ENV वैरिएबल को हटाकर, उसे नए सीक्रेट से बदलना होगा. इसलिए:
- Google Cloud Console का इस्तेमाल करके, Cloud Run को ऐक्सेस करना
- ऐप्लिकेशन चुनें.
- "बदलाव करें और नया रिविज़न डिप्लॉय करें" पर क्लिक करें
- "वैरिएबल और सीक्रेट" टैब ढूंढें.
- DB_PASS ENV वैरिएबल को रीसेट करने के लिए, "+ किसी सीक्रेट का रेफ़रंस दें" बटन का इस्तेमाल करें.
- रेफ़रंस में दिए गए पासवर्ड के लिए, एक ही "DB_PASS" का इस्तेमाल करें और नए वर्शन का इस्तेमाल करें.
ऐसा करने के बाद, आपको गड़बड़ी का यह मैसेज दिखेगा
इसे ठीक करने का तरीका जानें. इसे ठीक करने के लिए, आपको IAM और एडमिन सेक्शन को ऐक्सेस करना होगा और अनुमतियां देने की सेटिंग में बदलाव करना होगा. डीबग करने के लिए शुभकामनाएं!
समस्या का पता चलने के बाद, Cloud Run पर वापस जाएं और नया रिविज़न फिर से डिप्लॉय करें. नतीजा, इस इमेज में दिखाए गए नतीजे जैसा दिखेगा:
सलाह: डेवलपर कंसोल (यूज़र इंटरफ़ेस) में, अनुमति से जुड़ी समस्याओं के बारे में पता चलता है. अपनी Cloud इकाइयों के सभी लिंक पर जाने के लिए समय निकालें!
7. मॉड्यूल 5: Cloud Build की मदद से अपना सीआई/सीडी सेटअप करना
सीआई/सीडी पाइपलाइन क्यों?
अब तक, आपने gcloud run deploy
को कुछ बार टाइप किया होगा. हो सकता है कि आपने एक ही सवाल का बार-बार जवाब दिया हो.
क्या आपको gcloud run deploy की मदद से, अपने ऐप्लिकेशन को मैन्युअल तरीके से डिप्लॉय करने में परेशानी हो रही है? क्या यह अच्छा नहीं होगा कि जब भी Git रिपॉज़िटरी में कोई नया बदलाव किया जाए, तो आपका ऐप्लिकेशन अपने-आप डिप्लॉय हो जाए?
सीआई/सीडी पाइपलाइन का इस्तेमाल करने के लिए, आपको इन दो चीज़ों की ज़रूरत होगी:
- निजी Git रिपॉज़िटरी: अच्छी बात यह है कि आपने दूसरे चरण में, वर्कशॉप रिपॉज़िटरी को अपने GitHub खाते में पहले ही फ़ॉर्क कर लिया होगा. अगर ऐसा नहीं है, तो वापस जाएं और वह चरण पूरा करें. फ़ोक्ड किया गया आपका रिपॉज़िटरी ऐसा दिखेगा:
https://github.com/<YOUR_GITHUB_USER>/app-mod-workshop
- Cloud Build. इस बेहतरीन और कम कीमत वाली सेवा की मदद से, Terraform, Dockerized ऐप्लिकेशन वगैरह के लिए, बिल्ड ऑटोमेशन कॉन्फ़िगर किए जा सकते हैं.
इस सेक्शन में, Cloud Build को सेट अप करने के बारे में बताया गया है.
Cloud Build का इस्तेमाल शुरू करें!
इसके लिए, हम Cloud Build का इस्तेमाल करेंगे:
- अपना सोर्स (Dockerfile की मदद से) बनाएं. इसे "बड़ी .zip फ़ाइल" के तौर पर देखें. इसमें, इसे बनाने और चलाने के लिए ज़रूरी सभी चीज़ें होती हैं. इसे "बिल्ड आर्टफ़ैक्ट" भी कहा जाता है.
- इस आर्टफ़ैक्ट को Artifact Registry (AR) में पुश करें.
- इसके बाद, "php-amarcord" ऐप्लिकेशन के लिए, AR से Cloud Run पर डिप्लॉयमेंट करें
- इससे मौजूदा ऐप्लिकेशन का नया वर्शन ("बदलाव") बन जाएगा. इसे नए कोड वाली लेयर के तौर पर देखें. अगर पुश पूरा हो जाता है, तो हम इसे ट्रैफ़िक को नए वर्शन पर भेजने के लिए कॉन्फ़िगर कर देंगे.
यहां मेरे php-amarcord
ऐप्लिकेशन के कुछ बिल्ड के उदाहरण दिए गए हैं:
हम यह सब कैसे करते हैं?
- एक बेहतरीन YAML फ़ाइल बनाकर:
cloudbuild.yaml
- Cloud Build ट्रिगर बनाकर.
- Cloud Build यूज़र इंटरफ़ेस (यूआई) की मदद से, हमारे GitHub डेटा स्टोर करने की जगह से कनेक्ट करके.
ट्रिगर बनाना (और कलेक्शन कनेक्ट करना)
- https://console.cloud.google.com/cloud-build/triggers पर जाएं
- "ट्रिगर बनाएं" पर क्लिक करें.
- कंपाइल करें:
- नाम:
on-git-commit-build-php-app
जैसा कोई काम का नाम - इवेंट: शाखा पर पुश करना
- सोर्स: "नया रिपॉज़िटरी कनेक्ट करें"
- इससे दाईं ओर एक विंडो खुलेगी: "रिपॉज़िटरी कनेक्ट करें"
- सोर्स उपलब्ध कराने वाली कंपनी: "GitHub" (पहला)
- "जारी रखें"
- पुष्टि करने के लिए, GitHub पर एक विंडो खुलेगी. निर्देशों का पालन करें और धैर्य बनाए रखें. अगर आपके पास कई रिपॉज़िटरी हैं, तो आपको कुछ समय लग सकता है.
- "रिपो चुनें" अपना खाता/रिपो चुनें और "मुझे समझ आ गया है..." वाले हिस्से पर सही का निशान लगाएं.
- अगर आपको गड़बड़ी का यह मैसेज मिलता है: GitHub ऐप्लिकेशन आपके किसी भी रिपॉज़िटरी पर इंस्टॉल नहीं है, तो "Google Cloud Build इंस्टॉल करें" पर क्लिक करके निर्देशों का पालन करें.
'कनेक्ट करें' पर क्लिक करें
- बिंगो! आपका रिपॉज़िटरी अब कनेक्ट हो गया है.
- ट्रिगर वाले हिस्से पर वापस जाएं....
- कॉन्फ़िगरेशन: अपने-आप पहचानी गई भाषा (*)
- बेहतर: सेवा खाता "[PROJECT_NUMBER]- compute@developer.gserviceaccount.com" चुनें
- xxxxx आपका प्रोजेक्ट आईडी है
- डिफ़ॉल्ट कंप्यूट सेवा खाता, लैब के लिए सही है - इसका इस्तेमाल प्रोडक्शन में न करें! ( ज़्यादा जानें).
- बाकी सभी चीज़ों को पहले जैसा ही रहने दें.
- "बनाएं" बटन पर क्लिक करें.
(*) यह सबसे आसान तरीका है, क्योंकि यह Dockerfile या cloudbuild.yaml की जांच करता है. हालांकि, cloudbuild.yaml
की मदद से यह तय किया जा सकता है कि किस चरण में क्या करना है.
मेरे पास अधिकार है!
अब, ट्रिगर तब तक काम नहीं करेगा, जब तक Cloud Build के सेवा खाते की जानकारी नहीं दी जाती. सेवा खाता क्या है? किसी "रोबोट" का ईमेल पता, जो किसी टास्क के लिए आपकी ओर से काम करता है - इस मामले में, Cloud में कॉन्टेंट बनाना!
जब तक आपके एसए को यह अधिकार नहीं दिया जाता, तब तक वह मॉडल को न तो बनाएगा और न ही डिप्लॉय कर पाएगा. अच्छी बात यह है कि यह आसान है!
- "Cloud Build" > " सेटिंग" पर जाएं.
- "[PROJECT_NUMBER]- compute@developer.gserviceaccount.com" सेवा खाता
- इन बॉक्स पर सही का निशान लगाएं:
- Cloud Run
- Secret Manager
- सेवा खाते
- Cloud Build
- "पसंदीदा सेवा खाते के तौर पर सेट करें" पर भी सही का निशान लगाएं
Cloud Build YAML फ़ाइल कहां है?
हमारा सुझाव है कि आप कुछ समय निकालकर, अपना क्लाउड बिल्ड YAML बनाएं.
हालांकि, अगर आपके पास समय नहीं है या आपको समय नहीं निकालना है, तो समस्या हल करने के लिए इस फ़ोल्डर में कुछ आइडिया देखें: .solutions
अब GitHub पर बदलाव को पुश किया जा सकता है और Cloud Build को उसके हिस्से के तौर पर देखा जा सकता है.
Cloud Build को सेट अप करना मुश्किल हो सकता है. इनके बीच कुछ समय लग सकता है:
- https://console.cloud.google.com/cloud-build/builds;region=global में लॉग देखना
- गड़बड़ी का पता लगाना.
- कोड में गड़बड़ी को ठीक करना और git commit / git push को फिर से जारी करना.
- कभी-कभी गड़बड़ी कोड में नहीं, बल्कि किसी कॉन्फ़िगरेशन में होती है. ऐसे में, यूज़र इंटरफ़ेस (cloud build > "Triggers" > Run) से नया बिल्ड जारी किया जा सकता है
ध्यान दें कि इस तरीके का इस्तेमाल करने के बाद भी, आपको कुछ काम करने होंगे. उदाहरण के लिए, आपको नए बनाए गए dev/prod एंडपॉइंट के लिए ENV वैरिएबल सेट करने होंगे:
आप इसे दो तरीकों से कर सकते हैं:
- यूज़र इंटरफ़ेस की मदद से - ENV वैरिएबल को फिर से सेट करके
- CLI की मदद से, अपने हिसाब से "सबसे सही" स्क्रिप्ट बनाकर. इसका एक उदाहरण यहां दिया गया है: gcloud-run-deploy.sh . आपको कुछ चीज़ों में बदलाव करना होगा. जैसे, एंडपॉइंट और प्रोजेक्ट नंबर. आपको अपना प्रोजेक्ट नंबर, Cloud की खास जानकारी में दिखेगा.
मैं GitHub पर कोड को कैसे कमिट करूं?
इस वर्कशॉप में, git push
को GitHub पर अपलोड करने का सबसे अच्छा तरीका नहीं बताया गया है. हालांकि, अगर आप Cloud Shell में हैं और आपको कोई समस्या आ रही है, तो इसे दो तरीकों से ठीक किया जा सकता है:
- CLI. स्थानीय तौर पर एक एसएसएच पासकोड जोड़ें और git@github.com:YOUR_USER/app-mod-workshop.git (http के बजाय) के साथ एक रिमोट जोड़ें
- VSCode. अगर Cloud Shell एडिटर का इस्तेमाल किया जा रहा है, तो सोर्स कंट्रोल (ctrl-shift-G) टैब का इस्तेमाल करें. इसके बाद, "बदलाव सिंक करें" पर क्लिक करें और निर्देशों का पालन करें. इसके बाद, vscode में अपने GitHub खाते की पुष्टि की जा सकती है. इसके बाद, वहां से आसानी से डेटा खींचा और डाला जा सकता है.
अन्य फ़ाइलों के साथ git add clodubuild.yaml
को भी git add clodubuild.yaml
करना न भूलें, वरना यह काम नहीं करेगा.
डीप बनाम शैलो "dev/prod parity" [ज़रूरी नहीं]
अगर आपने यहां से मॉडल वर्शन कॉपी किया है, तो आपके पास एक जैसे दो DEV और PROD वर्शन होंगे. यह तरीका अच्छा है और The Twelve-Factor App के नियम 10 के मुताबिक है.
हालांकि, हम एक ही डेटाबेस पर काम करने वाले ऐप्लिकेशन के लिए, दो अलग-अलग वेब एंडपॉइंट का इस्तेमाल कर रहे हैं. यह वर्कशॉप के लिए काफ़ी है. हालांकि, असल ज़िंदगी में, आपको सही प्रोडक्शन एनवायरमेंट बनाने के लिए कुछ समय देना होगा. इसका मतलब है कि आपके पास दो डेटाबेस (एक डेवलपमेंट के लिए और एक प्रोडक्शन के लिए) होने चाहिए. साथ ही, आपके पास यह चुनने का विकल्प भी होना चाहिए कि आपातकालीन स्थिति में डेटा को वापस लाने / ज़्यादा उपलब्धता के लिए, उन्हें कहां रखना है. यह इस वर्कशॉप के दायरे से बाहर की बात है, लेकिन इस पर विचार किया जा सकता है.
अगर आपके पास वीडियो के "डीप" वर्शन को बनाने का समय है, तो कृपया उन सभी रिसॉर्स को ध्यान में रखें जिन्हें आपको डुप्लीकेट करना है. जैसे:
- Cloud SQL डेटाबेस (और शायद SQL इंस्टेंस).
- GCS बकेट
- Cloud फ़ंक्शन.
- डेवलपमेंट में, Gemini 1.5 Flash मॉडल का इस्तेमाल किया जा सकता है. यह मॉडल सस्ता और तेज़ है. इसके अलावा, Gemini 1.5 Pro मॉडल का इस्तेमाल भी किया जा सकता है. यह मॉडल ज़्यादा बेहतर है.
आम तौर पर, जब भी ऐप्लिकेशन के लिए कोई बदलाव किया जाता है, तो इस बात का ध्यान रखें कि क्या प्रोडक्शन में भी यह वैल्यू होनी चाहिए या नहीं? अगर ऐसा नहीं होता है, तो फिर से कोशिश करें. Terraform की मदद से, यह काम बहुत आसानी से किया जा सकता है. इसमें, अपने संसाधनों के सफ़िक्स के तौर पर अपने एनवायरमेंट (-dev, -prod) को इंजेक्ट किया जा सकता है.
8. मॉड्यूल 6: Google Cloud Storage पर माइग्रेट करना
डिवाइस का स्टोरेज
फ़िलहाल, ऐप्लिकेशन ने स्टेटस को एक डॉकर कंटेनर में सेव किया है. अगर मशीन खराब हो जाती है, ऐप्लिकेशन में कोई गड़बड़ी आ जाती है या नया रिविज़न पॉइंट जोड़ा जाता है, तो नया रिविज़न शेड्यूल किया जाएगा. इसमें नया और खाली स्टोरेज होगा: 🙈
हम इसे कैसे ठीक करें? इसके कई तरीके हैं.
- इमेज को डीबी में सेव करें. मैंने अपने पिछले PHP ऐप्लिकेशन में ऐसा ही किया था. यह सबसे आसान तरीका है, क्योंकि इसमें कोई जटिलता नहीं होती. हालांकि, इससे आपके डीबी में इंतज़ार का समय और लोड बढ़ता है!
- क्या आपको अपने Cloud Run ऐप्लिकेशन को स्टोरेज के हिसाब से बेहतर समाधान पर माइग्रेट करना है: GCE + परसिस्टेंट डिस्क? क्या GKE + स्टोरेज का इस्तेमाल किया जा सकता है? ध्यान दें: कंट्रोल जितना ज़्यादा होगा, फ़्लैक्सिबिलिटी उतनी ही कम होगी.
- GCS पर ले जाएं. Google Cloud Storage, Google Cloud के लिए सबसे अच्छा स्टोरेज उपलब्ध कराता है. साथ ही, यह क्लाउड के लिए सबसे सही सलूशन है. हालांकि, इसके लिए हमें PHP लाइब्रेरी का इस्तेमाल करना होगा. क्या हमारे पास जीसीएस के लिए PHP 5.7 लाइब्रेरी हैं? क्या
PHP 5.7
,Composer
के साथ काम करता है (ऐसा लगता है कि PHP 5.3.2, Composer के साथ काम करने वाला सबसे पुराना वर्शन है)? - क्या docker sidecar का इस्तेमाल किया जा सकता है?
- इसके अलावा, GCS Cloud Run वॉल्यूम माउंट का इस्तेमाल भी किया जा सकता है. यह शानदार है.
🤔 स्टोरेज को माइग्रेट करना (इस पर काम जारी है)
[खुली जगह] इस एक्सरसाइज़ में, हम चाहते हैं कि आप अपनी इमेज को किसी ऐसे तरीके से मूव करें जिससे वे किसी तरह से सेव रहें.
स्वीकार करने से जुड़ी जांच
मैं आपको इसका समाधान नहीं बताना चाहता, लेकिन मुझे यह करना है:
- आपने
newpic.jpg
अपलोड किया है. आपको यह ऐप्लिकेशन में दिखेगा. - ऐप्लिकेशन को नए वर्शन पर अपग्रेड किया जाता है.
newpic.jpg
अब भी मौजूद है और दिख रहा है.
💡 समस्या हल करने का संभावित तरीका (GCS Cloud Run वॉल्यूम माउंट)
यह एक बहुत ही बेहतरीन तरीका है. इससे हमें कोड में कोई बदलाव किए बिना, स्टेटफ़ुल फ़ाइल अपलोड करने की सुविधा मिलती है. हालांकि, इसमें इमेज की जानकारी दिखाने की सुविधा भी शामिल है, लेकिन यह सुविधा ज़रूरी नहीं है.
इससे, Cloud Run से GCS में फ़ोल्डर को माउंट किया जा सकता है. इसके लिए:
- GCS में अपलोड किए गए सभी आइटम, आपके ऐप्लिकेशन में दिखेंगे.
- आपके ऐप्लिकेशन में किए गए सभी अपलोड, असल में GCS पर अपलोड किए जाएंगे
- GCS (सातवां चैप्टर) में अपलोड किए गए ऑब्जेक्ट में जादू की तरह बदलाव होंगे.
ध्यान दें. कृपया FUSE के फ़ाइन प्रिंट को पढ़ें. अगर परफ़ॉर्मेंस में समस्या है, तो ऐसा करना ठीक नहीं है.
जीसीएस बकेट बनाना
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/"
/uploads/ फ़ोल्डर में बकेट को माउंट करने के लिए, Cloud Run को कॉन्फ़िगर करना
अब बात करते हैं सबसे अहम बात की. हम एक वॉल्यूम php_uploads
बनाते हैं और Cloud Run को MOUNT_PATH
(/var/www/html/uploads/
जैसा कुछ) पर FUSE माउंट करने का निर्देश देते हैं:
#!/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 पर ले जाना है.
यूज़र इंटरफ़ेस (यूआई) से भी ऐसा किया जा सकता है
- "वॉल्यूम" टैब में, अपनी बकेट पर ले जाने वाला वॉल्यूम माउंट बनाएं. यह "क्लाउड स्टोरेज बकेट" टाइप का होना चाहिए. उदाहरण के लिए, "php_uploads" नाम का वॉल्यूम माउंट.
- कंटेनर > वॉल्यूम माउंट में जाकर, अपने ऐप्लिकेशन के अनुरोध किए गए वॉल्यूम पॉइंट पर, हाल ही में बनाए गए वॉल्यूम को माउंट करें. यह dockerfile पर निर्भर करता है, लेकिन यह
var/www/html/uploads/
जैसा दिख सकता है .
दोनों ही मामलों में, अगर यह काम करता है, तो Cloud Run के नए वर्शन में बदलाव करने पर, आपको कुछ ऐसा दिखेगा:
अब /upload.php
एंडपॉइंट पर एक नई इमेज अपलोड करके, नए ऐप्लिकेशन की जांच करें.
इमेज, PHP की एक लाइन भी लिखे बिना GCS पर आसानी से फ़्लो होनी चाहिए:
अभी क्या हुआ?
कुछ बहुत ही जादुई हुआ है.
पुराने कोड वाला कोई पुराना ऐप्लिकेशन अब भी काम कर रहा है. नए और आधुनिक स्टैक की मदद से, हम अपने ऐप्लिकेशन में सभी इमेज/फ़ोटो को आसानी से स्टेटफ़ुल Cloud बकेट में सेव कर सकते हैं. अब आपके पास बहुत से विकल्प हैं:
- क्या आपको "खतरनाक" या "नग्न" इमेज मिलने पर हर बार ईमेल भेजना है? ऐसा PHP कोड में बदलाव किए बिना किया जा सकता है.
- क्या आपको हर बार किसी इमेज के बारे में बताने के लिए, Gemini के मल्टीमोडल मॉडल का इस्तेमाल करना है और उसके ब्यौरे के साथ डीबी अपलोड करना है? ऐसा PHP कोड में बदलाव किए बिना किया जा सकता है. क्या आपको मेरी बात पर भरोसा नहीं है? सातवें चैप्टर में पढ़ना जारी रखें.
हमने यहां एक बड़ा अवसर खोला है.
9. सातवां मॉड्यूल: Google Gemini की मदद से अपने ऐप्लिकेशन को बेहतर बनाना
अब आपके पास क्लाउड स्टोरेज के साथ, आधुनिक और बेहतर PHP ऐप्लिकेशन (जैसे कि 2024 Fiat 126
) है.
इसका इस्तेमाल कैसे किया जा सकता है?
ज़रूरी शर्तें
पिछले चैप्टर में, मॉडल समाधान की मदद से, हमने GCS पर इमेज /uploads/
माउंट की थीं. इससे, ऐप्लिकेशन लॉजिक को इमेज स्टोरेज से असल में अलग किया जा सका.
इस एक्सरसाइज़ के लिए, आपको:
- आपने छठे चैप्टर (स्टोरेज) में दिया गया अभ्यास पूरा कर लिया हो.
- आपके पास इमेज अपलोड करने के लिए GCS की एक बकेट होनी चाहिए. इसमें लोग आपके ऐप्लिकेशन पर फ़ोटो अपलोड करते हैं और वे आपकी बकेट में सेव हो जाती हैं.
Python में Cloud फ़ंक्शन सेट अप करना
क्या आपने कभी सोचा है कि इवेंट-ड्रिवन ऐप्लिकेशन को कैसे लागू किया जाए? कुछ इस तरह:
- जब <event> होता है => ईमेल भेजें
- जब <event> होता है => अगर <condition> सही है, तो डेटाबेस अपडेट करें.
इवेंट कुछ भी हो सकता है. जैसे, BigQuery में उपलब्ध नया रिकॉर्ड, GCS के किसी फ़ोल्डर में बदला गया नया ऑब्जेक्ट या Pub/Sub की सूची में इंतज़ार कर रहा नया मैसेज.
Google Cloud, इस लक्ष्य को हासिल करने के लिए कई पैराडाइम का इस्तेमाल करता है. खास तौर पर:
- EventArc. GCS इवेंट पाने का तरीका देखें. क्लाउड में, डीएजी बनाने और 'अगर-तो-अन्यथा' के आधार पर कार्रवाइयां करने के लिए शानदार.
- Cloud Scheduler. उदाहरण के लिए, क्लाउड में आधी रात को क्रॉन जॉब के लिए बेहतरीन.
- Cloud Workflows. इवेंट आर्क की तरह ही, इसकी मदद से ये काम किए जा सकते हैं
- Cloud Run फ़ंक्शन (जिन्हें आम तौर पर
lambdas
कहा जाता है). - Cloud Composer. यह Apache Airflow का Google वर्शन है. यह डीएजी के लिए भी बेहतरीन है.
इस एक्सरसाइज़ में, हम बेहतर नतीजे पाने के लिए Cloud Function के बारे में ज़्यादा जानेंगे. साथ ही, हम आपको कुछ एक्सरसाइज़ के विकल्प भी देंगे.
ध्यान दें कि सैंपल कोड .solutions/
में दिया गया है
Cloud फ़ंक्शन (🐍 Python) सेट अप करना
हम एक बेहतरीन GCF बनाने की कोशिश कर रहे हैं.
- जब GCS पर कोई नई इमेज बनाई जाती है, तो.. (ऐसा इसलिए हो सकता है, क्योंकि किसी व्यक्ति ने इसे ऐप्लिकेशन पर अपलोड किया हो - लेकिन ऐसा सिर्फ़ इस वजह से नहीं हो सकता)
- .. Gemini को कॉल करके, इमेज के बारे में जानकारी पाएं और टेक्स्ट में इमेज की जानकारी पाएं .. (MIME की जांच करके यह पक्का करना अच्छा होगा कि यह इमेज है, न कि PDF, MP3 या टेक्स्ट)
- .. और इस जानकारी के साथ डीबी अपडेट करें. (इसके लिए,
images
टेबल मेंdescription
कॉलम जोड़ने के लिए, डीबी में पैच करना पड़ सकता है).
description
इमेज में जोड़ने के लिए, डीबी में बदलाव करना
- Cloud SQL Studio खोलें:
- Images DB के लिए अपना उपयोगकर्ता नाम और पासवर्ड डालें
- इमेज के ब्यौरे के लिए कॉलम जोड़ने वाला यह SQL इंजेक्ट करें:
ALTER TABLE images ADD COLUMN description TEXT;
और बिंगो! अब देखें कि यह तरीका काम कर रहा है या नहीं:
SELECT * FROM images;
आपको ब्यौरा वाला नया कॉलम दिखेगा:
Gemini f(x) लिखें
ध्यान दें. इस फ़ंक्शन को Gemini Code Assist की मदद से बनाया गया था.
ध्यान दें. यह फ़ंक्शन बनाते समय, आपको IAM की अनुमति से जुड़ी गड़बड़ियां हो सकती हैं. इनमें से कुछ गड़बड़ियों के बारे में यहां "संभावित गड़बड़ियां" पैराग्राफ़ में बताया गया है.
- एपीआई चालू करना
- https://console.cloud.google.com/functions/list पर जाएं
- "फ़ंक्शन बनाएं" पर क्लिक करें
- एपीआई विज़र्ड से एपीआई चालू करना:
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. पक्का करें कि ENVs को सही वैल्यू के साथ सोर्स किया गया हो या उन्हें सबसे ऊपर जोड़ा गया हो (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
को भी देखना न भूलें.
E2E टेस्ट
अब फ़ंक्शन की मैन्युअल तौर पर जांच करने का समय आ गया है!
- अपने ऐप्लिकेशन पर जाएं और लॉग इन करें
- कोई फ़ोटो अपलोड करें. फ़ोटो का साइज़ बहुत बड़ा न हो. हमें बड़ी फ़ोटो से समस्याएं आती हैं
- यूज़र इंटरफ़ेस (यूआई) पर जाकर देखें कि फ़ोटो अपलोड हो गई है या नहीं.
- Cloud SQL Studio में जाकर देखें कि ब्यौरा अपडेट हो गया है या नहीं. लॉग इन करें और यह क्वेरी चलाएं:
SELECT * FROM images
.
और यह काम करता है! हम उस जानकारी को दिखाने के लिए, फ़्रंटएंड को भी अपडेट कर सकते हैं.
दिखाने के लिए PHP को अपडेट करना [ज़रूरी नहीं]
हमने यह साबित कर दिया है कि ऐप्लिकेशन काम करता है. हालांकि, यह अच्छा होगा कि उपयोगकर्ताओं को भी वह ब्यौरा दिखे.
index.php
में ब्यौरा जोड़ने के लिए, हमें 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 की मदद से यूज़र इंटरफ़ेस (यूआई) का बेहतर वर्शन भी दिखता है. बेहतर वर्शन कुछ ऐसा दिख सकता है:
निष्कर्ष
GCS में नए ऑब्जेक्ट के लैंड होने पर, आपके Cloud फ़ंक्शन को ट्रिगर किया गया है. यह फ़ंक्शन, इमेज के कॉन्टेंट पर एनोटेट कर सकता है, ठीक उसी तरह जैसे कोई इंसान कर सकता है. साथ ही, यह डीबी को अपने-आप अपडेट कर सकता है. वाह!
आगे क्या करना है? दो बेहतर सुविधाएं पाने के लिए, यही तरीका अपनाया जा सकता है.
[ज़रूरी नहीं] ज़्यादा 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 / अनुमतियां)
इस समाधान को डेवलप करते समय, मुझे IAM की अनुमति से जुड़ी कुछ समस्याएं मिलीं. हम इन समस्याओं को यहां जोड़ेंगे, ताकि हम इनके बारे में ज़्यादा जान सकें और उन्हें ठीक करने के कुछ आइडिया दे सकें.
गड़बड़ी: सेवा खाते के लिए ज़रूरी अनुमतियां नहीं हैं
- ध्यान दें कि GCS बकेट को सुनने वाले GCF फ़ंक्शन को डिप्लॉय करने के लिए, आपको उस सेवा खाते के लिए सही अनुमतियां सेट अप करनी होंगी जिसका इस्तेमाल इस काम के लिए किया जा रहा है. ऐसा करने के लिए, यह तरीका अपनाएं:
आपको EventArc API भी चालू करने पड़ सकते हैं. हालांकि, ये पूरी तरह से उपलब्ध होने में कुछ मिनट लग सकते हैं.
गड़बड़ी: Cloud Run का invoker मौजूद नहीं है
- GCF की अनुमति देने के लिए यूज़र इंटरफ़ेस से मिली एक और टिप्पणी यह है ( Cloud Run Invoker भूमिका):
इस गड़बड़ी को ठीक करने के लिए, इमेज में दिया गया निर्देश चलाएं. यह निर्देश, fix-permissions.sh जैसा ही है
इस समस्या के बारे में यहां बताया गया है: https://cloud.google.com/functions/docs/securing/authenticating
गड़बड़ी: मेमोरी की सीमा पार हो गई है
पहली बार इसे चलाने पर, मेरे लॉग में यह जानकारी दिखी: "244 एमबी की मेमोरी सीमा पार हो गई है. अब 270 एमबी का इस्तेमाल किया जा रहा है. मेमोरी की सीमा बढ़ाएं. इसके लिए, https://cloud.google.com/functions/docs/configuring/memory देखें'". फिर से, अपने GCF में रैम जोड़ें. यूज़र इंटरफ़ेस (यूआई) में ऐसा करना बहुत आसान है. यहां एक समस्या के बारे में बताया गया है:
इसके अलावा, रैम/सीपीयू बढ़ाने के लिए, Cloud Run की डिप्लॉयमेंट स्क्रिप्ट को भी ठीक किया जा सकता है. इसमें थोड़ा ज़्यादा समय लगता है.
गड़बड़ी: PubSub पब्लिश किया गया
GCF v1 की मदद से ट्रिगर बनाते समय, एक बार यह गड़बड़ी मिली:
इसे ठीक करने के लिए, IAM पर जाएं और अपने सेवा खाते को "Pub/Sub पब्लिशर" की भूमिका दें.
गड़बड़ी: Vertex AI का इस्तेमाल नहीं किया गया है
अगर आपको यह गड़बड़ी दिखती है, तो:
अनुमति नहीं दी गई: 403 Vertex AI API का इस्तेमाल, प्रोजेक्ट YOUR_PROJECT में पहले कभी नहीं किया गया है या इसे बंद कर दिया गया है. इसे चालू करने के लिए, https://console.developers.google.com/apis/api/aiplatform.googleapis.com/overview?project=YOR_PROJECT पर जाएं
आपको सिर्फ़ Vertex AI एपीआई चालू करने होंगे. ज़रूरी सभी एपीआई को चालू करने का सबसे आसान तरीका यह है:
- https://console.cloud.google.com/vertex-ai
- "सुझाए गए सभी एपीआई चालू करें" पर क्लिक करें.
गड़बड़ी: EventArc ट्रिगर नहीं मिला.
अगर आपको यह गड़बड़ी दिखती है, तो कृपया फ़ंक्शन को फिर से डिप्लॉय करें.
गड़बड़ी: 400 सर्विस एजेंट के लिए प्रोविज़न किया जा रहा है
400 सर्विस एजेंट प्रोवाइड किए जा रहे हैं ( https://cloud.google.com/vertex-ai/docs/general/access-control#service-agents ). दी गई Cloud Storage फ़ाइल को पढ़ने के लिए, सर्विस एजेंट ज़रूरी हैं. इसलिए, कृपया कुछ मिनट बाद फिर से कोशिश करें.
अगर ऐसा होता है, तो कुछ समय इंतज़ार करें या किसी Googler से पूछें.
10. मॉड्यूल 8: उपलब्धता के लिए एसएलओ बनाना
इस चैप्टर में, हमने इन चीज़ों को हासिल करने की कोशिश की है:
- एसएलआई बनाना
- एसएलआई के आधार पर एसएलओ बनाना
- एसएलओ के आधार पर सूचनाएं बनाना
यह लेखक के लिए काफ़ी अहम विषय है, क्योंकि Riccardo Google Cloud के एसआरई / डेवलपमेंट ऑपरेशंस (डीओपीएस) एरिया में काम करते हैं.
(खुला-खुला) इस ऐप्लिकेशन के लिए एसएलआई और एसएलओ बनाएं
अगर आपको यह पता नहीं चलता कि ऐप्लिकेशन कब काम नहीं कर रहा है, तो वह कितना अच्छा है?
एसएलओ क्या है?
ओह! एसएलओ का आविष्कार Google ने किया है! इस बारे में ज़्यादा जानने के लिए, हमारा सुझाव है कि आप:
- एसआरई बुक - दूसरा चैप्टर - एसएलओ लागू करना. ( 👉 SRE से जुड़ी ज़्यादा किताबें)
- एसएलओ की कला ( शानदार वीडियो). अपनी सेवा के लिए सही एसएलओ बनाने के तरीके के बारे में ज़्यादा जानने के लिए, यह एक बेहतरीन ट्रेनिंग है.
- Coursera पर एसआरई कोर्स. मैंने इसमें योगदान दिया है!
पहला चरण: उपलब्धता के लिए एसएलआई/एसएलओ बनाना
चलिए, उपलब्धता एसएलओ से शुरुआत करते हैं, क्योंकि यह मेज़र करने के लिए सबसे आसान और शायद सबसे ज़रूरी चीज़ है.
अच्छी बात यह है कि Istio की मदद से, Cloud Run में पहले से एसएलओ की सुविधा मौजूद होती है.
आपका ऐप्लिकेशन Cloud Run पर होने के बाद, यह काम करना बहुत आसान है. मुझे इसमें 30 सेकंड लगते हैं.
- अपने Cloud Run पेज पर जाएं.
- अपने ऐप्लिकेशन पर क्लिक करें या उसे चुनें.
SLOs
टैब चुनें.- "+ एसएलओ बनाएं" पर क्लिक करें.
- खरीदारी के लिए उपलब्धता, अनुरोध के आधार पर
- जारी रखें
- कैलेंडर का महीना / 99%.
- "एसएलओ बनाएं" पर क्लिक करें.
दूसरा चरण: इस एसएलओ के लिए सूचनाएं पाने की सुविधा सेट अप करना
हमारा सुझाव है कि आप दो सूचनाएं बनाएं:
- कम बर्नरेट वाला एक ("धीमा बर्न"), ताकि आपको ईमेल से सूचना दी जा सके (कम प्राथमिकता वाले टिकट की नकल करता है).
- एक ऐसा टिकट जिसका बर्न रेट ज़्यादा हो ("फ़ास्टबर्न"), ताकि आपको एसएमएस से सूचना दी जा सके (ज़्यादा प्राथमिकता वाले टिकट / पेजर की नकल करता है)
अपने पिछले SLO tab
पर जाएं.
ऐसा दो बार करें:
- "एसएलओ सूचना बनाएं" पर क्लिक करें (दाईं ओर, प्लस के साथ 🔔 बटन)
- लुकबैक पीरियड, खर्च की दर का थ्रेशोल्ड:
- [FAST]. पहला:
60
मिनट /10
x - [SLOW]. दूसरा:
720
मिनट /2
x - सूचना का चैनल: 'सूचना के चैनल मैनेज करें' पर क्लिक करें
- सबसे पहले, "ईमेल" -> नया जोड़ें -> ..
- दूसरा, "एसएमएस" -> नया जोड़ें -> फ़ोन पर पुष्टि करें.
- सलाह: मुझे नामों में इमोजी इस्तेमाल करना पसंद है! डेमो के लिए मज़ेदार है.
- इसके बाद, सबसे ऊपर दाईं ओर मौजूद बड़े 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
.
बिंगो!
आखिरी नतीजा
जब आपके पास एक काम करने वाला एसएलओ और उपलब्धता के लिए दो सूचनाएं होंगी, तब हम इस प्रोसेस को पूरा मान सकते हैं. साथ ही, यह भी ज़रूरी है कि ये सूचनाएं आपके ईमेल और फ़ोन पर भेजी जा रही हों.
अगर आप चाहें, तो देरी या इससे भी ज़्यादा मुश्किल कोई वैरिएबल जोड़ा जा सकता है. हमारा सुझाव है कि आप ऐसा करें. इंतज़ार के समय के लिए, अपनी पसंद के हिसाब से इंतज़ार का समय चुनें. अगर आपको नहीं पता कि कितना इंतज़ार का समय चुनना है, तो 200 मिलीसेकंड चुनें.
11. अगले चरण
आपने सभी चरणों को पूरा कर लिया है, लेकिन क्या कुछ छूट गया है?
कुछ बातें ध्यान में रखें:
Gemini के साथ खेलना
Gemini का इस्तेमाल दो तरीकों से किया जा सकता है:
- Vertex AI. "एंटरप्राइज़ का तरीका", जो आपके GCP के साथ जुड़ा हुआ है. हमने इस बारे में सातवें चैप्टर (GCF+Gemini) में बताया है. पुष्टि करने की प्रोसेस आसानी से काम करती है और सेवाएं एक-दूसरे से बेहतर तरीके से जुड़ी होती हैं.
- Google का एआई. "उपभोक्ता का तरीका". यहां से Gemini API पासकोड पाएं और छोटी-छोटी स्क्रिप्ट बनाएं. इन स्क्रिप्ट को आपके मौजूदा वर्कलोड (मालिकाना हक वाला काम, दूसरे क्लाउड, localhost वगैरह) से जोड़ा जा सकता है. इसके लिए, बस अपना एपीआई पासकोड डालें और कोड अपने-आप काम करने लगेगा.
हमारा सुझाव है कि आप अपने पसंदीदा प्रोजेक्ट के लिए, (2) को एक्सप्लोर करें.
यूज़र इंटरफ़ेस (यूआई) को बेहतर बनाना
मुझे यूज़र इंटरफ़ेस बनाने में कोई दिलचस्पी नहीं है. हालांकि, 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!]
इसे पांच मिनट से भी कम समय में आसानी से हासिल किया जा सकता है. इसके लिए, आपको सिर्फ़ एक Cloud Build की ज़रूरत होगी! :)
Gemini से मिला जवाब सही था (इसका मतलब है कि मुझे कुछ भी बदलने की ज़रूरत नहीं पड़ी):
यहां लेखक के निजी ऐप्लिकेशन में नया लेआउट दिख रहा है:
ध्यान दें: कोड को इमेज के तौर पर चिपकाया गया है, क्योंकि हम आपको कोड इस्तेमाल करने के लिए बढ़ावा नहीं देना चाहते. हम चाहते हैं कि आप अपने क्रिएटिव यूज़र इंटरफ़ेस (यूआई)/फ़्रंटएंड की सीमाओं के साथ, Gemini को आपके लिए कोड लिखने दें. भरोसा रखें, इसके बाद आपको बहुत कम बदलाव करने होंगे.
सुरक्षा
इस चार घंटे की वर्कशॉप का मकसद, इस ऐप्लिकेशन को सुरक्षित करना नहीं है. ऐसा करने पर, इस वर्कशॉप को पूरा करने में 1 से 2 गुना ज़्यादा समय लगेगा.
हालांकि, यह विषय बहुत ज़रूरी है! हमने SECURITY
में कुछ आइडिया इकट्ठा किए हैं.
12. बधाई हो!
बधाई हो 🎉🎉🎉 , आपने Google Cloud की मदद से अपने लेगसी PHP ऐप्लिकेशन को आधुनिक बना दिया है.
इस कोडलैब में, आपको ये चीज़ें सीखने को मिली हैं:
- Google Cloud SQL में डेटाबेस को डिप्लॉय करने और अपने मौजूदा डेटाबेस को इसमें माइग्रेट करने का तरीका.
- Docker और Buildpack की मदद से, अपने PHP ऐप्लिकेशन को कंटेनर में कैसे डालें और उसकी इमेज को Google Cloud Artifact Registry में कैसे सेव करें
- कंटेनर में मौजूद अपने ऐप्लिकेशन को Cloud Run पर डिप्लॉय करने और उसे Cloud SQL के साथ चलाने का तरीका
- Google Secret Manager का इस्तेमाल करके, संवेदनशील कॉन्फ़िगरेशन पैरामीटर (जैसे, डीबी पासवर्ड) को गुप्त रूप से सेव/इस्तेमाल करने का तरीका
- Google Cloud Build की मदद से, सीआई/सीडी पाइपलाइन को सेट अप करने का तरीका. इससे, GitHub डेटा स्टोर करने की जगह में किसी भी कोड को पुश करने पर, आपका PHP ऐप्लिकेशन अपने-आप बन जाएगा और डिप्लॉय हो जाएगा.
- अपने ऐप्लिकेशन के संसाधनों को "क्लाउड पर ले जाने" के लिए, Cloud Storage का इस्तेमाल करने का तरीका
- अपने ऐप्लिकेशन के कोड में बदलाव किए बिना, Google Cloud पर बेहतरीन वर्कफ़्लो बनाने के लिए, सर्वरलेस टेक्नोलॉजी का फ़ायदा पाने का तरीका.
- अपने काम के हिसाब से, Gemini की मल्टीमोडल सुविधाओं का इस्तेमाल करें.
- Google Cloud में एसआरई के सिद्धांतों को लागू करना
Google Cloud की मदद से, ऐप्लिकेशन को आधुनिक बनाने की प्रोसेस शुरू करने के लिए, यह एक बेहतरीन शुरुआत है!
🔁 सुझाव, राय या शिकायत
अगर आपको इस वर्कशॉप के बारे में अपने अनुभव के बारे में बताना है, तो यह फ़ीडबैक फ़ॉर्म भरें.
हम आपके सुझाव, शिकायत या राय का स्वागत करते हैं. साथ ही, उन कोड के लिए पीआर का भी स्वागत करते हैं जिन पर आपको खास तौर पर गर्व है.
🙏 धन्यवाद
लेखक, Datatonic के Mirko Gilioli और Maurizio Ipsale को धन्यवाद देना चाहते हैं. इनकी मदद से, इस लेख को लिखा गया और समाधान की जांच की गई.