Xây dựng và triển khai một ứng dụng lập kế hoạch ăn kiêng dựa trên AI bằng Streamlit, Gemini Pro, Vertex AI và BigQuery

1. Giới thiệu

9370c0f92c692ebb.png

Trong lớp học lập trình này, bạn sẽ tìm hiểu cách tạo và triển khai một Trợ lý lập kế hoạch ăn kiêng dựa trên AI. Đối với giao diện người dùng sử dụng Streamlit, mô hình LLM sử dụng Gemini Pro 2.5, Trình điều phối công cụ AI dựa trên tác nhân sử dụng Vertex AI để phát triển AI dựa trên tác nhân, BigQuery để lưu trữ dữ liệu và Cloud Run để triển khai.

Trong lớp học lập trình này, bạn sẽ sử dụng phương pháp từng bước như sau:

  1. Chuẩn bị dự án Google Cloud và Bật tất cả API bắt buộc trên dự án đó
  2. Xây dựng Trình lập kế hoạch ăn kiêng bằng AI có khả năng hành động bằng cách sử dụng streamlit, Vertex AI và BigQuery
  3. Triển khai ứng dụng lên Cloud Run

Tổng quan về cấu trúc

84e3f3620dc4ed68.png

Điều kiện tiên quyết

  • Một dự án trên Google Cloud Platform (GCP) đã bật tính năng thanh toán.
  • Kiến thức cơ bản về Python

Kiến thức bạn sẽ học được

  • Cách tạo Trình lập kế hoạch ăn kiêng bằng AI dựa trên tác nhân bằng cách sử dụng streamlit, Vertex AI và lưu trữ dữ liệu vào BigQuery
  • Cách triển khai ứng dụng lên Cloud Run

Bạn cần có

  • Trình duyệt web Chrome
  • Tài khoản Gmail
  • Một Dự án trên đám mây đã bật tính năng thanh toán

2. Thiết lập cơ bản và yêu cầu

Thiết lập môi trường theo tốc độ của riêng bạn

  1. Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

fbef9caa1602edd0.png

37d264871000675d.png

5e3ff691252acf41.png

  • Tên dự án là tên hiển thị cho những người tham gia dự án này. Đây là một chuỗi ký tự mà các API của Google không sử dụng. Bạn luôn có thể cập nhật thông tin này.
  • Mã dự án là giá trị duy nhất trên tất cả các dự án trên Google Cloud và không thể thay đổi (bạn không thể thay đổi mã này sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (thường được xác định là PROJECT_ID). Nếu không thích mã nhận dạng được tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Hoặc bạn có thể thử tên người dùng của riêng mình để xem tên đó có được chấp nhận hay không. Bạn không thể thay đổi tên này sau bước này và tên này sẽ tồn tại trong suốt thời gian của dự án.
  • Để bạn biết, có một giá trị thứ ba là Số dự án mà một số API sử dụng. Tìm hiểu thêm về cả 3 giá trị này trong tài liệu.
  1. Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các tài nguyên/API trên Cloud. Việc thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, nếu có. Để tắt các tài nguyên nhằm tránh bị tính phí ngoài phạm vi hướng dẫn này, bạn có thể xoá các tài nguyên đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

3. Trước khi bắt đầu

Thiết lập dự án trên Cloud trong Cloud Shell Editor

Lớp học lập trình này giả định rằng bạn đã có một dự án trên Google Cloud đã bật tính năng thanh toán. Nếu chưa có, bạn có thể làm theo hướng dẫn bên dưới để bắt đầu.

  1. Trong Google Cloud Console, trên trang chọn dự án, hãy chọn hoặc tạo một dự án trên Google Cloud.
  2. Đảm bảo bạn đã bật tính năng thanh toán cho dự án trên Cloud. Tìm hiểu cách kiểm tra xem tính năng thanh toán có được bật trên một dự án hay không .
  3. Bạn sẽ sử dụng Cloud Shell, một môi trường dòng lệnh chạy trong Google Cloud và được tải sẵn bq. Nhấp vào biểu tượng Kích hoạt Cloud Shell ở đầu bảng điều khiển Google Cloud.

26f20e837ff06119.png

  1. Sau khi kết nối với Cloud Shell, bạn có thể kiểm tra để đảm bảo rằng bạn đã được xác thực và dự án được đặt thành mã dự án của bạn bằng lệnh sau:
gcloud auth list
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn.
gcloud config list project
  1. Nếu bạn chưa đặt dự án, hãy dùng lệnh sau để đặt:
gcloud config set project <YOUR_PROJECT_ID>

Ngoài ra, bạn cũng có thể xem mã PROJECT_ID trong bảng điều khiển

bb98435b79995b15.jpeg

Nhấp vào đó, bạn sẽ thấy tất cả dự án và mã dự án ở bên phải

ffa73dee57de5307.jpeg

  1. Bật các API bắt buộc thông qua lệnh bên dưới. Quá trình này có thể mất vài phút, vì vậy, vui lòng kiên nhẫn chờ đợi.
gcloud services enable aiplatform.googleapis.com \
                           run.googleapis.com \
                           cloudbuild.googleapis.com \
                           cloudresourcemanager.googleapis.com \
                    bigquery.googleapis.com

Khi thực thi lệnh thành công, bạn sẽ thấy một thông báo tương tự như thông báo dưới đây:

Operation "operations/..." finished successfully.

Bạn có thể thay thế lệnh gcloud bằng cách tìm kiếm từng sản phẩm trên bảng điều khiển hoặc sử dụng đường liên kết này.

Nếu bỏ lỡ API nào, bạn luôn có thể bật API đó trong quá trình triển khai.

Tham khảo tài liệu để biết các lệnh và cách sử dụng gcloud.

Thiết lập thư mục làm việc của ứng dụng

  1. Nhấp vào nút Open Editor (Mở trình chỉnh sửa). Thao tác này sẽ mở Cloud Shell Editor. Chúng ta có thể viết mã tại đây 6f8e18e89d3198c0.png
  2. Đảm bảo dự án Cloud Code được đặt ở góc dưới bên trái (thanh trạng thái) của trình chỉnh sửa Cloud Shell, như được đánh dấu trong hình bên dưới và được đặt thành dự án Google Cloud đang hoạt động mà bạn đã bật tính năng thanh toán. Uỷ quyền nếu được nhắc. Có thể mất một lúc sau khi bạn khởi động Cloud Shell Editor thì nút Cloud Code – Đăng nhập mới xuất hiện. Vui lòng kiên nhẫn chờ đợi.

4e372d87c51afa30.png

Tiếp theo, chúng ta sẽ chuẩn bị môi trường Python

Thiết lập môi trường

Chuẩn bị môi trường ảo Python

Bước tiếp theo là chuẩn bị môi trường phát triển. Chúng ta sẽ sử dụng Python 3.12 trong lớp học lập trình này và sử dụng python virtualenv để đơn giản hoá nhu cầu tạo và quản lý phiên bản python cũng như môi trường ảo

  1. Nếu bạn chưa mở cửa sổ dòng lệnh, hãy mở bằng cách nhấp vào Terminal (Cửa sổ dòng lệnh) -> New Terminal (Cửa sổ dòng lệnh mới) hoặc sử dụng tổ hợp phím Ctrl + Shift + C

8635b60ae2f45bbc.jpeg

  1. Tạo thư mục mới và thay đổi vị trí thành thư mục này bằng cách chạy lệnh sau
mkdir agent_diet_planner
cd agent_diet_planner
  1. Tạo virtualenv mới bằng cách chạy lệnh sau
python -m venv .env
  1. Kích hoạt virtualenv bằng lệnh sau
source .env/bin/activate
  1. Tạo requirements.txt. Nhấp vào Tệp → Tệp văn bản mới rồi điền nội dung bên dưới. Sau đó, hãy lưu tệp dưới dạng requirements.txt
streamlit==1.33.0
google-cloud-aiplatform
google-cloud-bigquery
pandas==2.2.2
db-dtypes==1.2.0
pyarrow==16.1.0
  1. Sau đó, hãy cài đặt tất cả các phần phụ thuộc từ requirements.txt bằng cách chạy lệnh sau
pip install -r requirements.txt
  1. Nhập lệnh sau đây để kiểm tra xem bạn đã cài đặt tất cả các phần phụ thuộc của thư viện Python hay chưa
pip list

Thiết lập tệp cấu hình

Bây giờ, chúng ta cần thiết lập các tệp cấu hình cho dự án này. Tệp cấu hình được dùng để lưu trữ thông tin xác thực của biến và tài khoản dịch vụ.

  1. Bước đầu tiên là tạo tài khoản dịch vụ. Nhập tài khoản dịch vụ vào ô tìm kiếm, sau đó nhấp vào tài khoản dịch vụ. 18c210d5d1e2a666.png
  2. Nhấp vào + Tạo tài khoản dịch vụ. Nhập tên Tài khoản dịch vụ rồi nhấp vào tạo và tiếp tục. 67cad62d367e236a.png
  3. Trong phần quyền, hãy chọn vai trò Người dùng tài khoản dịch vụ. Nhấp vào + Thêm một vai trò khác rồi chọn vai trò IAM : Quản trị viên BigQuery, Quản trị viên Cloud Run, Người gọi Cloud Run, Tác nhân dịch vụ Vertex AI và Người dùng Vertex AI, sau đó nhấp vào Xong be84afdc13678f6c.png
  4. Nhấp vào Email tài khoản dịch vụ, nhấp vào phím tab, nhấp vào Thêm khoá → Tạo khoá mới. 50989af3bb9e1538.png
  5. Chọn json rồi nhấp vào Tạo. Lưu tệp tài khoản dịch vụ này vào thiết bị cho bước tiếp theo a4a119672da532da.png
  6. Tạo một thư mục có tên là .streamlit với cấu hình sau. Nhấp chuột phải, nhấp vào Thư mục mới rồi nhập tên thư mục .streamlit
  7. Nhấp chuột phải vào thư mục .streamlit, sau đó nhấp vào New File (Tệp mới) rồi điền giá trị bên dưới. Sau đó, hãy lưu tệp dưới dạng secrets.toml
# secrets.toml (for Streamlit sharing)
# Store in .streamlit/secrets.toml

[gcp]
project_id = "your_gcp_project"
location = "us-central1"

[gcp_service_account]
type = "service_account"
project_id = "your-project-id"
private_key_id = "your-private-key-id"
private_key = '''-----BEGIN PRIVATE KEY-----
YOUR_PRIVATE_KEY_HERE
-----END PRIVATE KEY-----'''
client_email = "your-sa@project-id.iam.gserviceaccount.com"
client_id = "your-client-id"
auth_uri = "https://accounts.google.com/o/oauth2/auth"
token_uri = "https://oauth2.googleapis.com/token"
auth_provider_x509_cert_url = "https://www.googleapis.com/oauth2/v1/certs"
client_x509_cert_url = "https://www.googleapis.com/robot/v1/metadata/x509/your-sa%40project-id.iam.gserviceaccount.com"
  1. Cập nhật giá trị cho project_id, private_key_id, private_key, client_email , client_id , and auth_provider_x509_cert_url dựa trên tài khoản dịch vụ mà bạn đã tạo ở bước trước

Chuẩn bị tập dữ liệu BigQuery

Bước tiếp theo là tạo một Tập dữ liệu BigQuery để lưu kết quả tạo vào BigQuery.

  1. Nhập BigQuery vào ô tìm kiếm rồi nhấp vào BigQuery.
  2. Nhấp vào 2f2e87396859bc74.png, rồi nhấp vào Tạo tập dữ liệu
  3. Nhập mã nhận dạng tập dữ liệu diet_planner_data rồi nhấp vào Tạo tập dữ liệu 2055cda1ee0360bd.png

4. Xây dựng ứng dụng Agent Diet Planner

Chúng ta sẽ tạo một giao diện web đơn giản với 4 đầu vào như sau

43b20db2d5f94f38.png

Thay đổi cân nặng, chiều cao, tuổi và giới tính dựa trên hồ sơ của bạn rồi nhấp vào Tạo. Thao tác này sẽ gọi mô hình LLM Gemini Pro 2.5 trong thư viện Vertex AI và lưu trữ kết quả đã tạo vào BigQuery.

Mã này sẽ được chia thành 6 phần để không quá dài.

Tạo hàm tính toán trạng thái chỉ số khối cơ thể

  1. Nhấp chuột phải vào thư mục agent_diet_planner → Tệp mới → nhập tên tệp bmi_calc.py rồi nhấn Enter
  2. Điền mã bằng nội dung sau
# Add this function to calculate BMI and health status
def calculate_bmi_status(weight, height):
   """
   Calculate BMI and return status message
   """
   height_m = height / 100  # Convert cm to meters
   bmi = weight / (height_m ** 2)
  
   if bmi < 18.5:
       status = "underweight"
       message = "⚠️ Your BMI suggests you're underweight. Consider increasing calorie intake with nutrient-dense foods."
   elif 18.5 <= bmi < 25:
       status = "normal"
       message = "✅ Your BMI is in the healthy range. Let's maintain this balance!"
   elif 25 <= bmi < 30:
       status = "overweight"
       message = "⚠️ Your BMI suggests you're overweight. Focus on gradual weight loss through balanced nutrition."
   else:
       status = "obese"
       message = "❗ Your BMI indicates obesity. Please consult a healthcare provider for personalized guidance."
  
   return {
       "value": round(bmi, 1),
       "status": status,
       "message": message
   }

Tạo ứng dụng chính của nhân viên hỗ trợ lập kế hoạch ăn kiêng

  1. Nhấp chuột phải vào thư mục agent_diet_planner → Tệp mới → nhập tên tệp app.py rồi nhấn Enter.
  2. Điền mã bằng nội dung sau
import os
from google.oauth2 import service_account
import streamlit as st
from google.cloud import bigquery
from vertexai.preview.generative_models import GenerativeModel
import vertexai
import datetime
import time
import pandas as pd
from bmi_calc import calculate_bmi_status

# Get configuration from environment
PROJECT_ID = os.environ.get("GCP_PROJECT_ID", "your_gcp_project_id")
LOCATION = os.environ.get("GCP_LOCATION", "us-central1")

#CONSTANTS Dataset and table in BigQuery
DATASET = "diet_planner_data"
TABLE = "user_plans"

# Initialize Vertex AI
vertexai.init(project=PROJECT_ID, location=LOCATION)

# Initialize BigQuery client
try:
   # For Cloud Run, use default credentials
   bq_client = bigquery.Client()
except:
   # For local development, use service account from secrets
   if "gcp_service_account" in st.secrets:
       service_account_info = dict(st.secrets["gcp_service_account"])
       credentials = service_account.Credentials.from_service_account_info(service_account_info)
       bq_client = bigquery.Client(credentials=credentials, project=PROJECT_ID)
   else:
       st.error("BigQuery client initialization failed")
       st.stop()

Thay đổi giá trị your_gcp_project_id bằng mã dự án của bạn.

Tạo ứng dụng chính của nhân viên hỗ trợ lập kế hoạch chế độ ăn kiêng – setup_bq_tables

Trong phần này, chúng ta sẽ tạo một hàm có tên là setup_bq_table với 1 tham số đầu vào là bq_client. Hàm này sẽ xác định giản đồ trong bảng bigquery và tạo một bảng nếu bảng đó chưa tồn tại.

Điền mã bằng mã sau đây bên dưới mã trước đó trong app.py

# Create BigQuery table if not exists
def setup_bq_table(bq_client):
   dataset_id = f"{st.secrets['gcp']['project_id']}.{DATASET}"
   table_id = f"{dataset_id}.{TABLE}"
  
   schema = [
       bigquery.SchemaField("user_id", "STRING", mode="REQUIRED"),
       bigquery.SchemaField("timestamp", "TIMESTAMP", mode="REQUIRED"),
       bigquery.SchemaField("weight", "FLOAT", mode="REQUIRED"),
       bigquery.SchemaField("height", "INTEGER", mode="REQUIRED"),
       bigquery.SchemaField("age", "INTEGER", mode="REQUIRED"),
       bigquery.SchemaField("gender", "STRING", mode="REQUIRED"),
       bigquery.SchemaField("diet_plan", "STRING", mode="REQUIRED")
   ]
  
   try:
       bq_client.get_table(table_id)
   except:
       table = bigquery.Table(table_id, schema=schema)
       bq_client.create_table(table)
       st.toast("BigQuery table created successfully")

Tạo ứng dụng chính của nhân viên hỗ trợ lập kế hoạch chế độ ăn – generate_diet_plan

Trong phần này, chúng ta sẽ tạo một hàm có tên là generate_diet_plan với 1 tham số đầu vào. Hàm này sẽ gọi mô hình LLM Gemini Pro 2.5 bằng câu lệnh xác định và tạo kết quả.

Điền mã bằng mã sau đây bên dưới mã trước đó trong app.py

# Generate diet plan using Gemini Pro
def generate_diet_plan(params):
   try:
       model = GenerativeModel("gemini-2.5-pro")
       prompt = f"""
       Create a personalized 7-day diet plan for:
       - {params['gender']}, {params['age']} years old
       - Weight: {params['weight']} kg
       - Height: {params['height']} cm
      
       Include:
       1. Daily calorie target
       2. Macronutrient breakdown (carbs, protein, fat)
       3. Meal timing and frequency
       4. Food recommendations
       5. Hydration guidance
      
       Make the plan:
       - Nutritionally balanced
       - Practical for daily use
       - Culturally adaptable
       - With portion size guidance
       """
      
       response = model.generate_content(prompt)
       return response.text
   except Exception as e:
       st.error(f"AI generation error: {str(e)}")
       return None

Tạo ứng dụng chính của công cụ lập kế hoạch chế độ ăn kiêng cho nhân viên hỗ trợ – save_to_bq

Trong phần này, chúng ta sẽ tạo một hàm có tên là save_to_bq với 3 tham số đầu vào : bq_client, user_idplan. Hàm này sẽ lưu kết quả được tạo vào bảng bigquery

Điền mã bằng mã sau đây bên dưới mã trước đó trong app.py

# Save user data to BigQuery
def save_to_bq(bq_client, user_id, plan):
   try:
       dataset_id = f"{st.secrets['gcp']['project_id']}.{DATASET}"
       table_id = f"{dataset_id}.{TABLE}"
      
       row = {
           "user_id": user_id,
           "timestamp": datetime.datetime.utcnow().isoformat(),
           "weight": st.session_state.user_data["weight"],
           "height": st.session_state.user_data["height"],
           "age": st.session_state.user_data["age"],
           "gender": st.session_state.user_data["gender"],
           "diet_plan": plan
       }
      
       errors = bq_client.insert_rows_json(table_id, [row])
       if errors:
           st.error(f"BigQuery error: {errors}")
       else:
           return True
   except Exception as e:
       st.error(f"Data saving error: {str(e)}")
       return False

Tạo ứng dụng chính của nhân viên hỗ trợ lập kế hoạch ăn kiêng – main

Trong phần này, chúng ta sẽ tạo một hàm có tên là main mà không có tham số đầu vào. Hàm này chủ yếu xử lý tập lệnh giao diện người dùng streamlit, hiển thị kết quả đã tạo, hiển thị kết quả đã tạo trước đây từ bảng bigquery và để tải dữ liệu xuống tệp đánh dấu.

Điền mã bằng mã sau đây bên dưới mã trước đó trong app.py

# Streamlit UI
def main():
   st.set_page_config(page_title="AI Diet Planner", page_icon="🍏", layout="wide")
  
   # Initialize session state
   if "user_data" not in st.session_state:
       st.session_state.user_data = None
   if "diet_plan" not in st.session_state:
       st.session_state.diet_plan = None
  
   # Initialize clients
   #bq_client = init_clients()
   setup_bq_table(bq_client)
  
   st.title("🍏 AI-Powered Diet Planner")
   st.markdown("""
   <style>
   .stProgress > div > div > div > div {
       background-color: #4CAF50;
   }
   [data-testid="stForm"] {
       background: #f0f5ff;
       padding: 20px;
       border-radius: 10px;
       border: 1px solid #e6e9ef;
   }
   </style>
   """, unsafe_allow_html=True)
  
   # User input form
   with st.form("user_profile", clear_on_submit=False):
       st.subheader("Your Profile")
       col1, col2 = st.columns(2)
      
       with col1:
           weight = st.number_input("Weight (kg)", min_value=30.0, max_value=200.0, value=70.0)
           height = st.number_input("Height (cm)", min_value=100, max_value=250, value=170)
          
       with col2:
           age = st.number_input("Age", min_value=18, max_value=100, value=30)
           gender = st.selectbox("Gender", ["Man", "Woman"])
      
       submitted = st.form_submit_button("Generate Diet Plan")
      
       if submitted:
           user_data = {
               "weight": weight,
               "height": height,
               "age": age,
               "gender": gender
           }

           st.session_state.user_data = user_data
           # Calculate BMI
           bmi_result = calculate_bmi_status(weight, height)

           # Display BMI results in a visually distinct box
           with st.container():
               st.subheader("📊 Your Health Assessment")
               col1, col2 = st.columns([1, 3])
      
               with col1:
                   st.metric("BMI", bmi_result["value"])
          
               with col2:
                   if bmi_result["status"] != "normal":
                       st.warning(bmi_result["message"])
                   else:
                       st.success(bmi_result["message"])
      
           # Add BMI scale visualization
           st.markdown(f"""
           <div style="background:#f0f2f6;padding:10px;border-radius:10px;margin-top:10px">
           <small>BMI Scale:</small><br>
           <div style="display:flex;height:20px;background:linear-gradient(90deg,
           #4e79a7 0%,
           #4e79a7 18.5%,
           #60bd68 18.5%,
           #60bd68 25%,
           #f28e2b 25%,
           #f28e2b 30%,
           #e15759 30%,
           #e15759 100%);position:relative">
           <div style="position:absolute;left:{min(100, max(0, (bmi_result["value"]/40)*100))}%;top:-5px">

           </div>
           </div>
           <div style="display:flex;justify-content:space-between">
           <span>Underweight (<18.5)</span>
           <span>Healthy (18.5-25)</span>
           <span>Overweight (25-30)</span>
           <span>Obese (30+)</span>
           </div>
           </div>
           """, unsafe_allow_html=True)

           # Store BMI in session state
           st.session_state.bmi = bmi_result         
  
   # Plan generation and display
   if submitted and st.session_state.user_data:
       with st.spinner("🧠 Generating your personalized diet plan using Gemini AI..."):
           #diet_plan = generate_diet_plan(st.session_state.user_data)
           diet_plan = generate_diet_plan({**st.session_state.user_data,"bmi": bmi_result["value"],
                                           "bmi_status": bmi_result["status"]
           })

           if diet_plan:
               st.session_state.diet_plan = diet_plan
              
               # Generate unique user ID
               user_id = f"user_{int(time.time())}"
              
               # Save to BigQuery
               if save_to_bq(bq_client, user_id, diet_plan):
                   st.toast("✅ Plan saved to database!")
  
   # Display generated plan
   if st.session_state.diet_plan:
       st.subheader("Your Personalized Diet Plan")
       st.markdown("---")
       st.markdown(st.session_state.diet_plan)
      
       # Download button
       st.download_button(
           label="Download Plan",
           data=st.session_state.diet_plan,
           file_name="my_diet_plan.md",
           mime="text/markdown"
       )
      
       # Show history
       st.subheader("Your Plan History")
       try:
           query = f"""
               SELECT timestamp, weight, height, age, gender
               FROM `{st.secrets['gcp']['project_id']}.{DATASET}.{TABLE}`
               WHERE user_id LIKE 'user_%'
               ORDER BY timestamp DESC
               LIMIT 5
           """
           history = bq_client.query(query).to_dataframe()
           if not history.empty:
               history["timestamp"] = pd.to_datetime(history["timestamp"])
               st.dataframe(history.style.format({
                   "weight": "{:.1f} kg",
                   "height": "{:.0f} cm"
               }))
           else:
               st.info("No previous plans found")
       except Exception as e:
           st.error(f"History load error: {str(e)}")

if __name__ == "__main__":
   main()

Lưu mã có tên app.py.

5. Triển khai ứng dụng bằng Cloud Build lên Cloud Run

Tất nhiên, chúng ta muốn giới thiệu ứng dụng tuyệt vời này cho những người khác. Để làm như vậy, chúng ta có thể đóng gói ứng dụng này và triển khai ứng dụng đó vào Cloud Run dưới dạng một dịch vụ công cộng mà người khác có thể truy cập. Để làm được điều đó, hãy xem lại kiến trúc

84e3f3620dc4ed68.png

Trước tiên, chúng ta cần Dockerfile, hãy nhấp vào File->New Text File (Tệp->Tệp văn bản mới), rồi sao chép và dán mã sau, sau đó lưu mã đó dưới dạng Dockerfile

# Use official Python image
FROM python:3.12-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV PORT 8080

# Install system dependencies
RUN apt-get update && \
   apt-get install -y --no-install-recommends \
   build-essential \
   libpq-dev \
   && rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /app

# Copy requirements
COPY requirements.txt .

# Install Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# Copy application files
COPY . .

# Expose port
EXPOSE $PORT

# Run the application
CMD ["streamlit", "run", "app.py", "--server.port", "8080", "--server.address", "0.0.0.0"]

Tiếp theo, chúng ta sẽ tạo cloudbuid.yaml để tạo các ứng dụng thành hình ảnh Docker, đẩy vào sổ đăng ký cấu phần phần mềm và triển khai vào Cloud Run.

Nhấp vào File->New Text File (Tệp->Tệp văn bản mới), rồi sao chép và dán mã sau, sau đó lưu mã này dưới dạng cloudbuild.yaml

steps:
 # Build Docker image
 - name: 'gcr.io/cloud-builders/docker'
   args: ['build', '-t', 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID', '--no-cache',
        '--progress=plain',
        '.']
   id: 'Build'
   timeout: 1200s
   waitFor: ['-']
   dir: '.'
  # Push to Container Registry
 - name: 'gcr.io/cloud-builders/docker'
   args: ['push', 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID']
   id: 'Push'
   waitFor: ['Build']
  # Deploy to Cloud Run
 - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
   entrypoint: gcloud
   args:
     - 'run'
     - 'deploy'
     - 'diet-planner-service'
     - '--image=gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID'
     - '--port=8080'
     - '--region=us-central1'
     - '--platform=managed'
     - '--allow-unauthenticated'
     - '--set-env-vars=GCP_PROJECT_ID=$PROJECT_ID,GCP_LOCATION=us-central1'
     - '--cpu=1'
     - '--memory=1Gi'
     - '--timeout=300'
   waitFor: ['Push']

options:
 logging: CLOUD_LOGGING_ONLY
 machineType: 'E2_HIGHCPU_8'
 diskSizeGb: 100

images:
 - 'gcr.io/$PROJECT_ID/diet-planner:$BUILD_ID'

Đến đây, chúng ta đã có tất cả các tệp cần thiết để tạo ứng dụng thành hình ảnh Docker, đẩy vào sổ đăng ký cấu phần phần mềm và triển khai vào Cloud Run. Hãy triển khai ứng dụng. Chuyển đến Cloud Shell Terminal và đảm bảo dự án hiện tại được định cấu hình cho dự án đang hoạt động của bạn. Nếu không, bạn phải dùng lệnh gcloud configure để đặt mã dự án:

gcloud config set project [PROJECT_ID]

Sau đó, hãy chạy lệnh sau để tạo các ứng dụng thành hình ảnh Docker, đẩy vào sổ đăng ký cấu phần phần mềm và triển khai vào Cloud Run

gcloud builds submit --config cloudbuild.yaml

Thao tác này sẽ tạo vùng chứa Docker dựa trên Dockerfile mà chúng ta đã cung cấp trước đó và đẩy vùng chứa đó vào Artifact Registry. Sau đó, chúng ta sẽ triển khai hình ảnh đã tạo vào Cloud Run. Tất cả quy trình này được xác định trong các bước cloudbuild.yaml.

Xin lưu ý rằng chúng tôi đang cho phép truy cập chưa xác thực tại đây vì đây là một ứng dụng minh hoạ. Bạn nên sử dụng phương thức xác thực phù hợp cho các ứng dụng doanh nghiệp và ứng dụng phát hành công khai.

Sau khi quá trình triển khai hoàn tất, chúng ta có thể kiểm tra quá trình này trong trang Cloud Run, tìm kiếm Cloud Run trong thanh tìm kiếm bảng điều khiển đám mây ở trên cùng rồi nhấp vào sản phẩm Cloud Run

3c460765656fc072.png

Sau đó, bạn có thể kiểm tra dịch vụ đã triển khai có trong trang Dịch vụ Cloud Run. Nhấp vào dịch vụ đó để lấy URL dịch vụ

93dc975d3caeab0e.png

URL của dịch vụ sẽ nằm trên thanh trên cùng

9325464321c106f8.pngHãy tiếp tục sử dụng ứng dụng của bạn trong cửa sổ Ẩn danh hoặc trên thiết bị di động. Nội dung đó đã được xuất bản.

6. Dọn dẹp

Để tránh phát sinh phí cho tài khoản Google Cloud của bạn đối với các tài nguyên được dùng trong lớp học lập trình này, hãy làm theo các bước sau:

  1. Trong Google Cloud Console, hãy chuyển đến trang Quản lý tài nguyên.
  2. Trong danh sách dự án, hãy chọn dự án mà bạn muốn xoá, rồi nhấp vào Xoá.
  3. Trong hộp thoại, hãy nhập mã dự án rồi nhấp vào Tắt để xoá dự án.
  4. Ngoài ra, bạn có thể chuyển đến Cloud Run trên bảng điều khiển, chọn dịch vụ bạn vừa triển khai rồi xoá.