GCP 部署完整指南:Cloud Run 與 Cloud Function 實作
「Google Cloud Platform 好像很厲害,但服務那麼多,我該從哪個開始?」
這是很多想嘗試 GCP 部署的開發者都有的疑問。相比 AWS 的複雜,GCP 其實提供了更直覺的部署體驗,尤其是 Cloud Run 和 Cloud Functions 這兩個服務,幾乎是「寫完程式碼就能上線」的程度。
這篇文章會帶你從零開始,了解 GCP 各種部署服務的差異,並實際動手完成 Cloud Run 和 Cloud Functions 的部署。
GCP 部署服務總覽
GCP 提供多種部署服務,各有不同定位。在開始實作前,先搞清楚它們的差異,才能選對工具。
Compute Engine vs App Engine vs Cloud Run
GCP 的運算服務可以分成三大類:
| 服務 | 類型 | 控制程度 | 適合情境 | 計費方式 |
|---|---|---|---|---|
| Compute Engine | IaaS | 最高 | 需要完整 VM 控制 | 按小時計費 |
| App Engine | PaaS | 中等 | 傳統 Web 應用程式 | 按實例時間 |
| Cloud Run | Serverless 容器 | 低 | 容器化應用程式 | 按請求計費 |
Compute Engine 就像你自己買了一台電腦放在 Google 機房,要自己安裝作業系統、設定網路、管理安全更新。自由度最高,但管理成本也最高。
App Engine 是 Google 最早的 PaaS 服務,你只要上傳程式碼,平台自動處理其他事情。但它的架構比較固定,彈性有限。
Cloud Run 是目前最受歡迎的選擇,結合了容器的彈性和 Serverless 的便利。你把程式包成 Docker 容器,Cloud Run 自動處理擴展、負載平衡、HTTPS 等。
想深入了解部署的基本概念,可以參考 程式部署完整指南。
Cloud Functions vs Cloud Run 比較
這兩個服務常被拿來比較,因為都是 Serverless 架構:
| 比較項目 | Cloud Functions | Cloud Run |
|---|---|---|
| 部署單位 | 單一函式 | 整個容器 |
| 執行時間限制 | 最長 9 分鐘(HTTP) | 最長 60 分鐘 |
| 記憶體上限 | 32 GB | 32 GB |
| 冷啟動 | 較快 | 稍慢(需啟動容器) |
| 適合場景 | 單一 API、事件處理 | 完整 API 服務 |
| 語言支援 | 特定語言 | 任何語言(Docker) |
Cloud Functions 適合「做一件事」的情境,例如:
- 接收 Webhook 並處理資料
- 定時執行的排程任務
- 檔案上傳後的自動處理
Cloud Run 適合「完整服務」的情境,例如:
- RESTful API 後端
- 網頁應用程式
- 微服務架構
如何選擇適合的服務
簡單的決策流程:
- 需要完整掌控 VM? → Compute Engine
- 只是單一函式或 Webhook? → Cloud Functions
- 已經有 Docker 容器? → Cloud Run
- 想要最簡單的部署體驗? → Cloud Run(source deploy)
對於大多數情況,Cloud Run 是最推薦的選擇,因為它平衡了彈性和便利性。
Cloud Run 部署實戰
接下來我們實際動手,把一個 Python Flask API 部署到 Cloud Run。
什麼是 Cloud Run?
Cloud Run 是 Google 的「全託管容器平台」,它的核心概念是:
你只管寫程式和打包容器,Google 負責其他所有事情。
Cloud Run 的特色:
- 自動擴展:流量大就自動開更多實例,沒流量就縮回 0
- 按請求計費:沒有流量就不收錢
- 免設定 HTTPS:自動提供 SSL 憑證
- 支援自訂網域:可以綁定自己的網域
準備 Docker 容器
以一個簡單的 Python Flask API 為例:
app.py
from flask import Flask, jsonify
import os
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify({
'message': 'Hello from Cloud Run!',
'version': '1.0.0'
})
@app.route('/health')
def health():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 8080))
app.run(host='0.0.0.0', port=port)
requirements.txt
flask==3.0.0
gunicorn==21.2.0
Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 app:app
幾個重點:
- PORT 環境變數:Cloud Run 會透過這個變數告訴你要監聽哪個 Port
- gunicorn:Production 環境建議使用 gunicorn 而不是 Flask 內建 server
- slim 映像:使用較小的基礎映像,加快部署速度
部署到 Cloud Run
方法一:直接從原始碼部署(最簡單)
如果你不想自己建 Docker 映像,Cloud Run 可以自動幫你處理:
# 安裝 gcloud CLI(如果還沒安裝)
# https://cloud.google.com/sdk/docs/install
# 登入 GCP
gcloud auth login
# 設定專案
gcloud config set project YOUR_PROJECT_ID
# 直接從原始碼部署
gcloud run deploy my-api \
--source . \
--region asia-east1 \
--allow-unauthenticated
Cloud Run 會自動偵測你的程式語言,建立容器映像並部署。
方法二:手動建立並推送容器
如果需要更多控制,可以自己建容器:
# 啟用必要的 API
gcloud services enable artifactregistry.googleapis.com
gcloud services enable run.googleapis.com
# 建立容器映像
gcloud builds submit --tag gcr.io/YOUR_PROJECT_ID/my-api
# 部署到 Cloud Run
gcloud run deploy my-api \
--image gcr.io/YOUR_PROJECT_ID/my-api \
--region asia-east1 \
--allow-unauthenticated
設定自訂網域
預設的 Cloud Run URL 長這樣:https://my-api-xxxxx-de.a.run.app
如果想用自己的網域,例如 api.yourdomain.com:
# 驗證網域所有權
gcloud domains verify yourdomain.com
# 對應網域
gcloud run domain-mappings create \
--service my-api \
--domain api.yourdomain.com \
--region asia-east1
然後到你的 DNS 設定,新增一筆 CNAME 記錄指向 ghs.googlehosted.com。
Cloud Run 會自動處理 SSL 憑證,完全不用手動設定。
想了解更多 AWS 的對比方案,可以參考 AWS 部署教學。
💡 Docker 設定卡關? 容器化對新手來說確實有些門檻。如果你在打包容器時遇到問題,讓 VibeFix 幫你處理,我們有豐富的 GCP 部署經驗。
Cloud Functions 部署實戰
如果你的需求只是「一個 API 端點」或「處理事件」,Cloud Functions 會更輕量。
什麼是 Cloud Functions?
Cloud Functions 是 Google 的 Function as a Service(FaaS) 服務,核心概念是:
一個函式處理一件事,用多少算多少。
與 Cloud Run 相比,Cloud Functions 更適合:
- 單純的 API 端點
- Webhook 接收器
- 事件驅動的處理(檔案上傳、訊息佇列等)
撰寫第一個 Function
main.py
import functions_framework
from flask import jsonify
@functions_framework.http
def hello_world(request):
"""HTTP Cloud Function."""
name = request.args.get('name', 'World')
return jsonify({
'message': f'Hello, {name}!',
'method': request.method
})
requirements.txt
functions-framework==3.*
flask==3.0.0
Cloud Functions 使用 functions-framework 套件來處理 HTTP 請求,這讓你可以在本機測試:
# 本機測試
pip install functions-framework
functions-framework --target hello_world --debug
# 瀏覽器打開 http://localhost:8080
部署與測試
# 部署 HTTP 觸發的 Function
gcloud functions deploy hello-world \
--gen2 \
--runtime python311 \
--region asia-east1 \
--source . \
--entry-point hello_world \
--trigger-http \
--allow-unauthenticated
部署完成後,會得到一個 URL,可以直接測試:
curl https://asia-east1-YOUR_PROJECT.cloudfunctions.net/hello-world?name=VibeFix
# {"message": "Hello, VibeFix!", "method": "GET"}
設定觸發器
Cloud Functions 支援多種觸發方式:
HTTP 觸發(最常見)
gcloud functions deploy my-function \
--gen2 \
--trigger-http
Pub/Sub 觸發(訊息佇列)
@functions_framework.cloud_event
def process_message(cloud_event):
import base64
data = base64.b64decode(cloud_event.data["message"]["data"])
print(f"Received: {data}")
gcloud functions deploy process-message \
--gen2 \
--trigger-topic YOUR_TOPIC_NAME
Cloud Storage 觸發(檔案事件)
@functions_framework.cloud_event
def process_file(cloud_event):
data = cloud_event.data
bucket = data["bucket"]
name = data["name"]
print(f"File uploaded: gs://{bucket}/{name}")
gcloud functions deploy process-file \
--gen2 \
--trigger-event-filters="type=google.cloud.storage.object.v1.finalized" \
--trigger-event-filters="bucket=YOUR_BUCKET_NAME"
GCP 部署最佳實踐
部署成功只是第一步,接下來要確保服務穩定運行。
環境變數管理
不要把機密資訊寫死在程式碼裡!Cloud Run 和 Cloud Functions 都支援環境變數:
設定環境變數
# Cloud Run
gcloud run deploy my-api \
--set-env-vars="DB_HOST=xxx,API_KEY=yyy"
# Cloud Functions
gcloud functions deploy my-function \
--set-env-vars="DB_HOST=xxx,API_KEY=yyy"
使用 Secret Manager(推薦)
對於真正敏感的資訊(API Key、資料庫密碼),建議使用 Secret Manager:
# 建立 Secret
echo -n "my-api-key" | gcloud secrets create api-key --data-file=-
# 在 Cloud Run 中使用
gcloud run deploy my-api \
--set-secrets="API_KEY=api-key:latest"
程式碼中直接讀取環境變數:
import os
api_key = os.environ.get('API_KEY')
日誌與監控
GCP 內建了完整的監控工具,不需要額外設定:
Cloud Logging
所有 print() 和 logging 輸出都會自動送到 Cloud Logging:
import logging
logging.info("Processing request...")
在 GCP Console 可以搜尋、過濾日誌。
Cloud Monitoring
Cloud Run 和 Cloud Functions 自動收集這些指標:
- 請求次數
- 回應時間(延遲)
- 錯誤率
- 記憶體使用量
- CPU 使用量
你可以設定警示,例如「錯誤率超過 5% 就發通知」。
費用控制
Serverless 的優點是按用量計費,但也要注意不要爆帳。
Cloud Run 免費額度(每月)
- 200 萬次請求
- 360,000 GB-秒 記憶體
- 180,000 vCPU-秒 運算
Cloud Functions 免費額度(每月)
- 200 萬次調用
- 400,000 GB-秒 記憶體
- 200,000 GHz-秒 運算
設定預算警示
強烈建議設定預算警示:
# 在 GCP Console → Billing → Budgets & alerts
# 設定每月預算,例如 $10
# 當使用量達到 50%、80%、100% 時發送通知
限制最大實例數
避免流量爆發時開太多實例:
gcloud run deploy my-api \
--max-instances 10
想深入了解 Python 的部署技巧,可以參考 Python 部署指南。
FAQ 常見問題
Cloud Run 和 Cloud Functions 哪個比較便宜?
兩者的計費模式類似,都是按請求次數和運算資源計費。對於小流量應用,兩者費用差不多。如果你的服務需要持續運行或處理時間較長,Cloud Run 可能更划算。
Cloud Run 冷啟動要多久?
通常在 1-3 秒之間,取決於容器大小和程式複雜度。可以設定「最小實例數」來避免冷啟動:
gcloud run deploy my-api --min-instances 1
但這會產生持續費用。
可以在 Cloud Run 上跑資料庫嗎?
技術上可以,但不建議。Cloud Run 的檔案系統是暫時性的,每次重啟都會清空。資料庫建議使用 Cloud SQL 或 Firestore。
Cloud Functions 的執行時間限制可以調整嗎?
HTTP 觸發的 Function 最長 9 分鐘,事件觸發的最長 9 分鐘。這是硬性限制,無法調整。如果你需要更長的執行時間,請使用 Cloud Run。
如何設定 CI/CD 自動部署?
最簡單的方式是使用 Cloud Build:
# cloudbuild.yaml
steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
entrypoint: gcloud
args:
- 'run'
- 'deploy'
- 'my-api'
- '--source=.'
- '--region=asia-east1'
把這個檔案加到 Git repository,然後在 Cloud Build 設定觸發器,就能實現 push 自動部署。
想了解更多容器化知識,可以參考 Docker Deploy 教學。
結語
GCP 的 Cloud Run 和 Cloud Functions 是目前最友善的 Serverless 部署方案,尤其適合:
- 個人開發者:免費額度足夠跑小專案
- 新創團隊:按用量計費,初期成本低
- 想快速驗證想法:幾分鐘就能部署上線
如果你是第一次嘗試雲端部署,建議從 Cloud Run 開始,因為它的彈性最高,未來要擴展也比較容易。
重點整理:
- 選對服務:大多數情況 Cloud Run 是最佳選擇
- 善用免費額度:小專案幾乎不用花錢
- 設定預算警示:避免意外帳單
- 使用 Secret Manager:保護機密資訊
🔧 雲端部署搞不懂? GCP 的服務確實很多,一開始會有點眼花撩亂。如果你在選擇服務或設定部署時遇到困難,讓 VibeFix 協助你規劃雲端架構,我們熟悉各種雲端平台的特性,能幫你找到最適合的方案。