نحوه اجرای خودکار تغییرات خود از GitHub به Cloud Run با استفاده از Cloud Build

1. مقدمه

نمای کلی

در این لبه کد، Cloud Run را به گونه‌ای پیکربندی می‌کنید که هر زمان که تغییرات کد منبع خود را به مخزن GitHub وارد می‌کنید ، به‌طور خودکار نسخه‌های جدید برنامه خود را بسازد و اجرا کند .

این برنامه آزمایشی داده های کاربر را در firestore ذخیره می کند، با این حال، تنها مقدار جزئی از داده ها به درستی ذخیره می شود. شما پیاده‌سازی‌های پیوسته را به گونه‌ای پیکربندی می‌کنید که وقتی یک رفع اشکال را به مخزن GitHub خود فشار می‌دهید، به‌طور خودکار مشاهده می‌کنید که اصلاح در یک نسخه جدید در دسترس است.

چیزی که یاد خواهید گرفت

  • با Cloud Shell Editor یک برنامه وب Express بنویسید
  • حساب GitHub خود را برای استقرار مداوم به Google Cloud متصل کنید
  • به طور خودکار برنامه خود را در Cloud Run مستقر کنید
  • نحوه استفاده از HTMX و TailwindCSS را بیاموزید

2. راه اندازی و الزامات

پیش نیازها

  • شما یک حساب GitHub دارید و با ایجاد و ارسال کد به مخازن آشنا هستید.
  • شما به کنسول Cloud وارد شده اید.
  • شما قبلاً یک سرویس Cloud Run را مستقر کرده اید. برای مثال، می‌توانید برای شروع ، استقرار یک سرویس وب را از کد منبع سریع دنبال کنید.

Cloud Shell را فعال کنید

  1. از Cloud Console، روی Activate Cloud Shell کلیک کنید d1264ca30785e435.png .

cb81e7c8e34bc8d.png

اگر این اولین باری است که Cloud Shell را راه اندازی می کنید، با یک صفحه میانی روبرو می شوید که آن را توصیف می کند. اگر با یک صفحه میانی مواجه شدید، روی Continue کلیک کنید.

d95252b003979716.png

تهیه و اتصال به Cloud Shell فقط باید چند لحظه طول بکشد.

7833d5e1c5d18f54.png

این ماشین مجازی با تمام ابزارهای توسعه مورد نیاز بارگذاری شده است. این یک فهرست اصلی 5 گیگابایتی دائمی ارائه می‌کند و در Google Cloud اجرا می‌شود، که عملکرد و احراز هویت شبکه را بسیار افزایش می‌دهد. بسیاری از کارهای شما، اگر نه همه، در این کد لبه با مرورگر قابل انجام است.

پس از اتصال به Cloud Shell، باید ببینید که احراز هویت شده اید و پروژه به ID پروژه شما تنظیم شده است.

  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. API ها را فعال کنید و متغیرهای محیط را تنظیم کنید

API ها را فعال کنید

این آزمایشگاه کد نیاز به استفاده از API های زیر دارد. با اجرای دستور زیر می توانید آن API ها را فعال کنید:

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 استفاده خواهد شد. این حساب سرویس همچنین دارای مجوز خواندن و نوشتن در Firestor و خواندن اسرار از Secret Manager است.

ابتدا با اجرای این دستور اکانت سرویس ایجاد کنید:

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

اکنون، به حساب سرویس دسترسی خواندن و نوشتن به Firestor اجازه دهید.

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

5. یک پروژه Firebase ایجاد و پیکربندی کنید

  1. در کنسول Firebase ، روی افزودن پروژه کلیک کنید.
  2. برای افزودن Firebase به یکی از پروژه‌های Google Cloud موجود، <YOUR_PROJECT_ID> را وارد کنید
  3. در صورت درخواست، شرایط Firebase را بررسی کرده و بپذیرید.
  4. روی Continue کلیک کنید.
  5. برای تأیید طرح صورت‌حساب Firebase روی تأیید طرح کلیک کنید.
  6. این اختیاری است که Google Analytics را برای این کد لبه فعال کنید.
  7. روی Add Firebase کلیک کنید.
  8. پس از ایجاد پروژه، روی Continue کلیک کنید.
  9. از منوی Build ، روی پایگاه داده Firestore کلیک کنید.
  10. روی ایجاد پایگاه داده کلیک کنید.
  11. منطقه خود را از منوی کشویی Location انتخاب کنید، سپس روی Next کلیک کنید.
  12. از Start پیش فرض در حالت تولید استفاده کنید، سپس روی Create کلیک کنید.

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>`;

یک فایل input.css برای tailwindCSS ایجاد کنید

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

و فایل tailwind.config.js را برای tailwindCSS ایجاد کنید

/** @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 در حال اجرا هستید) یا می توانید جعل هویت حساب کاربری که قبلاً ایجاد شده است.

استفاده از ADC هنگام اجرای محلی

اگر در Cloud Shell در حال اجرا هستید، در حال حاضر روی یک ماشین مجازی موتور محاسباتی گوگل کار می کنید. اعتبارنامه شما مرتبط با این ماشین مجازی (همانطور که با اجرای gcloud auth list نشان داده شده است) به طور خودکار توسط Application Default Credentials (ADC) استفاده می شود، بنابراین استفاده از دستور gcloud auth application-default login ضروری نیست. با این حال، هویت شما همچنان به نقش کاربر Datastore نیاز دارد. می توانید به بخش اجرای برنامه به صورت محلی پرش کنید.

با این حال، اگر در ترمینال محلی خود در حال اجرا هستید (یعنی نه در Cloud Shell)، باید از اعتبارنامه پیش فرض برنامه برای احراز هویت در API های Google استفاده کنید. شما می توانید 1) با استفاده از اطلاعات کاربری خود وارد شوید (به شرطی که نقش کاربر Datastore را داشته باشید) یا 2) می توانید با جعل هویت حساب سرویس مورد استفاده در این کد لبه وارد شوید.

گزینه 1) استفاده از اعتبارنامه خود برای ADC

اگر می‌خواهید از اعتبارنامه‌های خود استفاده کنید، می‌توانید ابتدا gcloud auth list را اجرا کنید تا نحوه احراز هویت خود را در gcloud تأیید کنید. در مرحله بعد، ممکن است لازم باشد به هویت خود نقش Vertex AI User را بدهید. اگر هویت شما دارای نقش مالک است، شما از قبل این نقش کاربری کاربر Datastore را دارید. اگر نه، می‌توانید این دستور را اجرا کنید تا به هویت خود، نقش کاربر Vertex AI و نقش کاربر Datastore را اعطا کنید.

USER=<YOUR_PRINCIPAL_EMAIL>

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

سپس دستور زیر را اجرا کنید

gcloud auth application-default login

گزینه 2) جعل هویت یک حساب سرویس برای ADC

اگر می‌خواهید از حساب سرویس ایجاد شده در این کد لبه استفاده کنید، حساب کاربری شما باید نقش ایجاد کننده رمز حساب سرویس را داشته باشد. با اجرای دستور زیر می توانید این نقش را بدست آورید:

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

در مرحله بعد، دستور زیر را برای استفاده از ADC با حساب سرویس اجرا می کنید

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

برنامه را به صورت محلی اجرا کنید

در مرحله بعد، مطمئن شوید که در دایرکتوری ریشه cloud-run-github-cd-demo برای Codelab خود هستید.

cd .. && pwd

اکنون، وابستگی ها را نصب خواهید کرد.

npm install

در نهایت، می توانید برنامه را با اجرای اسکریپت زیر راه اندازی کنید. این اسکریپت همچنین فایل output.css را از tailwindCSS تولید می کند.

npm run dev

اکنون مرورگر وب خود را به http://localhost:8080 باز کنید. اگر در Cloud Shell هستید، می توانید با باز کردن دکمه Web Preview و انتخاب Preview Port 8080 وب سایت را باز کنید.

پیش نمایش وب - پیش نمایش دکمه پورت 8080

متنی را برای فیلدهای ورودی نام و شهر وارد کنید و ذخیره را بزنید. سپس صفحه را رفرش کنید. متوجه خواهید شد که میدان شهر پابرجا نبود. در بخش بعدی این باگ را برطرف خواهید کرد.

اجرای محلی برنامه اکسپرس را متوقف کنید (مثلاً Ctrl^c در MacOS).

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 را خالی کنید

با اجرای دستورات زیر ، فشار یک مخزن موجود را از دستورالعمل های خط فرمان دنبال خواهید کرد:

ابتدا مخزن راه دور را با اجرا اضافه کنید

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

سپس شاخه اصلی را به مخزن بالادست فشار دهید.

git push -u origin main

9. راه اندازی مستمر استقرار

اکنون که کدی در یک GitHub دارید، می توانید استقرار مداوم را تنظیم کنید. برای Cloud Run به Cloud Console بروید.

  • روی ایجاد سرویس کلیک کنید
  • روی Continuously Deploy from a Repository کلیک کنید
  • روی SET UP CLOUD BUILD کلیک کنید.
  • در زیر مخزن منبع
    • GitHub را به عنوان ارائه دهنده مخزن انتخاب کنید
    • برای پیکربندی دسترسی Cloud Build به مخزن ، روی مدیریت مخازن متصل کلیک کنید
    • مخزن خود را انتخاب کنید و روی Next کلیک کنید
  • تحت پیکربندی ساخت
    • شعبه را به عنوان ^main$ ترک کنید
    • برای نوع ساخت، Go، Node.js، Python، Java، NET Core، Ruby یا PHP را از طریق بسته‌های ساخت Google Cloud انتخاب کنید.
  • دایرکتوری زمینه ساخت را به عنوان / رها کنید
  • روی ذخیره کلیک کنید
  • تحت احراز هویت
    • روی اجازه دادن به فراخوان‌های احراز هویت نشده کلیک کنید
  • تحت کانتینر(ها)، حجم، شبکه، امنیت
    • در برگه امنیت، حساب سرویسی را که در مرحله قبلی ایجاد کردید، انتخاب کنید، به عنوان مثال Cloud Run access to Firestore
  • روی CREATE کلیک کنید

با این کار سرویس 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 برای سرویس Cloud Run خود بروید.

تعمیر را در تولید بررسی کنید

هنگامی که کنسول Cloud برای سرویس Cloud Run شما نشان داد که نسخه دوم اکنون 100٪ ترافیک را ارائه می دهد، به عنوان مثال https://console.cloud.google.com/run/detail/<YOUR_REGION>/<YOUR_SERVICE_NAME>/revisions، می توانید باز کنید URL سرویس Cloud Run را در مرورگر خود و بررسی کنید که داده‌های شهر تازه وارد شده پس از رفرش صفحه همچنان باقی بماند.

11. تبریک می گویم!

برای تکمیل کد لبه تبریک می گویم!

توصیه می‌کنیم مستندات Cloud Run و استقرار مداوم از git را مرور کنید.

آنچه را پوشش داده ایم

  • با Cloud Shell Editor یک برنامه وب Express بنویسید
  • حساب GitHub خود را برای استقرار مداوم به Google Cloud متصل کنید
  • به طور خودکار برنامه خود را در Cloud Run مستقر کنید
  • نحوه استفاده از HTMX و TailwindCSS را بیاموزید

12. پاکسازی کنید

برای جلوگیری از هزینه‌های غیرعمدی، (به عنوان مثال، اگر سرویس‌های Cloud Run به طور ناخواسته بیشتر از تخصیص فراخوانی ماهانه Cloud Run در ردیف رایگان فراخوانی می‌شوند)، می‌توانید Cloud Run را حذف کنید یا پروژه‌ای را که در مرحله 2 ایجاد کرده‌اید حذف کنید.

برای حذف سرویس Cloud Run، به کنسول Cloud Run Cloud در https://console.cloud.google.com/run بروید و سرویس Cloud Run را که در این Codelab ایجاد کرده اید حذف کنید، به عنوان مثال، cloud-run-auto-deploy-codelab را حذف کنید. -سرویس cloud-run-auto-deploy-codelab .

اگر تصمیم به حذف کل پروژه دارید، می‌توانید به https://console.cloud.google.com/cloud-resource-manager بروید، پروژه‌ای را که در مرحله ۲ ایجاد کرده‌اید انتخاب کنید و حذف را انتخاب کنید. اگر پروژه را حذف کنید، باید پروژه ها را در Cloud SDK خود تغییر دهید. با اجرای gcloud projects list می توانید لیست تمام پروژه های موجود را مشاهده کنید.