> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# 部署到 Google Cloud

在 Cloud Build 上構建套件的 Docker 映象，用託管金鑰在 Cloud Run 上執行，並繫結你的域名。

## 初學者演練

前提條件：應用在本地可用、一個可以從網際網路訪問的真實資料庫（設定資料庫），以及你要上線的功能對應的服務商賬戶。你需要一個 Google 賬戶；配置結算時會要求繫結銀行卡，儘管輕度使用仍在免費額度內。

快速術語：容器映象是應用打包後的副本，任何主機都能執行。Artifact Registry 是 Google 存放映象的倉庫。Cloud Build 在 Google 的機器上構建映象——本地不需要 Docker。Cloud Run 把映象作為 HTTPS 服務執行並自動擴縮。Secret Manager 儲存密碼和金鑰。修訂版本（revision）是服務的一次部署版本。

你將構建的內容：一個 Google Cloud 專案、一個存放映象的 Artifact Registry 倉庫、一個通過 HTTPS 提供應用的 Cloud Run 服務、存放在 Secret Manager 中的金鑰，以及一個託管 Postgres。套件根目錄的 `Dockerfile` 已經能產出一個監聽 8080 埠的獨立 Next.js 伺服器——正是 Cloud Run 所期望的。

誠實的成本說明：Cloud Run 的免費額度可以覆蓋輕度流量，但 Cloud SQL——Google 的託管 Postgres——沒有免費層。Supabase 或 Neon 的免費資料庫是最便宜的起步方式；本指南走這條路。建議在 Billing → Budgets & alerts 下新增預算提醒，然後再開始折騰。

[設定資料庫](https://supastack.dev/zh-tw/docs/web/setup-database.md)

[先建立 OAuth 賬戶](https://supastack.dev/zh-tw/docs/web/external-accounts.md)


## 建立賬戶並安裝 CLI

1. 開啟 [console.cloud.google.com](https://console.cloud.google.com)，用你的 Google 賬戶登入並接受條款。

2. 按提示關聯結算：Billing → Link a billing account → Create billing account。啟用賬戶需要銀行卡；試用額度可以覆蓋早期實驗。

3. 點選專案下拉選單 → New Project，命名並 Create——或複用你為 Google 登入建立的專案；一個專案就夠了。

4. 從 [cloud.google.com/sdk](https://cloud.google.com/sdk/docs/install) 安裝 Google Cloud CLI：下載適合你作業系統的安裝程式並完成安裝，然後開啟一個新終端，讓 `gcloud` 命令可用。

5. 執行下面兩條命令。第一條會開啟瀏覽器為 CLI 授權；第二條選擇你的專案——使用控制台儀錶板上顯示的專案 ID，它不一定和名稱相同。

預期結果：`gcloud config list` 顯示你的賬戶和專案。如果 `gcloud` 無法識別，重新開啟終端或先完成安裝程式。

```
gcloud auth login
gcloud config set project YOUR_PROJECT_ID
```


## 建立生產資料庫

新手路徑——Google 之外的託管 Postgres。在 [supabase.com](https://supabase.com)：New project → 選擇名稱、資料庫密碼和區域 → 等待初始化 → Project Settings → Database。Supabase 提供兩種連線串：5432 埠的會話池/直連，和 6543 埠的事務池——5432 串用於遷移和長連線客戶端，6543 串用於無伺服器應用。在 [neon.tech](https://neon.tech)：New project → 複製它顯示的連線串。兩者都可以；保持密碼部分完整。

把直連/會話串放進根目錄 `.env` 的 `DATABASE_URL`——遷移工具讀取根目錄檔案且需要會話連線——以及 `apps/web/.env.local` 供本地開發伺服器使用。然後從倉庫根目錄執行一次遷移命令，在新資料庫中建立套件的表。已部署應用使用的 `DATABASE_URL` 金鑰也可以換成 6543 的池化串。

Google 原生替代方案是 Cloud SQL——同一專案內的託管 Postgres。它沒有免費層，且私有 IP 連線需要 VPC 聯結器——把它當作以後的升級，而不是起點。

```
# DATABASE_URL=<the direct/session Postgres string, port 5432> in .env + apps/web/.env.local, then:
corepack pnpm --filter @supastack/db db:migrate
```


## 啟用服務並推送映象

從倉庫根目錄執行下面的命令。它們會啟用本次部署用到的四個 Google 服務、在 Artifact Registry 中建立 Docker 倉庫，並把倉庫提交給 Cloud Build——它在遠端構建根目錄的 `Dockerfile`，因此不需要 Docker Desktop。

替換 `YOUR_PROJECT_ID`，並選擇一個區域——下面是 `us-central1`——倉庫和服務都複用它。預期結果：構建日誌滾動數分鐘，以 `DONE` / `STATUS: SUCCESS` 結束。隨後映象會出現在控制台的 Artifact Registry → supastack → web 下。

```
gcloud services enable run.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com secretmanager.googleapis.com

gcloud artifacts repositories create supastack --repository-format=docker --location=us-central1

gcloud builds submit --tag us-central1-docker.pkg.dev/YOUR_PROJECT_ID/supastack/web:latest
```


## 把金鑰存入 Secret Manager

金鑰絕不能進入 `--set-env-vars` 或映象——兩者都以明文儲存，任何能讀取服務配置的人都看得見。Secret Manager 讓它們保持加密並在執行時注入。

1. 在控制台開啟 Security → Secret Manager → Create Secret。

2. 建立 `DATABASE_URL`，值為完整的 Postgres 連線串——池化的無伺服器串對應用來說就可以；`AUTH_SECRET`，至少 32 個隨機字元（`openssl rand -hex 32` 可以生成一個）；以及 `CREDENTIAL_ENCRYPTION_KEY`，值為 Base64 編碼的 32 位元組金鑰（`openssl rand -base64 32`）；它用於加密工作區在應用中儲存的服務商金鑰。

3. 為每個已啟用的服務商各建一個金鑰——例如 `STRIPE_SECRET_KEY` 加 `STRIPE_WEBHOOK_SECRET`、`RESEND_API_KEY`、`GOOGLE_CLIENT_SECRET`、`GITHUB_CLIENT_SECRET`。像 `EMAIL_PROVIDER=resend` 這樣的非機密設定保持為普通環境變數，不要做成金鑰。

服務第一次引用某個金鑰時，它的執行時服務賬戶需要讀取許可權——通過控制台的服務編輯器掛載金鑰時，Google 會自動提供該授權；在 CLI 上，部署錯誤會報出需要授予的 Secret Manager 角色名。

```
# Secrets to create in Secret Manager:
DATABASE_URL     # Postgres connection string — the pooled serverless string is fine
AUTH_SECRET      # openssl rand -hex 32
CREDENTIAL_ENCRYPTION_KEY   # openssl rand -base64 32

# plus one per enabled provider, e.g.:
STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET
RESEND_API_KEY
GOOGLE_CLIENT_SECRET
GITHUB_CLIENT_SECRET
```


## 部署 Cloud Run 服務

控制台路徑：Cloud Run → Create service → Deploy one revision from an existing container image → 選擇剛推送的 `…/supastack/web:latest` 映象 → 選擇相同區域 → 在 Authentication 下選擇 Allow unauthenticated invocations（這是一個公開應用）→ Create。

下面的 CLI 等價命令在同一步驟中加上環境變數接線。明文配置放進 `--set-env-vars`；金鑰在 `--set-secrets` 中按 Secret Manager 名稱引用。把你的服務商開關（`EMAIL_PROVIDER`、`BILLING_PROVIDER`、`AI_PROVIDER`、`JOB_PROVIDER`）作為普通環境變數與 `APP_URL` 並列新增。

`APP_ENV=production` 是必需的——沒有它，應用會以 `local` 模式啟動：生產配置校驗被跳過，安全 cookie 字首保持關閉，僅限開發的 `/mail-preview` 頁面仍然公開可訪問（當 `EMAIL_PROVIDER=local` 時會洩露本地郵件發件箱）。生產環境在啟動時還需要另外四個值：`EXPO_PUBLIC_API_URL` 是移動應用訪問 API 所用的公開 https URL——設為服務 URL（純 Web 部署時與 `APP_URL` 相同）；`EXPO_PUBLIC_APP_SCHEME` 是移動端深鏈 scheme——不上線移動應用時，任何合法值如 `supastack` 都可以；`MOBILE_ALLOWED_ORIGINS` 是伺服器信任的精確 https origin 的逗號分隔列表——你的應用 URL 就是正確的起點，萬用字元會被拒絕；`CREDENTIAL_ENCRYPTION_KEY` 加密已儲存的服務商憑據，留在 Secret Manager 中。

首次部署時 Cloud Run 會分配一個 `https://….run.app` URL，而應用的 `APP_URL` 必須等於它的真實公開 URL，認證回撥和連結才能工作。所以先用佔位符部署一次，從服務頁面複製 `*.run.app` URL，然後更新服務（控制台：Edit & deploy new revision，或重新執行該命令），把 `APP_URL`——以及對應的 `EXPO_PUBLIC_API_URL` / `MOBILE_ALLOWED_ORIGINS` 值——設定為它。容器埠保持 8080——Cloud Run 的預設值已經與 `Dockerfile` 的 `PORT` 一致。

```
gcloud run deploy supastack --image us-central1-docker.pkg.dev/YOUR_PROJECT_ID/supastack/web:latest --region us-central1 --allow-unauthenticated --set-env-vars "APP_ENV=production,APP_URL=https://YOUR_SERVICE_URL,EXPO_PUBLIC_API_URL=https://YOUR_SERVICE_URL,EXPO_PUBLIC_APP_SCHEME=supastack,MOBILE_ALLOWED_ORIGINS=https://YOUR_SERVICE_URL" --set-secrets "DATABASE_URL=DATABASE_URL:latest,AUTH_SECRET=AUTH_SECRET:latest,CREDENTIAL_ENCRYPTION_KEY=CREDENTIAL_ENCRYPTION_KEY:latest"
```


## 繫結你自己的域名（可選）

測試期間可以跳過——`*.run.app` URL 已經提供 HTTPS。準備好後：Cloud Run → 你的服務 → Custom Domains / Domain Mappings → Add mapping → 選擇服務並輸入你的域名。

如有提示請驗證域名所有權（Google 會引導你完成），然後在你的域名註冊商處建立對映螢幕列出的 DNS 記錄。記錄生效後，託管的 HTTPS 證書會自動簽發——通常幾分鐘，最長一天。

域名開始承載流量後，把 `APP_URL` 更新為 `https://yourdomain.com`，並註冊對應的 OAuth redirect URI（`https://yourdomain.com/api/auth/callback/…`）——登入指南會說明在哪裡配置。


## 驗證部署

開啟 `https://YOUR_SERVICE_URL/api/health`——應返回 `ok`。然後端到端走一遍應用：開啟 URL、註冊、請求郵件驗證碼、確認它能到達收件箱（這需要 `EMAIL_PROVIDER=resend`、`RESEND_API_KEY` 和已驗證的發件人——本地介面卡永遠到不了真實收件箱）、登入並使用一個你啟用的功能。

Cloud Run → 你的服務 → Logs 顯示請求和錯誤輸出。如果部署出問題，Revisions 選項卡提供一鍵回滾到上一個修訂版本。

移動端和桌面客戶端必須指向這個 HTTPS 後端：Expo 用 `apps/mobile/.env.local` 中的 `EXPO_PUBLIC_API_URL`，桌面外殼用 `SUPASTACK_APP_URL`。

[建立移動端賬戶](https://supastack.dev/zh-tw/docs/mobile/external-accounts.md)

[執行完整部署清單](https://supastack.dev/zh-tw/docs/web/deployment.md)


如果你想繼續完成設定，可以閱讀《[部署清單](https://supastack.dev/zh-tw/docs/web/deployment.md)》。


## 下一篇

[部署清單](https://supastack.dev/zh-tw/docs/web/deployment.md)
