🛠️ 最近在部署 LINE 機器人到 Google Cloud Functions(Gen2)時,碰到一個常見又很容易卡住的錯誤:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'dotenv' imported from /workspace/xxx.js
其實這是因為我在本機使用 .env
開發環境變數,但部署到 GCP 時沒有處理好 dotenv 套件的使用方式。
✅ 問題情境
在本地開發的時候,我透過 dotenv
載入 .env
檔案,來讀取 API 金鑰與環境設定。但部署到 GCP Cloud Functions(Gen 2)後,卻出現 container health check 失敗、container exit(1) 等錯誤訊息。
檢查 log 發現是:
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'dotenv'
🧭 解法比較:方法 A vs 方法 B
🔹 方法 A:安裝 dotenv
套件(推薦)
npm install dotenv --save
然後在你的入口檔案(例如 secretManager.js
或 index.js
)中這樣寫:
import 'dotenv/config';
優點:
- 簡單、通用,在本機、GCP、其他平台都能運行。
- 不用改程式邏輯,.env 在本地、環境變數在 GCP,各自運作。
缺點:
- 正式環境會多載入 dotenv,但實際上不影響效能或安全。
🔹 方法 B:僅在本地載入 dotenv
// secretManager.js
if (!process.env.K_SERVICE) {
const { default: dotenv } = await import('dotenv');
dotenv.config();
}
優點:
- 正式環境不會額外載入不需要的套件。
- 更「乾淨」,遵循 12 Factor App。
缺點:
- 較難理解與維護,需額外判斷條件。
- 若將來轉移到非 GCP 平台,條件式判斷要再調整。
🧪 實用的檢查與排錯指令
✅ 部署指令(可一行執行):
gcloud functions deploy line-bot-gemini-node-js-dev --gen2 --runtime=nodejs20 --region=asia-east1 --source=. --entry-point=lineWebhook --trigger-http --allow-unauthenticated --set-env-vars=NODE_ENV=development,GOOGLE_MAPS_API_KEY=xxx,GOOGLE_CLOUD_PROJECT_ID=souvenir-ai-assistant-dev
🔍 查看最新失敗 log:
gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=line-bot-gemini-node-js-dev" --project=souvenir-ai-assistant-dev --limit=50 --format="value(textPayload)"
找 Cannot find package 'dotenv' 或 exit(1) 是常見錯誤關鍵字。
🌐 開放公開存取權限(如 webhook 需要 LINE 打得進來):
gcloud functions add-iam-policy-binding line-bot-gemini-node-js-dev --region=asia-east1 --member="allUsers" --role="roles/cloudfunctions.invoker"
🚀 我最後選了哪個?
我選擇 方法 A,因為:
- 我希望未來能將這支 bot 搬到其他雲端平台或本地伺服器。
- 用 dotenv 管理 .env.dev / .env.prod 對我來說更方便。
- 開發效率為主,少一個坑卡自己!
💬 如果你也踩過這個坑...
歡迎留言分享你的做法或部署心得,也可以收藏這篇當作未來部署 LINE bot 的小抄 ✨
或者你現在就遇到 exit(1)
問題,不妨先檢查一下你是不是用了 dotenv
卻沒安裝它 😅