Cloud Build का इस्तेमाल करके, GitHub से Cloud Run में अपने बदलाव अपने-आप डिप्लॉय करने का तरीका

1. परिचय

खास जानकारी

इस कोडलैब में, Cloud Run को कॉन्फ़िगर किया जाएगा, ताकि GitHub रिपॉज़िटरी में सोर्स कोड में किए गए बदलावों को पुश करने पर, आपके ऐप्लिकेशन के नए वर्शन अपने-आप बन जाएं और डिप्लॉय हो जाएं.

इस डेमो ऐप्लिकेशन में, उपयोगकर्ता का डेटा Firestore में सेव किया जाता है. हालांकि, डेटा का सिर्फ़ कुछ हिस्सा ही सही तरीके से सेव होता है. लगातार डिप्लॉयमेंट की सुविधा को कॉन्फ़िगर किया जाएगा, ताकि GitHub रिपॉज़िटरी में गड़बड़ी को ठीक करने के लिए कोड पुश करने पर, आपको नए वर्शन में वह गड़बड़ी ठीक हुई दिखे.

आपको क्या सीखने को मिलेगा

  • Cloud Shell Editor की मदद से, Express वेब ऐप्लिकेशन लिखना
  • लगातार डिप्लॉयमेंट के लिए, अपने GitHub खाते को Google Cloud से कनेक्ट करना
  • अपने ऐप्लिकेशन को Cloud Run पर अपने-आप डिप्लॉय करना
  • HTMX और TailwindCSS का इस्तेमाल करने का तरीका जानना

2. सेटअप और ज़रूरी शर्तें

ज़रूरी शर्तें

Cloud Shell चालू करें

  1. Cloud Console में, Cloud Shell चालू करें d1264ca30785e435.png पर क्लिक करें.

cb81e7c8e34bc8d.png

अगर Cloud Shell को पहली बार शुरू किया जा रहा है, तो आपको एक इंटरमीडिएट स्क्रीन दिखेगी. इसमें Cloud Shell के बारे में बताया गया होगा. अगर आपको इंटरमीडिएट स्क्रीन दिखती है, तो जारी रखें पर क्लिक करें.

d95252b003979716.png

Cloud Shell को चालू करने और उससे कनेक्ट होने में बस कुछ सेकंड लगेंगे.

7833d5e1c5d18f54.png

इस वर्चुअल मशीन में, डेवलपमेंट के लिए ज़रूरी सभी टूल लोड किए गए हैं. इसमें 5 जीबी की परसिस्टेंट होम डायरेक्ट्री मिलती है. साथ ही, यह Google Cloud में चलती है. इससे नेटवर्क की परफ़ॉर्मेंस और पुष्टि करने की प्रोसेस बेहतर होती है. इस कोडलैब में ज़्यादातर काम ब्राउज़र की मदद से किया जा सकता है.

Cloud Shell से कनेक्ट होने के बाद, आपको दिखेगा कि आपकी पुष्टि हो गई है और प्रोजेक्ट को आपके प्रोजेक्ट आईडी पर सेट किया गया है.

  1. पुष्टि करने के लिए, Cloud Shell में यह कमांड चलाएं:
gcloud auth list

कमांड का आउटपुट

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. पुष्टि करने के लिए, Cloud Shell में यह कमांड चलाएं कि gcloud कमांड को आपके प्रोजेक्ट के बारे में जानकारी है या नहीं:
gcloud config list project

कमांड का आउटपुट

[core]
project = <PROJECT_ID>

अगर ऐसा नहीं है, तो इस कमांड से इसे सेट किया जा सकता है:

gcloud config set project <PROJECT_ID>

कमांड का आउटपुट

Updated property [core/project].

3. एपीआई चालू करना और एनवायरमेंट वैरिएबल सेट करना

एपीआई चालू करना

इस कोडलैब के लिए, इन एपीआई का इस्तेमाल करना ज़रूरी है. इन एपीआई को चालू करने के लिए, यह कमांड चलाएं:

gcloud services enable run.googleapis.com \
    cloudbuild.googleapis.com \
    firestore.googleapis.com \
    iamcredentials.googleapis.com

एनवायरमेंट वैरिएबल सेट अप करना

एनवायरमेंट वैरिएबल सेट किए जा सकते हैं. इनका इस्तेमाल इस कोडलैब में किया जाएगा.

REGION=<YOUR-REGION>
PROJECT_ID=<YOUR-PROJECT-ID>
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
SERVICE_ACCOUNT="firestore-accessor"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

4. सेवा खाता बनाना

Cloud Run, Vertex AI Gemini API को कॉल करने के लिए इस सेवा खाते का इस्तेमाल करेगा. इस सेवा खाते के पास, Firestore में डेटा पढ़ने और लिखने की अनुमतियां भी होंगी. साथ ही, यह Secret Manager से सीक्रेट पढ़ सकेगा.

सबसे पहले, यह कमांड चलाकर सेवा खाता बनाएं:

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run access to Firestore"

अब, सेवा खाते को Firestore में डेटा पढ़ने और लिखने का ऐक्सेस दें.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role=roles/datastore.user

5. Firebase प्रोजेक्ट बनाना और उसे कॉन्फ़िगर करना

  1. Firebase कंसोल में, प्रोजेक्ट जोड़ें पर क्लिक करें.
  2. अपने किसी मौजूदा Google Cloud प्रोजेक्ट में Firebase जोड़ने के लिए, <YOUR_PROJECT_ID> डालें
  3. अगर कहा जाए, तो Firebase की शर्तों की समीक्षा करें और उन्हें स्वीकार करें.
  4. जारी रखें पर क्लिक करें.
  5. Firebase के बिलिंग प्लान की पुष्टि करने के लिए, प्लान की पुष्टि करें पर क्लिक करें.
  6. इस कोडलैब के लिए, Google Analytics को चालू करना ज़रूरी नहीं है.
  7. Firebase जोड़ें पर क्लिक करें.
  8. प्रोजेक्ट बन जाने के बाद, जारी रखें पर क्लिक करें.
  9. बनाएं मेन्यू में, Firestore डेटाबेस पर क्लिक करें.
  10. डेटाबेस बनाएं पर क्लिक करें.
  11. जगह ड्रॉप-डाउन में जाकर, अपना इलाका चुनें. इसके बाद, आगे बढ़ें पर क्लिक करें.
  12. डिफ़ॉल्ट प्रोडक्शन मोड में शुरू करें का इस्तेमाल करें. इसके बाद, बनाएं पर क्लिक करें.

6. ऐप्लिकेशन लिखना

सबसे पहले, सोर्स कोड के लिए एक डायरेक्ट्री बनाएं और उस डायरेक्ट्री में सीडी करें.

mkdir cloud-run-github-cd-demo && cd $_

इसके बाद, यहां दिया गया कॉन्टेंट डालकर, package.json फ़ाइल बनाएं:

{
  "name": "cloud-run-github-cd-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node app.js",
    "nodemon": "nodemon app.js",
    "tailwind-dev": "npx tailwindcss -i ./input.css -o ./public/output.css --watch",
    "tailwind": "npx tailwindcss -i ./input.css -o ./public/output.css",
    "dev": "npm run tailwind && npm run nodemon"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@google-cloud/firestore": "^7.3.1",
    "axios": "^1.6.7",
    "express": "^4.18.2",
    "htmx.org": "^1.9.10"
  },
  "devDependencies": {
    "nodemon": "^3.1.0",
    "tailwindcss": "^3.4.1"
  }
}

सबसे पहले, यहां दिया गया कॉन्टेंट डालकर, app.js सोर्स फ़ाइल बनाएं. इस फ़ाइल में, सेवा के लिए एंट्री पॉइंट होता है. साथ ही, इसमें ऐप्लिकेशन के लिए मुख्य लॉजिक होता है.

const express = require("express");
const app = express();
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
const path = require("path");
const { get } = require("axios");

const { Firestore } = require("@google-cloud/firestore");
const firestoreDb = new Firestore();

const fs = require("fs");
const util = require("util");
const { spinnerSvg } = require("./spinnerSvg.js");

const service = process.env.K_SERVICE;
const revision = process.env.K_REVISION;

app.use(express.static("public"));

app.get("/edit", async (req, res) => {
    res.send(`<form hx-post="/update" hx-target="this" hx-swap="outerHTML">
                <div>
  <p>
    <label>Name</label>    
    <input class="border-2" type="text" name="name" value="Cloud">
    </p><p>
    <label>Town</label>    
    <input class="border-2" type="text" name="town" value="Nibelheim">
    </p>
  </div>
  <div class="flex items-center mr-[10px] mt-[10px]">
  <button class="btn bg-blue-500 text-white px-4 py-2 rounded-lg text-center text-sm font-medium mr-[10px]">Submit</button>
  <button class="btn bg-gray-200 text-gray-800 px-4 py-2 rounded-lg text-center text-sm font-medium mr-[10px]" hx-get="cancel">Cancel</button>  
                ${spinnerSvg} 
                </div>
  </form>`);
});

app.post("/update", async function (req, res) {
    let name = req.body.name;
    let town = req.body.town;
    const doc = firestoreDb.doc(`demo/${name}`);

    //TODO: fix this bug
    await doc.set({
        name: name
        /* town: town */
    });

    res.send(`<div hx-target="this" hx-swap="outerHTML" hx-indicator="spinner">
                <p>
                <div><label>Name</label>: ${name}</div>
                </p><p>
                <div><label>Town</label>: ${town}</div>
                </p>
                <button
                    hx-get="/edit"
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium mt-[10px]"
                >
                    Click to update
                </button>               
            </div>`);
});

app.get("/cancel", (req, res) => {
    res.send(`<div hx-target="this" hx-swap="outerHTML">
                <p>
                <div><label>Name</label>: Cloud</div>
                </p><p>
                <div><label>Town</label>: Nibelheim</div>
                </p>
                <div>
                <button
                    hx-get="/edit"
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium mt-[10px]"
                >
                    Click to update
                </button>                
                </div>
            </div>`);
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, async () => {
    console.log(`booth demo: listening on port ${port}`);

    //serviceMetadata = helper();
});

app.get("/helper", async (req, res) => {
    let region = "";
    let projectId = "";
    let div = "";

    try {
        // Fetch the token to make a GCF to GCF call
        const response1 = await get(
            "http://metadata.google.internal/computeMetadata/v1/project/project-id",
            {
                headers: {
                    "Metadata-Flavor": "Google"
                }
            }
        );

        // Fetch the token to make a GCF to GCF call
        const response2 = await get(
            "http://metadata.google.internal/computeMetadata/v1/instance/region",
            {
                headers: {
                    "Metadata-Flavor": "Google"
                }
            }
        );

        projectId = response1.data;
        let regionFull = response2.data;
        const index = regionFull.lastIndexOf("/");
        region = regionFull.substring(index + 1);

        div = `
        <div>
        This created the revision <code>${revision}</code> of the 
        Cloud Run service <code>${service}</code> in <code>${region}</code>
        for project <code>${projectId}</code>.
        </div>`;
    } catch (ex) {
        // running locally
        div = `<div> This is running locally.</div>`;
    }

    res.send(div);
});

spinnerSvg.js नाम की फ़ाइल बनाएं

module.exports.spinnerSvg = `<svg id="spinner" alt="Loading..."
                    class="htmx-indicator animate-spin -ml-1 mr-3 h-5 w-5 text-blue-500"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 24 24"
                >
                    <circle
                        class="opacity-25"
                        cx="12"
                        cy="12"
                        r="10"
                        stroke="currentColor"
                        stroke-width="4"
                    ></circle>
                    <path
                        class="opacity-75"
                        fill="currentColor"
                        d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
                    ></path>
                </svg>`;

TailwindCSS के लिए, input.css फ़ाइल बनाएं

@tailwind base;
@tailwind components;
@tailwind utilities;

TailwindCSS के लिए, tailwind.config.js फ़ाइल बनाएं

/** @type {import('tailwindcss').Config} */
module.exports = {
    content: ["./**/*.{html,js}"],
    theme: {
        extend: {}
    },
    plugins: []
};

साथ ही, .gitignore फ़ाइल बनाएं.

node_modules/

npm-debug.log
coverage/

package-lock.json

.DS_Store

अब, public नाम की नई डायरेक्ट्री बनाएं.

mkdir public
cd public

साथ ही, उस पब्लिक डायरेक्ट्री में, फ्रंट एंड के लिए index.html फ़ाइल बनाएं. इसमें htmx का इस्तेमाल किया जाएगा.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta
            name="viewport"
            content="width=device-width, initial-scale=1.0"
        />
        <script
            src="https://unpkg.com/htmx.org@1.9.10"
            integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
            crossorigin="anonymous"
        ></script>

        <link href="./output.css" rel="stylesheet" />
        <title>Demo 1</title>
    </head>
    <body
        class="font-sans bg-body-image bg-cover bg-center leading-relaxed"
    >
        <div class="container max-w-[700px] mt-[50px] ml-auto mr-auto">
            <div class="hero flex items-center">                    
                <div class="message text-base text-center mb-[24px]">
                    <h1 class="text-2xl font-bold mb-[10px]">
                        It's running!
                    </h1>
                    <div class="congrats text-base font-normal">
                        Congratulations, you successfully deployed your
                        service to Cloud Run. 
                    </div>
                </div>
            </div>

            <div class="details mb-[20px]">
                <p>
                    <div hx-trigger="load" hx-get="/helper" hx-swap="innerHTML" hx-target="this">Hello</div>                   
                </p>
            </div>

            <p
                class="callout text-sm text-blue-700 font-bold pt-4 pr-6 pb-4 pl-10 leading-tight"
            >
                You can deploy any container to Cloud Run that listens for
                HTTP requests on the port defined by the
                <code>PORT</code> environment variable. Cloud Run will
                scale automatically based on requests and you never have to
                worry about infrastructure.
            </p>

            <h1 class="text-2xl font-bold mt-[40px] mb-[20px]">
                Persistent Storage Example using Firestore
            </h1>
            <div hx-target="this" hx-swap="outerHTML">
                <p>
                <div><label>Name</label>: Cloud</div>
                </p><p>
                <div><label>Town</label>: Nibelheim</div>
                </p>
                <div>
                <button
                    hx-get="/edit"
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-sm font-medium mt-[10px]"
                >
                    Click to update
                </button>                
                </div>
            </div>

            <h1 class="text-2xl font-bold mt-[40px] mb-[20px]">
                What's next
            </h1>
            <p class="next text-base mt-4 mb-[20px]">
                You can build this demo yourself!
            </p>
            <p class="cta">
                <button
                    class="bg-blue-500 text-white px-4 py-2 rounded-lg text-center text-sm font-medium"
                >
                    VIEW CODELAB
                </button>
            </p> 
        </div>
   </body>
</html>

7. ऐप्लिकेशन को स्थानीय तौर पर चलाना

इस सेक्शन में, ऐप्लिकेशन को स्थानीय तौर पर चलाया जाएगा, ताकि यह पुष्टि की जा सके कि उपयोगकर्ता के डेटा सेव करने की कोशिश करने पर, ऐप्लिकेशन में कोई गड़बड़ी है या नहीं.

सबसे पहले, Firestore को ऐक्सेस करने के लिए, आपके पास Datastore User की भूमिका होनी चाहिए. यह भूमिका तब ज़रूरी है, जब पुष्टि करने के लिए आपकी पहचान का इस्तेमाल किया जा रहा हो. जैसे, Cloud Shell में ऐप्लिकेशन चलाने पर. इसके अलावा, पहले बनाए गए उपयोगकर्ता खाते से मिलती-जुलती पहचान का इस्तेमाल किया जा सकता है.

स्थानीय तौर पर ऐप्लिकेशन चलाते समय, एडीसी का इस्तेमाल करना

अगर Cloud Shell में ऐप्लिकेशन चलाया जा रहा है, तो यह पहले से ही Google Compute Engine की वर्चुअल मशीन पर चल रहा है. `gcloud auth list` कमांड चलाने पर, इस वर्चुअल मशीन से जुड़े क्रेडेंशियल दिखेंगे. इनका इस्तेमाल, ऐप्लिकेशन के डिफ़ॉल्ट क्रेडेंशियल (एडीसी) अपने-आप करेंगे. इसलिए, `gcloud auth application-default login` कमांड का इस्तेमाल करना ज़रूरी नहीं है. हालांकि, आपकी पहचान के लिए अब भी Datastore User की भूमिका ज़रूरी होगी. ऐप्लिकेशन को स्थानीय तौर पर चलाना सेक्शन पर जाएं.

हालांकि, अगर स्थानीय टर्मिनल पर ऐप्लिकेशन चलाया जा रहा है, तो Google के एपीआई की पुष्टि करने के लिए, ऐप्लिकेशन के डिफ़ॉल्ट क्रेडेंशियल का इस्तेमाल करना होगा. Cloud Shell में ऐप्लिकेशन चलाने पर, इसकी ज़रूरत नहीं होती. इसके लिए, 1) अपने क्रेडेंशियल का इस्तेमाल करके लॉग इन किया जा सकता है. हालांकि, इसके लिए आपके पास Datastore User की भूमिका होनी चाहिए. इसके अलावा, 2) इस कोडलैब में इस्तेमाल किए गए सेवा खाते से मिलती-जुलती पहचान का इस्तेमाल करके लॉग इन किया जा सकता है.

पहला विकल्प) एडीसी के लिए अपने क्रेडेंशियल का इस्तेमाल करना

अगर अपने क्रेडेंशियल का इस्तेमाल करना है, तो सबसे पहले gcloud auth list कमांड चलाकर यह पुष्टि करें कि gcloud में आपकी पुष्टि कैसे की गई है. इसके बाद, हो सकता है कि आपको अपनी पहचान को Vertex AI User की भूमिका देनी पड़े. अगर आपकी पहचान के पास Owner की भूमिका है, तो आपके पास पहले से ही Datastore User की भूमिका है. अगर ऐसा नहीं है, तो अपनी पहचान को Vertex AI User की भूमिका और Datastore User की भूमिका देने के लिए, यह कमांड चलाएं.

USER=<YOUR_PRINCIPAL_EMAIL>

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member user:$USER \
  --role=roles/datastore.user

इसके बाद, यह कमांड चलाएं

gcloud auth application-default login

दूसरा विकल्प) एडीसी के लिए, सेवा खाते से मिलती-जुलती पहचान का इस्तेमाल करना

अगर इस कोडलैब में बनाए गए सेवा खाते का इस्तेमाल करना है, तो आपके उपयोगकर्ता खाते के पास Service Account Token Creator की भूमिका होनी चाहिए. यह भूमिका पाने के लिए, यह कमांड चलाएं:

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member user:$USER \
  --role=roles/iam.serviceAccountTokenCreator

इसके बाद, सेवा खाते के साथ एडीसी का इस्तेमाल करने के लिए, यह कमांड चलाएं

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

ऐप्लिकेशन को स्थानीय तौर पर चलाना

इसके बाद, पक्का करें कि कोडलैब के लिए, रूट डायरेक्ट्री cloud-run-github-cd-demo में हों.

cd .. && pwd

अब, डिपेंडेंसी इंस्टॉल करें.

npm install

आखिर में, यह स्क्रिप्ट चलाकर ऐप्लिकेशन शुरू किया जा सकता है. यह स्क्रिप्ट, TailwindCSS से output.css फ़ाइल भी जनरेट करेगी.

npm run dev

अब अपना वेब ब्राउज़र खोलें और http://localhost:8080 पर जाएं. अगर Cloud Shell में हैं, तो वेबसाइट खोलने के लिए, वेब प्रीव्यू बटन खोलें और 'पोर्ट 8080 का प्रीव्यू' चुनें.

वेब प्रीव्यू - पोर्ट 8080 पर झलक देखें बटन

नाम और शहर के इनपुट फ़ील्ड में टेक्स्ट डालें और सेव करें पर क्लिक करें. इसके बाद, पेज को रीफ़्रेश करें. आपको दिखेगा कि शहर का फ़ील्ड सेव नहीं हुआ है. अगले सेक्शन में, इस गड़बड़ी को ठीक किया जाएगा.

Express ऐप्लिकेशन को स्थानीय तौर पर चलने से रोकें. जैसे, MacOS पर Ctrl^c दबाएं.

8. GitHub रिपॉज़िटरी बनाना

अपनी स्थानीय डायरेक्ट्री में, main को डिफ़ॉल्ट ब्रांच के नाम के तौर पर इस्तेमाल करके, नई रिपॉज़िटरी बनाएं.

git init
git branch -M main

मौजूदा कोडबेस को कमिट करें. इसमें गड़बड़ी मौजूद है. लगातार डिप्लॉयमेंट की सुविधा को कॉन्फ़िगर करने के बाद, गड़बड़ी को ठीक किया जाएगा.

git add .
git commit -m "first commit for express application"

GitHub पर जाएं और खाली रिपॉज़िटरी बनाएं. यह रिपॉज़िटरी, आपके लिए निजी या सार्वजनिक हो सकती है. इस कोडलैब में, रिपॉज़िटरी का नाम cloud-run-auto-deploy-codelab रखने का सुझाव दिया गया है. खाली रिपॉज़िटरी बनाने के लिए, सभी डिफ़ॉल्ट सेटिंग से सही का निशान हटाएं या उन्हें 'कोई नहीं' पर सेट करें. इससे, रिपॉज़िटरी बनने पर, उसमें डिफ़ॉल्ट रूप से कोई कॉन्टेंट नहीं होगा. जैसे,

GitHub की डिफ़ॉल्ट सेटिंग

अगर यह चरण सही तरीके से पूरा किया गया है, तो आपको खाली रिपॉज़िटरी वाले पेज पर ये निर्देश दिखेंगे:

GitHub repo के लिए खाली निर्देश

कमांड लाइन से मौजूदा रिपॉज़िटरी को पुश करना निर्देशों का पालन करने के लिए, ये कमांड चलाएं:

सबसे पहले, रिमोट रिपॉज़िटरी जोड़ने के लिए, यह कमांड चलाएं

git remote add origin <YOUR-REPO-URL-PER-GITHUB-INSTRUCTIONS>

इसके बाद, main ब्रांच को अपस्ट्रीम रिपॉज़िटरी में पुश करें.

git push -u origin main

9. लगातार डिप्लॉयमेंट सेट अप करना

अब GitHub में कोड मौजूद है. इसलिए, लगातार डिप्लॉयमेंट सेट अप किया जा सकता है. Cloud Run के लिए, Cloud Console पर जाएं.

  • सेवा बनाएं पर क्लिक करें
  • किसी रिपॉज़िटरी से लगातार डिप्लॉय करें पर क्लिक करें
  • CLOUD BUILD सेट अप करें पर क्लिक करें.
  • सोर्स रिपॉज़िटरी में जाकर,
    • रिपॉज़िटरी प्रोवाइडर के तौर पर GitHub को चुनें
    • रिपॉज़िटरी का ऐक्सेस कॉन्फ़िगर करने के लिए, कनेक्ट की गई रिपॉज़िटरी मैनेज करें पर क्लिक करें
    • अपनी रिपॉज़िटरी चुनें और आगे बढ़ें पर क्लिक करें
  • बिल्ड कॉन्फ़िगरेशन में जाकर,
    • ब्रांच को ^main$ पर छोड़ दें
    • बिल्ड टाइप के लिए, Google Cloud के बिल्डपैक की मदद से Go, Node.js, Python, Java, .NET Core, Ruby या PHP को चुनें
  • बिल्ड कॉन्टेक्स्ट डायरेक्ट्री को / पर छोड़ दें
  • सेव करें पर क्लिक करें
  • पुष्टि करने की सेटिंग में जाकर,
    • बिना पुष्टि किए कॉल करने की अनुमति दें पर क्लिक करें
  • कंटेनर, वॉल्यूम, नेटवर्किंग, सुरक्षा में जाकर,
    • सुरक्षा टैब में, पहले बनाए गए सेवा खाते को चुनें. जैसे, Cloud Run access to Firestore
  • बनाएं पर क्लिक करें

इससे, Cloud Run सेवा डिप्लॉय हो जाएगी. इसमें वह गड़बड़ी मौजूद है जिसे अगले सेक्शन में ठीक किया जाएगा.

10. गड़बड़ी ठीक करना

कोड में मौजूद गड़बड़ी ठीक करना

Cloud Shell Editor में, app.js फ़ाइल खोलें और उस टिप्पणी पर जाएं जिसमें लिखा है //TODO: fix this bug

इस लाइन को

 //TODO: fix this bug
    await doc.set({
        name: name
    });

इससे बदलें

//fixed town bug
    await doc.set({
        name: name,
        town: town
    });

गड़बड़ी ठीक होने की पुष्टि करने के लिए, यह कमांड चलाएं

npm run start

इसके बाद, अपना वेब ब्राउज़र खोलें. शहर के लिए डेटा फिर से सेव करें और रीफ़्रेश करें. आपको दिखेगा कि रीफ़्रेश करने पर, शहर का नया डेटा सही तरीके से सेव हो गया है.

अब गड़बड़ी ठीक होने की पुष्टि हो गई है. इसलिए, इसे डिप्लॉय किया जा सकता है. सबसे पहले, गड़बड़ी ठीक करने के लिए कोड को कमिट करें.

git add .
git commit -m "fixed town bug"

इसके बाद, इसे GitHub पर अपस्ट्रीम रिपॉज़िटरी में पुश करें.

git push origin main

Cloud Build, आपके बदलावों को अपने-आप डिप्लॉय कर देगा. डिप्लॉयमेंट में किए गए बदलावों की निगरानी करने के लिए, Cloud Run सेवा के लिए Cloud Console पर जाएं.

प्रोडक्शन में गड़बड़ी ठीक होने की पुष्टि करना

जब Cloud Run सेवा के लिए Cloud Console में यह दिखे कि दूसरा वर्शन अब 100% ट्रैफ़िक को मैनेज कर रहा है, जैसे कि https://console.cloud.google.com/run/detail/<YOUR_REGION>/<YOUR_SERVICE_NAME>/revisions, तब अपने ब्राउज़र में Cloud Run सेवा का यूआरएल खोलें. इसके बाद, पुष्टि करें कि पेज को रीफ़्रेश करने के बाद, शहर का नया डेटा सेव हो गया है.

11. बधाई हो!

कोडलैब पूरा करने के लिए बधाई!

हमारा सुझाव है कि Cloud Run और Git से लगातार डिप्लॉयमेंट की सुविधा के बारे में दस्तावेज़ पढ़ें.

हमने क्या-क्या कवर किया

  • Cloud Shell Editor की मदद से, Express वेब ऐप्लिकेशन लिखना
  • लगातार डिप्लॉयमेंट के लिए, अपने GitHub खाते को Google Cloud से कनेक्ट करना
  • अपने ऐप्लिकेशन को Cloud Run पर अपने-आप डिप्लॉय करना
  • HTMX और TailwindCSS का इस्तेमाल करने का तरीका जानना

12. व्यवस्थित करें

अनजाने में शुल्क लगने से बचने के लिए, Cloud Run सेवाओं को मिटाया जा सकता है. उदाहरण के लिए, अगर Cloud Run सेवाओं को मुफ़्त टियर में, हर महीने Cloud Run के लिए तय की गई सीमा से ज़्यादा बार कॉल किया जाता है, तो शुल्क लग सकता है. इसके लिए, Cloud Run सेवाओं को मिटाएं या दूसरे चरण में बनाए गए प्रोजेक्ट को मिटाएं.

Cloud Run सेवा को मिटाने के लिए, Cloud Run Cloud Console पर जाएं. इसका यूआरएल https://console.cloud.google.com/run है. इसके बाद, इस कोडलैब में बनाई गई Cloud Run सेवा को मिटाएं. जैसे, cloud-run-auto-deploy-codelab सेवा को मिटाएं.

पूरा प्रोजेक्ट मिटाने के लिए, https://console.cloud.google.com/cloud-resource-manager पर जाएं. इसके बाद, दूसरे चरण में बनाया गया प्रोजेक्ट चुनें और मिटाएं को चुनें. प्रोजेक्ट मिटाने पर, आपको Cloud SDK में प्रोजेक्ट बदलने होंगे. gcloud projects list कमांड चलाकर, सभी उपलब्ध प्रोजेक्ट की सूची देखी जा सकती है.