每週固定節奏
先理解本週要解決的部署問題,再完成本週交付物,最後用驗收句確認成果能接到下一週。
course outcome report
nuva course outcome report
20 週逐步閱讀、製作、驗收與交接的 n8n 部署課程成果報告。每週都包含導讀、實作任務、驗收標準與完整原文講義。
How to read this report
這不是把 20 份文件簡單合併成長文,而是把整套 n8n 部署學習路線整理成「每週可閱讀、可製作、可驗收」的課程報告。每一週先看導讀與任務,再展開完整原文講義核對細節。
先看本週任務、關鍵概念與原始講義全文。
依照交付物清單做出可保存的文件、設定或演練紀錄。
用 acceptance criteria 檢查是否能被下一週接住。
把成果放進 handoff、runbook 或作品包,留下 owner 與證據。
先理解本週要解決的部署問題,再完成本週交付物,最後用驗收句確認成果能接到下一週。
每週頁面下方都放入來源週文件全文,包含表格、Mermaid 圖、檢查清單、官方來源與交付物說明。
報告會不斷追問 state 在哪裡、public URL 是否正確、誰負責更新、如何備份、何時需要擴展。
Learning Architecture
整套課程的主線是「搬家」:從只會打開 n8n,搬到能說明部署選擇、保護資料、公開 webhook、選平台、維護更新、演練事故,最後交出可複製作品包。
先學會判斷 Cloud、local、VPS、PaaS、hyperscaler 的責任邊界,再把 state、DNS、public URL 與 proxy 概念放到同一張圖上。
從 Docker Desktop 開始做出可保留資料的本機 n8n,再比較 npm 與 container,最後用 tunnel 安全地練習 webhook。
把 n8n Cloud、VPS、PaaS、Cloud Run 與 AWS 類型平台放進同一個決策表,用成本、持久化與維運責任做選擇。
補齊資料庫、binary data、備份還原、更新、安全修補與 scaling gate,讓部署不是只停在能開機。
用 troubleshooting drill、cost-risk worksheet、可複製作品包與最終驗收,把學習成果轉成能交接的部署方法。
學概念、保留資料、建立本機操作信心。
短期測試 webhook 與 OAuth callback,不當 production edge。
低維運優先 Cloud;需要控制權則用 VPS + Compose。
用 runbook、patch cadence、capacity gate 管理長期風險。
在需求證明後擴展,不用一開始過度工程。
Week by Week
點選任一週可直接跳到對應課程頁。建議每週按順序完成,因為後面的 runbook、troubleshooting 與 final recommendation 都會引用前面建立的 state、URL、database、backup 與 platform decision 模型。
1.0 本週定位
第一週的任務,是先回答「n8n 到底有哪些部署方式,為什麼不能只問 cloud 還是 local?」這不是實作指令週,而是部署決策週。你要先看懂每種部署路線背後的責任邊界,再決定後續要往本機、Cloud、VPS、PaaS 或企業雲端走。
本週已完成三個主要交付物與一個口頭驗收稿。閱讀時請把它們視為同一套決策工具:先用矩陣比較部署方式,再用流程圖選路線,最後用風險詞彙表檢查自己是否漏掉 production responsibility。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| 一頁部署選項矩陣 | 完成 | 1.3 | 能快速比較 Cloud、local、VPS、PaaS、hyperscaler、Kubernetes 的定位。 |
| 一張需求判斷流程圖 | 完成 | 1.4 | 能從需求回答走到合理部署路線。 |
| 一份風險詞彙表 | 完成 | 1.5 | 至少涵蓋 uptime、public URL、persistence、patching、backup。 |
| 三分鐘驗收說明 | 完成 | 1.6 | 能說清楚 local Docker 適合學習,但不適合長期 public webhook production。 |
不要急著把 n8n 跑起來。先學會判斷部署路線,因為後面每一週的 Docker、PostgreSQL、Tunnel、VPS、PaaS、backup、security、scaling 都會回到這張 Week 01 決策地圖。
整合來源:docs/week-01-n8n-deployment-framework.md
05本週只採用官方文件作為事實基礎,避免把部落格、二手整理或平台行銷話術直接當成部署決策。讀這一節時,請把每一列當成後續章節的判斷前提。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
| n8n 建議多數 self-hosting 使用 Docker;self-hosting 需要能管理伺服器、容器、資源、擴展與安全。 | Docker 是主要 self-hosting 路線;缺乏維運經驗時,n8n 建議使用 n8n Cloud。 | n8n Docker Installation |
| n8n Cloud 是託管方案,主打免技術設定與維護、uptime monitoring、managed OAuth、one-click upgrades。 | 這是 beginner 與低維運團隊的低風險起點。 | n8n Cloud Overview |
| self-hosted n8n 預設使用 SQLite 儲存 credentials、past executions、workflows,也支援 PostgreSQL。 | production-like 部署應優先把資料庫責任納入設計。 | n8n Supported Databases |
| 反向代理後需要明確設定 public webhook URL,並處理 proxy hops。 | WEBHOOK_URL 與 N8N_PROXY_HOPS=1 是 webhook 與 OAuth URL 正確性的核心。 | Webhook URL with Reverse Proxy |
| n8n 內建 tunnel 僅供本機開發與測試,不適合 production。 | 不能把隨機或開發 tunnel 當長期 public edge。 | n8n Docker Installation |
| Cloudflare Quick Tunnels 僅供 testing and development;production 應使用 remotely-managed tunnel。 | Quick Tunnel 的 random subdomain 不適合長期 callback。 | Cloudflare Quick Tunnels |
| Docker Desktop 包含 Docker Engine、Docker CLI、Docker Compose。 | 這就是 Week 05 本機實作採用 Docker Desktop 的原因。 | Docker Desktop Docs |
| n8n queue mode 透過 worker instances 擴展,並可加入 webhook processors 作為下一層 scaling。 | 這是 Week 16 的內容,本週只放入決策圖,不提前實作。 | n8n Queue Mode |
| self-hosted n8n 必須保持版本更新。 | patching 是 public self-hosted 的基本責任。 | Update self-hosted n8n |
| Railway、Render、Zeabur、Fly 均提供某種 persistent storage 或 managed database 能力,但使用方式與限制不同。 | PaaS 可行性取決於 volume、database、domain、TLS 與 secrets 是否正確配置。 | Railway · Render · Zeabur · Fly |
第一週的核心判斷不是「哪個平台最好」,而是「哪個平台的責任剛好匹配目前需求」。n8n Cloud 把最多維運責任交給 n8n;local Docker 把學習成本降到最低;VPS + Compose 在控制、成本與理解度之間取得平衡;PaaS 用平台能力換取部分維運簡化;hyperscaler 與 Kubernetes 則用複雜度換取企業級控制。
| 部署選項 | 最適合情境 | State 層 | Public URL | 維運責任 | Production 判斷 | 第一週結論 |
|---|---|---|---|---|---|---|
| n8n Cloud | 初學者、非工程團隊、想專注做 workflow 而不是管伺服器 | n8n 管理 | n8n 管理 | 最低,主要是 workflow 與帳號治理 | 是,視 plan 與功能需求而定 | 最低風險起點。若沒有明確 self-host 理由,應優先評估。 |
| Local Docker Desktop | 學習、練習、短期 prototype、本機測試 | Docker volume 或本機 .n8n | 無;只在 localhost | 使用者本機 | 否 | 適合學習 n8n 概念與本機持久化,不適合長期公開 webhook。 |
| Local npm | 快速看 editor、一次性測試、教學展示 | 本機 .n8n | 無;只在 localhost | 使用者本機與 Node.js 環境 | 否 | 啟動最快,但環境隔離與長期維護弱於 Docker。 |
| Local + Tunnel | 本機測試外部 webhook、短期 demo、OAuth callback 實驗 | 本機 Docker volume 或 .n8n | tunnel provider 提供 | 使用者本機加 tunnel provider | 通常否 | 可學習 public webhook,但 random 或 quick tunnel 不能當長期 production edge。 |
| VPS + Docker Compose | 個人 production、小團隊、freelancer、需要穩定 domain 與完整控制 | PostgreSQL 加 Docker volumes | 自有 domain 加 reverse proxy | 使用者負責 OS、Docker、n8n、DB、backup、security | 是 | self-hosted sweet spot。複雜度可控,責任也明確。 |
| PaaS container platform | 想減少 Linux server 維運,但仍想 self-host container | managed Postgres 加 persistent volume | 平台 domain 或 custom domain | 平台負責部分 infra,使用者負責 app config、storage、secrets、backup 策略 | 有條件是 | 可行,但必須先確認 storage 非 ephemeral。不能只看部署成功。 |
| Hyperscaler managed stack | 已在 AWS/GCP/Azure、有 IAM、合規、內網、企業治理需求 | managed DB、secret manager、object storage | load balancer 或 managed ingress | shared responsibility,架構與成本較高 | 是 | 強大但組裝成本高。沒有治理或規模需求時,不是第一週建議起點。 |
| Kubernetes / GKE / EKS / AKS | 已有 Kubernetes 團隊、需要多環境、HA、標準化平台能力 | managed DB、PVC、secret manager | ingress controller 或 load balancer | 最高,需要平台工程能力 | 是 | 不應作為初學起點。只有既有平台能力或明確 HA 需求時才合理。 |
使用這張流程時,不要從平台名稱開始選,而是從需求責任開始問。每一個答案都會把你推向更合適的部署路線。
這張表把流程圖中的關鍵分岔整理成可操作的問題。每次評估一個 n8n 部署需求,都先逐列回答,再把答案對應回部署選項。
| 問題 | 如果答案是「是」 | 如果答案是「否」 |
|---|---|---|
| 只是學習嗎? | 用 Local Docker Desktop,先理解 state 與 workflow。 | 繼續問是否需要 public access 與 production 責任。 |
| 需要長期 public webhook 嗎? | 需要穩定 domain、HTTPS、WEBHOOK_URL、backup、patching。 | 可以先留在 localhost 或短期 tunnel。 |
| 想避免伺服器維運嗎? | 優先看 n8n Cloud 或 PaaS。 | 可以評估 VPS + Compose。 |
| 需要 host-level control 嗎? | self-host 比 Cloud 更合理。 | Cloud 通常是更穩的低維運路線。 |
| 是否已有雲端平台治理需求? | 可以進 AWS/GCP/Azure managed stack。 | 不要為了看起來正式而過早採用 hyperscaler。 |
| 是否已有 Kubernetes 操作能力? | Kubernetes 可被列入長期架構。 | 不把 Kubernetes 當第一階段部署方案。 |
這些詞不是背誦用,而是部署前的檢查語言。只要你開始談 production,就要能用這些詞拆解責任。
| 詞彙 | 本週定義 | 常見錯誤 | 正確判斷 | 第一個檢查點 |
|---|---|---|---|---|
| uptime | n8n 可以被使用者、外部服務或排程穩定觸發的時間比例。 | 以為本機能跑就等於服務穩定。 | 本機 uptime 等於電腦、網路、Docker、睡眠設定都穩定;正式使用要看平台與維運能力。 | 服務是否依賴個人電腦開機與網路? |
| public URL | 外部服務、OAuth provider、使用者實際看到並呼叫的 n8n 網址。 | 用 localhost、random tunnel URL 或錯誤 proxy host 設 webhook。 | production webhook 需要穩定、可預期、HTTPS 的 public URL。 | WEBHOOK_URL 與 N8N_EDITOR_BASE_URL 是否等於外部看到的網址? |
| persistence | workflow、credentials、executions、binary data、community nodes、設定能否在重啟、redeploy、換機後保留。 | 只看到容器啟動,沒有確認 volume 或 DB。 | production-like 部署要明確設計 database、volume、encryption key。 | 重建 container 後資料是否還在? |
| patching | 持續更新 n8n、OS、container image、proxy、database 的安全與相容性責任。 | 以為 automation tool 裝好後可以不更新。 | public self-hosted instance 必須有固定更新節奏與 rollback 方法。 | 目前 n8n 版本、image tag、更新流程是否記錄? |
| backup | 可以在資料遺失、升級失敗、主機故障後恢復 n8n 的完整資料集合與流程。 | 只備份 workflow JSON,忘了 DB、volume、encryption key。 | backup 至少要涵蓋 database、n8n volume、encryption key、Compose/env/proxy config。 | 是否做過 restore drill,而不是只有 backup 檔? |
這些詞會在後續週次反覆出現。Week 01 先建立語言,後面再把它們落到 Docker、PostgreSQL、Tunnel、VPS、PaaS、backup 與 scaling 的具體操作。
| 詞彙 | 本週定義 | 決策影響 |
|---|---|---|
| state layer | n8n 依賴的資料層,包含 DB、volume、binary data、credential encryption key。 | 決定 local、VPS、PaaS、cloud stack 是否可靠。 |
| public edge | 接收 internet traffic 的入口,可能是 tunnel、reverse proxy、platform ingress、load balancer。 | 決定 HTTPS、headers、domain、firewall、exposure risk。 |
| shared responsibility | 平台與使用者各自負責的維運邊界。 | Cloud 責任較少,VPS 責任較多,PaaS 介於兩者之間。 |
| ephemeral filesystem | redeploy 或 restart 後可能消失的檔案系統。 | 對 n8n 是高風險,因為 user folder 與 community nodes 可能需要持久化。 |
| stable callback | OAuth 或 webhook provider 設定中可長期使用、不會隨機改變的 callback URL。 | 影響 tunnel 是否可用、domain 是否必買、production 是否穩定。 |
| scaling path | 從單機到 PostgreSQL、Redis queue、worker、webhook processor 的漸進路線。 | 防止太早 Kubernetes,也防止單機過載後沒有升級路線。 |
| cost model | plan、execution、RAM、CPU、storage、egress、always-on 的計價方式。 | PaaS 與 hyperscaler 必須估算使用量,不能只看起始價格。 |
| recovery point | 發生事故時可以回復到哪個時間點的資料。 | 決定 backup 頻率與是否需要 managed DB snapshot。 |
| recovery time | 發生事故後多久可以恢復服務。 | 決定 Cloud、VPS、PaaS 或 managed stack 是否符合業務要求。 |
| security perimeter | public exposure、login、2FA、SSO、firewall、proxy、secret handling 的整體邊界。 | public self-hosted n8n 的風險遠高於 local-only instance。 |
Local Docker 適合學習,但不適合長期 public webhook production。Local Docker Desktop 是很好的 n8n 學習起點,因為它能用最少設定讓使用者看見 n8n editor、建立 workflow、測試 credential,並透過 Docker volume 學到「資料需要持久化」這件事。它也比 npm 更接近正式部署,因為 container、port mapping、volume、image tag 這些概念會延伸到 Docker Compose 與 VPS。
但 local Docker 不適合長期 public webhook production,原因有五個。第一,uptime 依賴個人電腦;只要電腦睡眠、關機、網路斷線、Docker Desktop 停止,webhook 就無法被外部服務觸發。第二,localhost 不是外部服務可以長期呼叫的 public URL;如果透過 tunnel 補上 public access,random 或 development tunnel 又會帶來 URL 不穩定、callback 變動與 production exposure 的問題。第三,本機環境通常沒有正式的 reverse proxy、TLS、firewall、monitoring、alerting 與 backup discipline。第四,production n8n 要保護 database、volume、encryption key 與 workflow execution data,本機測試環境很容易漏掉 restore drill。第五,公開 self-hosted n8n 必須持續 patch,local Docker 學習環境通常沒有明確的更新、rollback 與安全責任分工。
所以 Week 01 的結論是:local Docker 適合學習 n8n 如何運作,也適合作為 Week 05 到 Week 08 的實作基礎;但只要需求變成長期 public webhook、OAuth callback、多人使用、客戶服務或營運流程,部署路線就要升級到 n8n Cloud、VPS + Docker Compose + PostgreSQL + reverse proxy,或具備 persistent storage 與 managed database 的 PaaS。
先理解 n8n editor、workflow、credential、volume 與 state。
確認資料不只在 container 裡,還包含 DB、volume、key 與 binary data。
釐清 localhost、tunnel、domain、reverse proxy、callback 的差異。
若答案是 yes,就要選 Cloud、VPS、PaaS 或 managed stack。
正式路線必須能回答 backup、restore、update、monitoring 與 rollback。
本週完成的判斷是:n8n 部署不是二選一題,而是責任分配題。最重要的五個變數是 uptime、public URL、persistence、patching、backup。只要其中任何一項變成 production requirement,local-only 或 random tunnel setup 就不能被視為正式部署。
| 使用者型態 | 第一週推薦路線 | 理由 |
|---|---|---|
| 完全初學者 | n8n Cloud 或 Local Docker Desktop | Cloud 降低維運風險;Local Docker 建立技術理解。 |
| 想做個人自動化 | Local Docker Desktop 開始,之後依 public webhook 需求進 VPS 或 PaaS | 不先過度設計,保留升級路徑。 |
| 需要長期 webhook 的 freelancer | VPS + Docker Compose + PostgreSQL + reverse proxy | 成本、控制與可理解性平衡。 |
| 想少管伺服器的小團隊 | n8n Cloud 或 PaaS container platform | 維運責任較低,但 PaaS 必須確認 persistence。 |
| 已有企業雲端治理需求的團隊 | Hyperscaler managed stack | IAM、network、secrets、logging、compliance 可整合。 |
| 已有 Kubernetes 團隊 | Kubernetes 可列入長期選項 | 只有既有平台能力時才值得承擔複雜度。 |
Week 02 會進入「n8n 如何運作」,把本週 decision matrix 往下拆到 application、database、credentials、executions、binary data、public URL 的關係。Week 01 不實作部署指令,因為本週的工作是防止一開始選錯路線。
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 01 計畫要求 | 通過 |
| 已核對官方來源 | 通過 |
| 已完成部署選項矩陣 | 通過 |
| 已完成需求判斷流程圖 | 通過 |
| 已完成風險詞彙表 | 通過 |
| 已完成三分鐘驗收說明 | 通過 |
| 未把後續週次內容提前實作 | 通過 |
| 未使用未核對的第三方平台宣稱作為核心依據 | 通過 |
2.0 本週定位
Week 02 的核心問題是:n8n 的 application、database、credentials、executions、binary data、public URL 如何互相影響?這一週要把 n8n 從「一個可以打開的 UI」拆成 runtime process、state layer、public edge 與 external integrations。
本週所有產出都在回答同一件事:換容器、換主機、換資料庫或換 URL 時,哪些東西不能丟。請先看交付物,再回到後面每一張 state 圖與 inventory 表。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| n8n runtime architecture 圖 | 完成 | 2.3 | 能看懂 browser、public edge、n8n process、database、user folder、binary data、external APIs 的關係。 |
| state inventory 表 | 完成 | 2.4 | 能逐項說明 workflow、credential、execution history、binary data、.n8n、encryption key 的保存位置與備份責任。 |
| credential-loss 風險說明卡 | 完成 | 2.5 | 能判斷 credentials 為什麼會在換容器、換主機、換 volume 或換 encryption key 時失效。 |
| 驗收說明 | 完成 | 2.6 | 能解釋為什麼換容器或換主機時,保存 encryption key 與 volume 不是可選項。 |
Week 01 教你選路線;Week 02 開始拆「搬家清單」。如果你只能記一句話:n8n container 可以重建,但 n8n state 不能靠重建補回。
整合來源:docs/week-02-n8n-runtime-state-model.md
16本週只採用官方文件作為事實基礎。尤其是 state 與 encryption key,不能靠印象處理。每一列都是後面「搬家清單」的依據。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
| self-hosted n8n 預設使用 SQLite,資料庫儲存 credentials、past executions、workflows,也支援 PostgreSQL。 | database 是 n8n state layer 的核心,不是附屬品。 | n8n Supported Databases |
n8n 會在使用者的 .n8n 資料夾保存 user-specific data,例如 encryption key、SQLite database file、tunnel ID。 | .n8n 不是暫存目錄,對本機與 Docker volume 都是關鍵。 | Specify user folder path |
Docker 安裝範例會把 n8n_data volume 掛到 /home/node/.n8n,用來在 container restart 後保留資料。 | container 本身可重建,但 volume 不可隨便丟。 | n8n Docker Installation |
n8n 第一次啟動會產生 random encryption key 並保存在 ~/.n8n;credentials 在存進 database 前會用這個 key 加密。 | 資料庫和 encryption key 必須成對保存。 | Set a custom encryption key |
N8N_ENCRYPTION_KEY 可提供自訂 key;queue mode 下所有 workers 都必須指定同一個 encryption key。 | 多 process 或 worker 架構更不能讓 key 漂移。 | Encryption key · Queue mode |
N8N_EDITOR_BASE_URL 是使用者可存取 editor 的 public URL,也用於 email 與 SAML redirect URL。 | public URL 不只影響瀏覽器,也影響身份驗證與通知連結。 | Deployment environment variables |
reverse proxy 後需設定 WEBHOOK_URL,並設定 N8N_PROXY_HOPS=1,讓 n8n 註冊正確 webhook URL。 | public edge 與 n8n process 的內外網址不一致時,必須顯式設定。 | Configure webhook URLs with reverse proxy |
| execution data 會讓 database 成長;n8n 建議不要保存不必要資料,並啟用 pruning。 | execution history 是容量與隱私風險來源。 | Execution data |
binary data 位置依版本與 N8N_DEFAULT_BINARY_DATA_MODE 設定而定;memory mode 可能因大檔案造成 crash,v2 breaking changes 說 regular mode 預設 filesystem、queue mode 預設 database。 | 不能在文件裡把 binary data 永遠寫死在單一位置。 | Binary data scaling · n8n v2.0 breaking changes |
community nodes 安裝在硬碟;Docker 重建或升級時若沒有保存 ~/.n8n/nodes,可能出現 missing packages。 | custom/community nodes 也屬於 state inventory。 | Community nodes troubleshooting |
n8n 的 browser/editor 與 webhook endpoint 都會回到同一個 application process;process 再讀寫 database、user folder、binary data storage,並呼叫 external APIs。credential records 在 database 裡,但解密依賴 encryption key。
Docker learning mode 的重點是:container 可以刪掉重建,但 n8n_data volume 不可以被當成暫存物。若使用預設 SQLite,database file 與 encryption key 都會落在 .n8n 這個 state boundary 裡。
這就是為什麼 Week 05 做 Docker Desktop 時,驗收重點不是「n8n 打得開」,而是「container 重建後,volume 裡的 workflow 與 credential probe 還在」。
Production-shaped 模式要把三層分清楚:public edge 負責接 internet traffic,n8n application process 負責執行 workflow,state layer 負責保存 workflow、credential、execution、binary data 與 encryption material。三層任何一層錯,都會讓同一個 workflow 呈現不同錯誤。
domain、TLS、headers、WEBHOOK_URL、N8N_EDITOR_BASE_URL。
執行 workflow、接 webhook、呼叫 external APIs。
保存 workflows、credentials、executions、key、files。
Queue mode 是 Week 16 才深入的擴展主題。本週只建立一個基本觀念:只要同一個 n8n deployment 有多個 main 或 worker process,所有 process 都必須共享能讀取 credentials 的同一組 encryption key,並共同指向一致的 database state。
Queue mode 不是「加幾台機器」這麼簡單。worker 能不能跑,取決於它是否能讀到同一個 database、同一個 queue,以及同一把 key。
這張表是 Week 02 最重要的搬家清單。每一個 state 項目都要回答:用途是什麼、存在哪裡、能不能重建、遺失後會怎樣、誰要備份。
| State 項目 | 主要用途 | 典型保存位置 | 可否重建 | 遺失後影響 | 第一備份責任 |
|---|---|---|---|---|---|
| Workflows | 保存節點、連線、trigger、workflow 設定與版本內容。 | n8n database:預設 SQLite,production 常用 PostgreSQL。 | 可從 export 或 source control 部分重建,但不是完整替代 database。 | workflow 消失、trigger 不存在、團隊無法編輯或執行既有流程。 | database backup;另可搭配 workflow export。 |
| Credentials | 保存 API key、OAuth token、database password 等敏感連線資料。 | n8n database 中的 encrypted credentials。 | 不能靠 workflow JSON 完整重建;通常要重新授權或重新輸入。 | workflow 仍在,但節點無法連外部服務;OAuth integration 失效。 | database backup 加同一個 encryption key。 |
| Encryption key | 解密 credentials 與敏感資料的 master key 或 instance key。 | ~/.n8n settings file,或以 N8N_ENCRYPTION_KEY 環境變數注入。 | 不可等價重建;新 key 不能解舊資料。 | database 還在但 credentials 無法解密,等同 credential loss。 | secret manager、.env 安全備份、deployment config。 |
| Executions | 保存 workflow run 的狀態、輸入輸出、錯誤與除錯資訊。 | n8n database;保存量受 execution settings 與 pruning 影響。 | 歷史紀錄不可完整重建。 | 無法追蹤歷史錯誤、稽核與除錯資訊消失。 | database backup;同時設定 pruning 策略。 |
| Binary data | 工作流處理的檔案,例如圖片、PDF、文件、音訊。 | 依版本與 N8N_DEFAULT_BINARY_DATA_MODE:memory、filesystem、database、S3-compatible storage。 | 通常不可重建,除非來源系統仍保留原檔。 | 文件處理 workflow 失敗,歷史 execution 的檔案參照失效。 | 依實際 mode 備份 volume、database 或 external storage。 |
n8n 的 state 不只在 database。user folder、community nodes、environment variables、public URL 與 proxy config 都會影響「搬家後能不能照常運作」。
| State 項目 | 主要用途 | 典型保存位置 | 可否重建 | 遺失後影響 | 第一備份責任 |
|---|---|---|---|---|---|
.n8n user folder | 保存 user-specific data,例如 encryption key、SQLite database file、tunnel ID、settings、部分本機資料。 | Linux/macOS 常見為 ~/.n8n;Docker official path 為 /home/node/.n8n,通常掛 volume。 | 不可當成純 cache。 | 使用預設 SQLite 時可能同時失去 database 與 encryption key。 | Docker volume backup 或 host folder backup。 |
| Community nodes | 自行安裝的 community node packages。 | ~/.n8n/nodes 等本機硬碟位置。 | 可重新安裝,但版本與啟動時間會有風險。 | workflow 找不到 node package,啟動或執行失敗。 | 保存 .n8n/nodes 或記錄版本並配置 reinstall 策略。 |
| Environment variables | 控制 DB、URL、execution、binary data、security、proxy、feature flags。 | .env、平台 env settings、secret manager、container config。 | 可重建,但前提是有文件與 secret。 | public URL 錯、DB 連不上、credentials 無法解密、binary data mode 改變。 | deployment config backup 與 secret manager。 |
| Public URL settings | 讓 n8n 產生正確 editor links、webhook URL、email link、SAML/OAuth redirect。 | N8N_EDITOR_BASE_URL、WEBHOOK_URL、N8N_HOST、N8N_PROTOCOL、N8N_PROXY_HOPS。 | 可修正,但錯誤期間會造成 integration 失敗。 | webhook 註冊錯誤、OAuth callback mismatch、email 或 SAML redirect 錯誤。 | .env、reverse proxy config、DNS 記錄。 |
| Reverse proxy config | TLS termination、domain routing、forwarded headers、public edge。 | Caddyfile、Nginx config、Traefik labels、platform ingress settings。 | 可重建,但需知道 domain 與 headers。 | HTTPS、webhook、OAuth、UI 存取錯誤。 | proxy config backup 與 DNS 記錄。 |
保護順序的重點是先保住不可等價重建的東西。workflow export 很有用,但它不能取代 database、encryption key 與 volume。
| 優先級 | State | 原因 |
|---|---|---|
| P0 | Encryption key | 沒有同一把 key,encrypted credentials 可能無法解密。 |
| P0 | Database | workflows、credentials、executions 的主要保存地。 |
| P0 | .n8n volume 或 user folder | 預設 SQLite、settings、generated encryption key、community nodes 都可能在這裡。 |
| P1 | Environment variables and secrets | 決定 database、URL、binary data、security 與 worker 是否正確。 |
| P1 | Reverse proxy and DNS config | 決定 public access、OAuth、webhook URL 是否正確。 |
| P1 | Binary data storage | 檔案型 workflow 與 execution data 需要它才能完整回復。 |
| P2 | Workflow exports | 可當輔助備份,但不能取代 database 與 credentials。 |
| P2 | Screenshots and manual setup notes | 可協助人工恢復,但不是正式 backup。 |
這張表把常見遷移、重建與擴展情境拆成「要保存什麼」與「不保存會怎樣」。這就是 Week 03 備份責任表的前置資料。
| 情境 | 需要保存什麼 | 不保存會怎樣 |
|---|---|---|
| 只刪除並重建 Docker container | 保留 n8n_data volume;若使用 external DB,也要保留 DB 連線與 encryption key。 | container 會回來,但 workflows、credentials 或 SQLite DB 可能消失。 |
| 從 SQLite 搬到 PostgreSQL | 保存舊 SQLite database、encryption key、migration/export 流程、volume。 | credentials 可能不可讀,workflow migration 不完整。 |
| 從一台 VPS 搬到另一台 VPS | 搬 database、.n8n volume、N8N_ENCRYPTION_KEY、env、proxy、DNS。 | 新主機能啟動 n8n,但舊 credentials、webhook URL 或 binary data 失效。 |
| PaaS redeploy | 確認 database 是 managed 或 volume 持久化,確認 env secrets 沒有變。 | service 看似 redeploy 成功,但 state 被重置。 |
| 加入 queue workers | 所有 main 與 workers 使用同一 database、Redis、N8N_ENCRYPTION_KEY。 | worker 拿到 execution ID 卻無法讀取或解密 workflow credential。 |
| 改變 binary data mode | 記錄舊 mode,確保舊資料仍能被讀取或遷移。 | historical execution 的 binary references 可能無法被 pruning 或讀取。 |
Credential loss 通常不是「credential 不見了」這麼單純,而是 database、key、volume、URL 或 storage 其中一層失配。
| 欄位 | 說明 |
|---|---|
| 症狀 | workflows 還在,credential records 也可能還在 database 裡,但節點授權失敗或 credential 無法正常使用。 |
| 根因 | n8n credentials 存入 database 前會用 encryption key 加密;換了 key,就不能等價解舊資料。 |
| 高風險動作 | 刪掉 .n8n folder、換 Docker volume、換 VPS 沒帶 N8N_ENCRYPTION_KEY、PaaS 重建 env secrets。 |
| 預防 | production-like deployment 一律顯式設定 N8N_ENCRYPTION_KEY,並放在 secret manager 或安全的 .env 備份中。 |
| 修復 | 找回原 key;若找不回,只能重新建立或重新授權 credentials。 |
| 驗收句 | database backup 沒有 encryption key,不是完整 backup。 |
| 欄位 | 說明 |
|---|---|
| 症狀 | n8n 能啟動,key 也正確,但 workflow、credential、execution history 不存在。 |
| 根因 | database 是 workflows、credentials、past executions 的主要保存地;只有 key 沒有資料可解。 |
| 高風險動作 | SQLite database file 隨 .n8n 消失、PostgreSQL volume 被刪、PaaS 沒有 managed DB 或 persistent volume。 |
| 預防 | 使用 PostgreSQL 時安排 database backup;使用 SQLite 學習時保留整個 .n8n volume。 |
| 修復 | 還原 database backup,再使用同一把 key 啟動。 |
| 驗收句 | encryption key 是鑰匙,database 是保險箱;兩者缺一個都不能恢復 credential state。 |
| 欄位 | 說明 |
|---|---|
| 症狀 | workflow 與 credentials 都存在,但 webhook 或 OAuth callback 失敗。 |
| 根因 | n8n process 內部可能只知道 localhost:5678,但外部服務需要看到 https://n8n.example.com。 |
| 高風險動作 | 加 reverse proxy 或 tunnel 後,沒設定 WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS。 |
| 預防 | public edge 一變,就同步檢查 n8n public URL env vars、OAuth provider callback、proxy headers。 |
| 修復 | 設定正確 public URL,重新註冊或更新外部服務 webhook/OAuth callback。 |
| 驗收句 | state 正確只能保證資料還在,不能保證外部世界打得到正確入口。 |
| 欄位 | 說明 |
|---|---|
| 症狀 | workflow history 還在,但歷史 execution 的檔案、圖片、PDF 或附件讀不到;或大檔 workflow 不穩定。 |
| 根因 | binary data 位置依 N8N_DEFAULT_BINARY_DATA_MODE 與 n8n 版本而定,可能在 memory、filesystem、database 或 S3-compatible storage。 |
| 高風險動作 | 改 binary data mode、換 worker/queue mode、只備份 DB 但漏備 volume 或 external storage。 |
| 預防 | 在 deployment inventory 中記錄實際 binary data mode,並把對應 storage 納入 backup。 |
| 修復 | 回復原 storage mode 與資料位置;若原始 binary files 已遺失,只能從外部來源重跑或重新上傳。 |
| 驗收句 | binary data 不是「一定在 database」或「一定在 volume」,它必須按實際設定檢查。 |
| 欄位 | 說明 |
|---|---|
| 症狀 | n8n 啟動後提示 missing packages,或 workflow 裡的 community node 無法載入。 |
| 根因 | community nodes 安裝在 hard disk;Docker 重建或升級時如果沒保存 ~/.n8n/nodes,package 可能消失。 |
| 高風險動作 | 沒有掛載 .n8n volume、清空 node package folder、PaaS filesystem 是 ephemeral。 |
| 預防 | 保存 ~/.n8n/nodes,或清楚記錄 community node package 與版本。 |
| 修復 | 還原 nodes folder 或重新安裝相同 packages。 |
| 驗收句 | workflow JSON 只能描述 node,用不到 node package 時照樣跑不起來。 |
Credential 能不能恢復,不是只看 credential record。你需要 database、同一把 encryption key、正確 volume、正確 public URL、正確 binary storage 與必要 node packages 一起到位。
為什麼換容器或換主機時,保存 encryption key 與 volume 不是可選項?
換容器或換主機時,保存 encryption key 與 volume 不是可選項,因為 n8n 不是無狀態 web app。n8n 的 database 會保存 workflows、credentials 和 past executions;credentials 在進 database 前會用 encryption key 加密;.n8n user folder 或 Docker volume 又可能保存 generated encryption key、SQLite database file、settings、tunnel ID 和 community nodes。這代表 container image 本身只是一個可重建的 application package,真正能讓舊 workflow 繼續工作的,是 database、volume、encryption key 與 deployment config。
如果只搬 database、不搬 encryption key,encrypted credentials 可能無法解密。反過來,如果只搬 key、不搬 database,workflow、credential records 和 execution history 都不在。若只搬 database 和 key,但漏掉 .n8n volume、binary data storage、community nodes 或 public URL settings,則可能出現檔案遺失、node package missing、webhook URL 錯誤或 OAuth callback mismatch。這就是為什麼 Week 02 的核心結論是:n8n 遷移與備份要以 state inventory 為單位,不是以 container 為單位。
n8n container 可以重建,但 n8n state 不能靠重建補回。database 保存 workflows、credentials、executions;encryption key 決定 credentials 能不能被解密;.n8n volume 可能保存 SQLite、key、settings 和 community nodes。因此換容器或換主機時,database、volume、encryption key、env 與 public URL config 必須一起管理。
這張表可以直接拿來檢查任何一個 n8n deployment。只有全部通過,才可以說自己知道這個 instance 的 state 在哪裡。
| 檢查項 | 通過標準 |
|---|---|
| Database type 已知 | 明確知道目前是 SQLite 還是 PostgreSQL。 |
.n8n 位置已知 | 明確知道 host path、Docker volume 或 N8N_USER_FOLDER。 |
| Encryption key 已保存 | production-like deployment 有固定 N8N_ENCRYPTION_KEY,不是只靠未備份的 generated key。 |
| Credential restore 路徑已知 | 能說明 credentials 需要 database 加同一把 key。 |
| Execution data policy 已知 | 知道是否保存成功/失敗/手動 execution,以及 pruning 設定。 |
| Binary data mode 已知 | 知道實際 N8N_DEFAULT_BINARY_DATA_MODE 與對應 storage。 |
| Public URL 已知 | N8N_EDITOR_BASE_URL 與 WEBHOOK_URL 對得上外部可見網址。 |
| Reverse proxy hops 已知 | behind reverse proxy 時有設定 N8N_PROXY_HOPS 與 forwarded headers。 |
| Community nodes 已盤點 | 若有使用 community nodes,知道 package 保存位置與版本。 |
| Migration bundle 已定義 | 搬家時至少包含 database、volume、encryption key、env、proxy/DNS、binary storage。 |
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 02 計畫要求 | 通過 |
| 已核對官方來源 | 通過 |
| 已完成 n8n runtime architecture 圖 | 通過 |
| 已完成 state inventory 表 | 通過 |
| 已完成 credential-loss 風險說明卡 | 通過 |
| 已完成驗收說明 | 通過 |
| 已處理 binary data 版本差異,不寫死單一保存位置 | 通過 |
| 未把 Week 05 或 Week 07 的部署實作提前執行 | 通過 |
Week 03 會進入「資料保存與安全基礎」,把本週的 state inventory 轉成 SQLite vs PostgreSQL、最小備份組合與 binary-heavy workflow 風險。Week 02 的輸出會直接成為 Week 03 的備份責任表基礎。
n8n 的搬家不是 container 搬家,而是 state 搬家。能啟動新容器,只代表 application package 回來了;能解密 credentials、保留 executions、讀到 binary data、維持 webhook URL,才代表真正搬完。
3.0 本週定位
Week 03 的核心問題是:SQLite、PostgreSQL、volume、binary data、encryption key 各自承擔什麼責任?這週把 Week 02 的 state inventory 轉成資料安全與備份判斷,開始回答 production self-host n8n 到底要備份什麼。
本週的交付物是一套資料安全基礎:先選資料庫,再定義最小備份組合,最後把 binary-heavy workflow 的額外風險補進去。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| SQLite vs PostgreSQL 決策表 | 完成 | 3.3 | 能說明 SQLite 適合學習與單機低風險使用,PostgreSQL 適合 production-like self-hosted 部署。 |
| 最小備份組合 checklist | 完成 | 3.4 | 能列出 production self-host n8n 的最小備份內容:database、volume、encryption key、Compose/env/proxy config。 |
| binary-heavy workflow 注意事項 | 完成 | 3.5 | 能判斷 binary data mode、容量、queue mode、pruning 與 external storage 的影響。 |
| 驗收說明 | 完成 | 3.6 | 能在 60 秒內列出 production self-host n8n 的最小備份內容與理由。 |
Week 03 開始,請不要再把「有 workflow JSON」當成「有備份」。production recovery 看的是 recovery bundle,不是單一 export。
整合來源:docs/week-03-data-safety-foundation.md
32本週只採用官方文件作為事實基礎。資料保存與備份不能靠平台印象或「應該會在某處」來判斷。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
| self-hosted n8n 預設使用 SQLite;SQLite 會保存 credentials、past executions、workflows;n8n 也支援 PostgreSQL。 | database 是 workflows、credentials、executions 的主要保存地。 | Supported databases and settings |
SQLite database file 位置是 ~/.n8n/database.sqlite。 | 若使用 Docker 預設 volume,這個檔案會落在 container 的 /home/node/.n8n 對應 volume 中。 | Supported databases and settings |
n8n database env vars 使用 DB_TYPE=sqlite 或 DB_TYPE=postgresdb;MySQL/MariaDB 已 deprecated。 | Week 03 決策表只比較 SQLite 與 PostgreSQL。 | Database environment variables |
| n8n CLI 可 export entities,支援從 SQLite 匯出並匯入到 Postgres;execution history data tables 預設排除,因為可能很大。 | CLI export 是遷移與輔助備份工具,不等於完整基礎設施備份。 | CLI commands |
| workflow JSON 可匯出/匯入;匯出的 workflow JSON 會包含 credential names 和 IDs。 | workflow export 是輔助備份,不可當成完整 credential backup。 | Export and import workflows |
credentials 可用 CLI export;--decrypted 會輸出明文敏感資料。 | 明文 credential export 只應作為受控遷移手段,不應成為一般備份習慣。 | CLI commands |
這一頁補上資料成長、binary data mode、queue mode 與 source control 邊界。這些都是 Week 03 不能被簡化的資料安全細節。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
execution data 會讓 database 成長;n8n 建議不要保存不必要 execution data,並啟用 pruning;SQLite pruning 後磁碟空間不一定立即釋放,可用 DB_SQLITE_VACUUM_ON_STARTUP 或 manual VACUUM。 | execution retention 是 storage 與隱私管理議題。 | Execution data |
binary data 是檔案型資料,例如 image 或 document;大型 binary data 若留在 memory 可能造成 crash;可用 N8N_DEFAULT_BINARY_DATA_MODE=filesystem 讓資料存到 disk。 | binary-heavy workflow 必須檢查 storage mode 與容量。 | Binary data scaling |
| queue mode 不支援 filesystem binary data storage;queue mode 文件也不建議 SQLite database。 | 需要 worker/queue 時,Week 03 的資料層建議必須升級。 | Queue mode |
binary data environment variables 文件仍列出 memory/default 模式;v2 breaking changes 說 v2 起 regular mode 使用 filesystem、queue mode 使用 database,且 N8N_AVAILABLE_BINARY_DATA_MODES 會移除。 | 文件不得寫死「永遠 memory」或「永遠 filesystem」,必須要求檢查實際版本與 N8N_DEFAULT_BINARY_DATA_MODE。 | Binary data environment variables · n8n v2.0 breaking changes |
| S3 external storage for binary data 是 Self-hosted Enterprise 功能;n8n 支援 AWS S3,其他 S3-compatible service 可用但不屬官方支援。 | 不能把 S3 external storage 當所有 self-hosted 方案的預設選項。 | External storage for binary data |
| source control / environments 不會同步 credentials 與 variable values 到 Git。 | Git/source control 不是 credential backup。 | Environments in n8n |
這張表的重點不是說 SQLite 不好,而是把它放在正確位置:學習、短期測試、低風險單 instance。只要進入長期 public automation,PostgreSQL 就應該成為 production-like baseline。
| 判斷維度 | SQLite | PostgreSQL | Week 03 結論 |
|---|---|---|---|
| 預設性 | self-hosted n8n 沒有設定 database 時的預設。 | 需要明確設定 DB_TYPE=postgresdb 與 DB_POSTGRESDB_*。 | 初學可以接受預設;正式環境應主動選擇。 |
| 保存內容 | 保存 credentials、past executions、workflows。 | 同樣保存 credentials、past executions、workflows。 | 兩者都不是「只放設定」;都是核心 state。 |
| 檔案位置 | ~/.n8n/database.sqlite。Docker 中通常在 /home/node/.n8n volume。 | 外部 PostgreSQL server、managed DB 或 Compose 裡的 postgres volume。 | SQLite 備份常和 .n8n volume 綁一起;PostgreSQL 要有 DB backup 策略。 |
| 適合情境 | 本機學習、短期測試、低風險單 instance。 | production-like self-hosted、VPS、PaaS、multi-worker、可恢復性要求高的情境。 | 只要進入長期 public automation,PostgreSQL 優先。 |
| 備份方式 | 備份 .n8n folder 或 SQLite file,停機/一致性要小心。 | pg_dump、managed DB backup、snapshot、PITR 視平台能力。 | PostgreSQL 的備份與還原流程更適合長期維運。 |
| execution data 成長 | pruning 後空間可能被重用而非立即釋放;可能需 VACUUM。 | 可搭配成熟 DB 維運、監控與容量管理。 | execution retention policy 對 SQLite 更容易變成隱性磁碟問題。 |
| queue mode | 官方文件不建議 queue mode 搭配 SQLite。 | queue mode 的合理資料庫基礎。 | 想走 scaling path,就不要停在 SQLite。 |
| 搬遷能力 | 可用 CLI export entities 作為 SQLite 到 Postgres 的遷移工具。 | 可作為遷移目標,也可再用 DB backup/restore 管理。 | 遷移前要保留 encryption key 和完整備份。 |
| 操作複雜度 | 最低,幾乎不需另外管理 DB。 | 需要 DB 帳密、權限、連線、backup、監控。 | 初期省事,後期可能把風險留到事故時才爆出來。 |
| production 建議 | 不建議作為嚴肅 production default。 | 建議作為 meaningful self-hosted default。 | Week 03 的標準建議:production self-host 以 PostgreSQL 為基準。 |
是:SQLite 可接受。
是:PostgreSQL。
是:PostgreSQL。
PostgreSQL + Redis + shared encryption key。
production self-host n8n 的備份不是單一檔案,而是一組 recovery bundle。這一頁先列 P0:缺少任一項,就可能無法恢復可用服務。
| 必備等級 | 備份項目 | 為什麼必備 | 最低可接受形式 | 驗收方式 |
|---|---|---|---|---|
| P0 | Database | 保存 workflows、encrypted credentials、past executions。 | PostgreSQL:pg_dump、managed backup 或 volume snapshot;SQLite:一致性備份 database.sqlite。 | 能在測試環境還原並看到 workflow 和 credential records。 |
| P0 | Encryption key | 解密 credentials 與敏感資料。 | N8N_ENCRYPTION_KEY 的 secret backup,或保留含 generated key 的 .n8n settings。 | 還原後既有 credentials 可正常使用。 |
| P0 | .n8n user folder / Docker volume | 可能保存 SQLite file、generated encryption key、settings、binary data path、community nodes。 | Docker volume archive、host folder backup、平台 persistent volume snapshot。 | 重建 container 後 .n8n 內容一致。 |
| P0 | Deployment config | 定義 DB、URL、binary mode、security、execution settings。 | docker-compose.yml、.env、platform env export、secret inventory。 | 新環境可用同一設定啟動。 |
| P0 | Reverse proxy config | 決定 TLS、domain、headers、public edge。 | Caddyfile、Nginx config、Traefik labels、platform ingress 設定。 | public editor URL、webhook URL、OAuth callback 都正確。 |
P1 與 P2 不是不重要,而是它們通常依 workload 與維運成熟度決定深度。binary-heavy workflow 與 community nodes 一旦存在,就不能被視為可忽略。
| 必備等級 | 備份項目 | 為什麼必備 | 最低可接受形式 | 驗收方式 |
|---|---|---|---|---|
| P1 | Binary data storage | 檔案型 workflow 需要的實際 binary payload。 | 依 mode 備份 filesystem path、database、S3 bucket 或 managed storage。 | 歷史 execution 的檔案可讀,binary-heavy workflow 可重跑。 |
| P1 | Community nodes | workflow 執行所需的 community package。 | .n8n/nodes backup 或 package/version inventory。 | 重建後 workflow 不出現 missing packages。 |
| P1 | Workflow exports | 輔助版本管理與人工比對。 | n8n export:workflow --backup --output=backups/latest/workflows/。 | 可獨立檢視 workflow JSON,但不把它當唯一備份。 |
| P1 | Credentials export | 輔助遷移,特別是跨 database 或特殊情境。 | n8n export:credentials --backup --output=backups/latest/credentials/;必要時受控使用 --decrypted。 | 未授權人員無法讀取 sensitive data;若用 decrypted export,必須加密保存。 |
| P2 | Restore procedure | 避免只有 backup 沒有 recovery。 | 一份可執行 restore checklist。 | 至少每個 phase gate 做一次文件演練,正式前做測試還原。 |
這張矩陣的關鍵訊息很直白:任何單一 export 幾乎都不是完整備份。唯一能當 recovery baseline 的,是完整 recovery bundle。
| 備份方式 | Workflow | Credentials | Executions | Encryption key | Binary data | Config | 適合作為唯一備份嗎 |
|---|---|---|---|---|---|---|---|
| Workflow JSON export | 部分可 | 否,只含 credential names/IDs 等參照 | 否 | 否 | 否 | 否 | 否 |
| CLI workflow + credentials backup | 可 | 可,但仍需 key 或安全處理 | 通常否 | 否 | 否 | 否 | 否 |
| CLI export entities | 可 | 可 | 可選,需 --includeExecutionHistoryDataTables=true,但可能很大 | 否 | 視模式而定 | 否 | 否 |
| PostgreSQL backup | 可 | 可,仍需同一 encryption key | 可 | 否 | 若 binary mode=database 才包含 binary payload | 否 | 否 |
.n8n volume backup | 視 DB 而定;SQLite 情境可 | 視 DB/key 而定 | 視 DB 而定 | 可能可 | 若 binary mode=filesystem 且 path 在此 volume 可 | 部分可 | 否 |
| Full recovery bundle | 可 | 可 | 可 | 可 | 可 | 可 | 是 |
| 時機 | 必做備份 | 原因 |
|---|---|---|
| 第一次正式上線前 | Full recovery bundle | 建立 baseline。 |
| 每次 n8n 版本升級前 | Database、volume、encryption key、config | 防 migration 或 breaking change。 |
改 N8N_ENCRYPTION_KEY 或啟用 key rotation 前 | Full database backup、key inventory | key 相關變更不可草率。 |
| SQLite 轉 PostgreSQL 前 | SQLite DB、.n8n volume、key、CLI export entities | 遷移失敗時可回退。 |
| 改 binary data mode 前 | 原 mode 對應 storage、DB、config | 避免歷史 binary references 失效。 |
| 加 queue workers 前 | DB、key、env、binary mode 記錄 | workers 需要共同 DB 與 key;filesystem binary mode 不適用 queue mode。 |
Binary-heavy workflow 是大量處理 file-type data 的 workflow,例如圖片、PDF、文件、壓縮檔、音訊、影片、附件、爬蟲下載檔案、AI 生成檔案、OCR 或報表輸出。它的風險不是 workflow 節點多,而是檔案 payload 會佔用 memory、disk、database 或 external storage。
| Mode | 典型意義 | 優點 | 風險 | 備份責任 | Week 03 建議 |
|---|---|---|---|---|---|
| memory / default legacy | binary data 在 execution 期間留在 memory。 | 最少設定。 | 大檔案可能造成 crash;不適合嚴肅 binary-heavy workload。 | 通常不應依賴它保存 binary payload。 | 若處理大檔案,應改成明確 storage mode。 |
| filesystem | binary data 存到 disk,預設 storage path 與 N8N_USER_FOLDER/binaryData 相關。 | 減少 memory 壓力,適合一般 single-instance regular mode。 | 需要 disk capacity、volume backup;queue mode 不支援 filesystem binary data storage。 | 備份 binary data path 或包含它的 volume。 | single-instance self-host 可優先評估。 |
| database | binary data 存到 database。 | queue mode 情境更一致;DB backup 可涵蓋更多 state。 | DB 成長快,backup/restore 變大,效能與容量要監控。 | DB backup、retention policy、storage monitoring。 | queue mode 或多 worker 情境優先確認。 |
| s3 / external storage | binary data 存到 S3 或 S3-compatible store。 | 避免本機 filesystem 承擔大量檔案;適合大規模 binary storage。 | Self-hosted Enterprise 功能;AWS S3 是官方支援,其他 S3-compatible 非官方支援;bucket lifecycle 需要管理。 | bucket data、bucket policy、lifecycle、S3 credentials。 | 只有 enterprise 或大規模 binary data 才納入主方案。 |
| 風險 | 觸發情境 | 影響 | 預防 |
|---|---|---|---|
| Memory crash | 大圖片、PDF、影片、批次附件留在 memory。 | workflow 或 instance crash。 | 設定 filesystem/database/S3 mode,並限制單次檔案大小。 |
| Disk fill-up | filesystem mode 沒有容量監控或 pruning。 | n8n 無法寫入 execution/binary data,甚至整機不穩。 | 監控 binaryData path、設定 retention、安排 volume backup。 |
| Database bloat | database mode 保存大量 binary payload 或 execution data。 | DB backup 變慢、storage 成本增加、restore time 拉長。 | 調整 execution save policy、pruning、DB capacity planning。 |
| Queue incompatibility | queue mode 搭配 filesystem binary data。 | worker 架構不符合官方支援模式。 | queue mode 使用 database 或 enterprise external storage。 |
| S3 lifecycle gap | external storage 沒有 lifecycle policy。 | 舊 binary data 無限累積,成本與隱私風險上升。 | 設定 bucket lifecycle,並記錄 retention policy。 |
| Mode drift | 從 S3 改回 filesystem 或反向切換,沒有保留舊 mode。 | 舊 binary data 可能讀不到或不會被正確 pruning。 | 保留 N8N_AVAILABLE_BINARY_DATA_MODES 與舊 storage credentials,遷移前先盤點。 |
| File node security | Read/Write Files from Disk 或 Local File 類 workflow 讀寫主機檔案。 | 安全邊界擴大,可能讀到不該讀的檔案。 | 限制可讀寫路徑,審核需要 file access 的 workflow。 |
| 檢查項 | 通過標準 |
|---|---|
| 實際 mode 已確認 | 知道目前 N8N_DEFAULT_BINARY_DATA_MODE 與 n8n 版本。 |
| storage path 已確認 | 若是 filesystem,知道 N8N_BINARY_DATA_STORAGE_PATH 或實際 binaryData path。 |
| queue compatibility 已確認 | 若使用 queue mode,不使用 filesystem binary data storage。 |
| capacity 已估算 | 預估單檔大小、每日檔案數、retention days、總 storage。 |
| pruning 已設定 | execution data 和 binary data retention 都有政策。 |
| backup 已覆蓋 | binary payload 所在位置已納入 backup,不只備份 workflow JSON。 |
| restore 已驗證 | 還原後能開啟歷史 execution 的 binary file 或重跑 workflow。 |
| security 已審核 | Read/Write Files from Disk、Local File Trigger、Execute Command 類能力有明確邊界。 |
production self-host n8n 的最小備份內容不是單一檔案,而是一組 recovery bundle。第一是 database,因為 workflows、encrypted credentials、past executions 都在裡面;如果是 PostgreSQL,要有 pg_dump、managed backup 或等價方式,如果是 SQLite,要有一致性的 database.sqlite 備份。第二是 .n8n volume 或 user folder,因為它可能保存 SQLite file、generated encryption key、settings、binary data path 和 community nodes。第三是 encryption key,尤其是 N8N_ENCRYPTION_KEY,因為 database 裡的 credentials 需要同一把 key 才能解密。第四是 Compose/env/proxy config,因為 DB 連線、public URL、binary data mode、TLS 和 reverse proxy 都靠這些設定恢復。第五是 binary data storage,要依實際 mode 備份 filesystem path、database 或 S3 bucket。workflow JSON export 可以當輔助,但不能取代完整備份。
最小備份內容是 database、.n8n volume 或 user folder、N8N_ENCRYPTION_KEY、Compose/env/proxy config,再依 binary data mode 補上 binary storage。少了其中任何一項,都可能出現 workflow 在、credential 不能用,或資料在、public URL 與檔案失效。
這張表可以直接用來檢查一個 n8n instance 是否已具備基本資料安全意識。若任一項不明確,就表示還不能進正式導入。
| 檢查項 | 通過標準 |
|---|---|
| Database decision 已完成 | 明確知道目前使用 SQLite 或 PostgreSQL,並知道為什麼。 |
| PostgreSQL trigger point 已定義 | 一旦進入 public webhook、長期 automation、team usage、queue mode 或 production,就切換 PostgreSQL。 |
| SQLite backup 風險已理解 | 知道 SQLite file 在 .n8n,並知道 pruning 後可能需要 VACUUM 才釋放磁碟空間。 |
| Encryption key 已納入 P0 | N8N_ENCRYPTION_KEY 或 generated key 被視為 P0 secret。 |
| Full recovery bundle 已列出 | database、volume、key、env、proxy、binary storage 全部列入。 |
| Workflow export 定位正確 | workflow JSON export 只作輔助,不當唯一備份。 |
| Credential export 安全 | 若使用 --decrypted,必須加密保存並限制存取。 |
| Execution retention 已決定 | 知道保存成功/失敗/手動 executions 的策略,並配置 pruning。 |
| Binary mode 已確認 | 不寫死預設值,依實際版本和 N8N_DEFAULT_BINARY_DATA_MODE 判斷。 |
| Restore drill 已排程 | 至少有文件演練,正式前要做測試還原。 |
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 03 計畫要求 | 通過 |
| 已核對官方來源 | 通過 |
| 已完成 SQLite vs PostgreSQL 決策表 | 通過 |
| 已完成最小備份組合 checklist | 通過 |
| 已完成 binary-heavy workflow 注意事項 | 通過 |
| 已完成驗收說明 | 通過 |
| 已避免把 workflow JSON export 誤寫為完整備份 | 通過 |
| 已處理 binary data 版本差異,不寫死單一預設模式 | 通過 |
| 未把 Week 07 Docker Compose 實作或 Week 14 backup command runbook 提前執行 | 通過 |
Week 04 會進入 DNS、HTTPS、反向代理與公開 URL。Week 03 的資料安全結論會在 Week 04 補上 public edge:資料就算保存正確,只要 WEBHOOK_URL、N8N_EDITOR_BASE_URL、TLS 或 reverse proxy headers 錯,外部服務仍然無法可靠觸發 workflow。
資料安全的底線是 recovery bundle:database、volume、key、config、binary storage。workflow JSON 是好輔助,但不是救命繩本身。
4.0 本週定位
Week 04 的核心問題是:為什麼 webhook 與 OAuth 常常不是 workflow 錯,而是 URL、DNS、proxy 錯?這週把 Week 03 的資料安全往外接到 public edge,理解外部服務如何找到 n8n,以及 n8n 如何生成正確的 webhook 與 callback URL。
本週不是要急著公開本機服務,而是先建立排查順序:DNS、TLS、reverse proxy、forwarded headers、n8n public URL env vars、webhook 狀態與 OAuth provider callback。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| public URL troubleshooting flow | 完成 | 4.3 | 能從 DNS、TLS、reverse proxy、n8n env vars、webhook publish 狀態逐層排查。 |
| OAuth callback checklist | 完成 | 4.4 | 能確認 provider callback、WEBHOOK_URL、N8N_EDITOR_BASE_URL、domain 或 tunnel 穩定性。 |
| DNS/TLS glossary | 完成 | 4.5 | 能解釋 domain、A record、CNAME、subdomain、dynamic DNS、TLS certificate、reverse proxy。 |
| 驗收說明 | 完成 | 4.6 | 看到 OAuth callback mismatch 時,能先查 provider callback、public URL env vars、proxy headers 與 domain/tunnel。 |
瀏覽器打得開,只代表 UI path 可能通了。Webhook 與 OAuth 還需要 n8n 生成的 public URL、provider 設定、proxy headers 與 TLS 都同時正確。
整合來源:docs/week-04-public-url-dns-proxy.md
49本週只採用官方文件作為事實基礎。公開 URL 問題不能靠「瀏覽器打得開」就判定成功。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
n8n 會用 N8N_PROTOCOL、N8N_HOST、N8N_PORT 組 webhook URL;在 reverse proxy 後這通常不正確。 | 因為 n8n 內部可能跑在 5678,但外部是 443 與正式 domain。 | Configure webhook URLs with reverse proxy |
reverse proxy 情境應設定 WEBHOOK_URL,讓 n8n 在 editor UI 顯示並向外部服務註冊正確 webhook URL。 | 這是 public webhook 成敗核心。 | Configure webhook URLs with reverse proxy |
reverse proxy 情境應設定 N8N_PROXY_HOPS=1,並讓最後一層 proxy 傳遞 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto。 | proxy hop 與 forwarded headers 會影響 n8n 對外部 scheme 與 host 的理解。 | Configure webhook URLs with reverse proxy |
N8N_EDITOR_BASE_URL 是使用者可存取 editor 的 public URL,也用於 n8n email 與 SAML redirect URL。 | 它不是單純 UI 顯示設定。 | Deployment environment variables |
| Webhook node 有 Test URL 與 Production URL;Test URL 要先 Listen for test event,且測試 webhook 只維持 120 秒。 | 把 Test URL 當 production endpoint 是錯誤排查常見陷阱。 | Webhook workflow development |
| Production webhook URL 要在 workflow 準備好後使用,並 publish workflow 才會自動觸發。 | production webhook 失敗不一定是 DNS,有可能 workflow 沒 publish。 | Webhook workflow development |
OAuth callback、DNS record、Caddy reverse proxy 與 TLS certificate 是同一條 public edge 路徑的不同層。任何一層錯,都會讓外部服務回不到 n8n。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
n8n 官方 Cloud Run 指南的 OAuth redirect URI 範例是 <YOUR-N8N-URL>/rest/oauth2-credential/callback,且同時更新 N8N_HOST、WEBHOOK_URL、N8N_EDITOR_BASE_URL。 | OAuth provider 裡的 redirect URI 必須與 n8n public URL 精準一致。 | Google Cloud Run setup |
Cloudflare 建立 subdomain 時,需建立 A、AAAA 或 CNAME,依目標是 IPv4、IPv6 或 FQDN 決定。 | DNS record type 不是任意選。 | Cloudflare subdomain records |
| CNAME 是 alias,指向 canonical domain。 | PaaS 或 tunnel provider 常要求 CNAME 指到平台 hostname。 | Cloudflare CNAME record |
| Caddy 可作 reverse proxy;若使用非 localhost domain,Caddy 會嘗試取得 publicly trusted certificate,前提是 DNS 指向機器且 80/443 對外開放。 | TLS 自動化仍依賴 DNS 與 port 可達。 | Caddy reverse proxy quick-start |
| Let’s Encrypt 提供 SSL/TLS certificates,用於推廣 HTTPS。 | TLS certificate 是 HTTPS public edge 的必要元件。 | Let’s Encrypt FAQ |
| n8n 建議設定 SSL 來強制安全連線。 | public self-hosted n8n 不應長期停留在 HTTP。 | Securing n8n |
排查 public URL 問題時,請照層級往內查。不要一看到 webhook 或 OAuth 失敗就先改 workflow node。
domain、A record、CNAME、subdomain、DDNS。
certificate issuance、DNS validation、80/443、proxy status。
Caddy/Nginx/Traefik/platform ingress upstream and firewall。
WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS。
Test vs Production URL、Listen for test event、workflow publish。
OAuth redirect URI 與 stable domain/tunnel。
DNS/TLS/proxy/public URL 都通過後,才進 workflow logic、credential scopes、payload、auth 與 response handling。
使用者 browser 要能開 editor;外部 webhook provider 要能打到 production webhook;OAuth provider 要能回到精準 callback URL。三者都通,public URL 才算真的 ready。
| 順序 | 檢查層 | 要問的問題 | 通過標準 | 失敗時先修什麼 |
|---|---|---|---|---|
| 1 | DNS | n8n.example.com 是否解析到正確 server、platform 或 tunnel target? | A、AAAA 或 CNAME 指向正確目標。 | DNS record、subdomain、DDNS 更新、Cloudflare proxy 狀態。 |
| 2 | TLS | 外部看到的是有效 https:// 嗎? | 瀏覽器與外部 service 都接受 certificate。 | certificate issuance、80/443 port、reverse proxy、provider SSL 設定。 |
| 3 | Reverse proxy | public domain 是否轉到 n8n internal port? | request 能到 n8n:5678 或 localhost:5678 等正確 upstream。 | Caddyfile、Nginx config、Traefik labels、platform ingress、firewall。 |
| 4 | Forwarded headers | n8n 是否知道原始 request 的 host 與 protocol? | 最後一層 proxy 傳 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto。 | proxy header 設定與 N8N_PROXY_HOPS。 |
| 5 | n8n public URL env | editor 與 webhook 產出的 URL 是否是外部 URL? | WEBHOOK_URL 與 N8N_EDITOR_BASE_URL 指向穩定 public HTTPS URL。 | env vars 與 container restart。 |
| 順序 | 檢查層 | 要問的問題 | 通過標準 | 失敗時先修什麼 |
|---|---|---|---|---|
| 6 | Webhook mode | 使用的是 Test URL 還是 Production URL? | 測試用 Test URL 且已 Listen;正式用 Production URL 且 workflow 已 publish。 | URL 類型、workflow publish、provider registered URL。 |
| 7 | OAuth provider | provider 裡的 redirect URI 是否完全一致? | redirect URI 精準等於 n8n 的 callback URL,例如 https://n8n.example.com/rest/oauth2-credential/callback。 | provider console 的 authorized redirect URI。 |
| 8 | Tunnel/domain stability | URL 會不會每次重啟就變? | production 使用穩定 domain 或 named tunnel,不使用 random tunnel。 | domain、named tunnel、provider hostname。 |
| 9 | Workflow layer | DNS/TLS/proxy/URL 都正確後,才查 workflow。 | payload、method、auth、response code、node logic 正確。 | Webhook node method、auth、Respond to Webhook、credential scopes。 |
| 變數 | 用途 | 常見錯誤 | 正確範例 |
|---|---|---|---|
N8N_HOST | n8n host name,用於基礎 host 設定。 | 寫成 localhost,但外部使用 n8n.example.com。 | N8N_HOST=n8n.example.com |
N8N_PROTOCOL | n8n 對外 protocol 設定。 | reverse proxy 外部是 HTTPS,n8n 仍生成 HTTP。 | N8N_PROTOCOL=https |
N8N_PORT | n8n process 內部 port。 | 外部 443 與內部 5678 混淆。 | N8N_PORT=5678 |
WEBHOOK_URL | n8n 顯示與註冊 webhook 用的 public URL。 | 沒設定,導致 webhook URL 變成 internal host 或錯誤 port。 | WEBHOOK_URL=https://n8n.example.com |
N8N_EDITOR_BASE_URL | 使用者可存取 editor 的 public URL,也用於 email 與 SAML redirect。 | editor link、auth flow 或 email link 指錯 domain。 | N8N_EDITOR_BASE_URL=https://n8n.example.com |
N8N_PROXY_HOPS | 告訴 n8n 前面有幾層 reverse proxy。 | behind proxy 但仍為 0,n8n 不信任 forwarded headers。 | N8N_PROXY_HOPS=1 |
public URL 的正確性不是單點設定,而是 DNS、TLS、reverse proxy、forwarded headers、n8n env vars 和 provider callback 六層一起正確。
| 檢查項 | 通過標準 | 失敗症狀 |
|---|---|---|
| Provider callback 精準一致 | OAuth provider console 中的 redirect URI 等於 n8n public callback URL。 | redirect_uri_mismatch、callback mismatch、invalid redirect URI。 |
| Callback path 正確 | 常見 n8n OAuth callback path 是 /rest/oauth2-credential/callback。 | provider 回到錯誤 endpoint,n8n 收不到 token。 |
| Scheme 正確 | provider 使用 https://,不是 http://。 | provider 拒絕 redirect 或 browser blocked。 |
| Host 正確 | provider 使用 n8n.example.com,不是 localhost、container name 或舊 tunnel host。 | OAuth 成功登入 provider 後回不到 n8n。 |
| Domain 穩定 | production 不使用每次重啟會變的 random tunnel。 | 昨天可用,今天 callback 失效。 |
N8N_EDITOR_BASE_URL 正確 | 指向使用者實際打開 editor 的 public URL。 | auth/email/SAML 或 editor redirect 指錯。 |
| 檢查項 | 通過標準 | 失敗症狀 |
|---|---|---|
WEBHOOK_URL 正確 | 指向外部 service 能呼叫的 public base URL。 | webhook 或 OAuth-like provider registration 顯示錯誤 base URL。 |
N8N_PROXY_HOPS 正確 | reverse proxy 前方設定 N8N_PROXY_HOPS=1,多層 proxy 依實際層數評估。 | n8n 誤判 protocol 或 host。 |
| Forwarded headers 正確 | 最後一層 proxy 傳 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto。 | n8n 看到 internal host 或 HTTP。 |
| TLS certificate 有效 | provider 與 browser 都信任 certificate。 | OAuth provider 拒絕 callback,或 browser 顯示 certificate warning。 |
| Credential scopes 正確 | OAuth client scopes 與 n8n credential 所需服務一致。 | callback 成功但 credential 無權限或 API call 失敗。 |
| 欄位 | 正確值範例 | 不正確值範例 |
|---|---|---|
| Authorized JavaScript origin | https://n8n.example.com | http://localhost:5678 |
| Authorized redirect URI | https://n8n.example.com/rest/oauth2-credential/callback | https://random-tunnel.trycloudflare.com/rest/oauth2-credential/callback |
| n8n editor base | N8N_EDITOR_BASE_URL=https://n8n.example.com | N8N_EDITOR_BASE_URL=http://localhost:5678 |
| n8n webhook base | WEBHOOK_URL=https://n8n.example.com | WEBHOOK_URL=http://n8n:5678 |
N8N_EDITOR_BASE_URL 與 WEBHOOK_URL 服務不同目的,但 production 應共同指向同一個穩定 public base URL。| 詞彙 | 定義 | n8n 部署影響 | 第一檢查點 |
|---|---|---|---|
| Domain name | 人類可讀的網域,例如 example.com。 | 提供穩定 public identity。 | 是否擁有並控制該 domain? |
| Subdomain | root domain 底下的子網域,例如 n8n.example.com。 | 建議給 n8n 獨立 subdomain,避免 path proxy 複雜度。 | 是否已建立 n8n 這個 DNS record? |
| DNS | 將 domain 解析到 IP 或另一個 hostname 的系統。 | 外部服務能否找到 n8n 的第一層。 | domain 是否解析到正確 server/platform/tunnel? |
| A record | 將 hostname 指向 IPv4 address。 | VPS 常用 A record 指向 server IP。 | n8n.example.com A 203.0.113.10 是否正確? |
| AAAA record | 將 hostname 指向 IPv6 address。 | IPv6 環境使用;若設錯可能導致部分 client 走錯路。 | 是否真的有 IPv6 service 可用? |
| CNAME record | 將 hostname 作為另一個 hostname 的 alias。 | PaaS、tunnel、managed platform 常要求 CNAME。 | target 是否為 provider 給的 FQDN? |
| TTL | DNS record cache 時間。 | 變更 DNS 後外部可能仍暫時看到舊值。 | 是否等 TTL 與 DNS propagation? |
| Dynamic DNS | 當 residential IP 改變時,自動更新 DNS record。 | home server 或 dynamic IP 情境可能需要。 | 更新腳本或 provider API 是否可靠? |
| HTTPS | HTTP over TLS。 | public n8n 應使用 HTTPS,尤其是 credentials 與 OAuth callback。 | browser 是否顯示 valid HTTPS? |
| TLS certificate | 用來證明 server identity 並加密連線的 certificate。 | certificate invalid 會導致 browser 或 provider 拒絕連線。 | certificate domain 是否符合 public hostname? |
| Certificate authority | 簽發 certificate 的受信任機構,例如 Let’s Encrypt。 | 讓外部 client 信任你的 n8n domain。 | certificate 是否由受信任 CA 簽發? |
| 詞彙 | 定義 | n8n 部署影響 | 第一檢查點 |
|---|---|---|---|
| Reverse proxy | 位於 internet 與 n8n 之間,處理 TLS、routing、headers 的前置服務。 | 把 https://n8n.example.com 轉到 internal n8n:5678。 | proxy upstream 是否正確? |
| Public edge | 外部流量第一個進入點,可能是 reverse proxy、platform ingress、tunnel 或 load balancer。 | 決定外部看到的 scheme、host、port。 | public edge 是否穩定且可監控? |
| Origin service | reverse proxy 後方真正跑 n8n 的服務。 | 通常是 localhost:5678 或 Docker service n8n:5678。 | proxy 是否能連到 origin? |
| Forwarded headers | X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto 等 header。 | 讓 n8n 知道原始 request 的 public host 與 protocol。 | proxy 是否傳遞這些 headers? |
WEBHOOK_URL | n8n 用來顯示與註冊 webhook 的 public base URL。 | webhook URL 錯誤時第一優先檢查。 | 是否為 https://n8n.example.com? |
N8N_EDITOR_BASE_URL | n8n editor 的 public base URL,也影響 email 與 SAML redirect。 | auth redirect 與 editor link 錯誤時必查。 | 是否為實際使用者打開的 URL? |
N8N_PROXY_HOPS | 告訴 n8n 前方 proxy hop 數。 | behind reverse proxy 時必須正確設定。 | 單層 reverse proxy 通常設 1。 |
| Test webhook URL | Webhook node 的測試 URL。 | 需要 Listen for test event,且短時間有效。 | 是否按下 Listen 並在 120 秒內測試? |
| Production webhook URL | Webhook node 的正式 URL。 | workflow publish 後才適合外部 production service 使用。 | workflow 是否已 publish? |
| OAuth callback URL | OAuth provider 完成授權後回到 n8n 的 URL。 | mismatch 時 credential connection 失敗。 | provider console 是否完全符合 n8n callback? |
看到 OAuth callback mismatch 時,不要先改 workflow。第一步先把 provider 錯誤訊息中的 redirect URI 複製出來,逐字比對 scheme、host、port 與 path。n8n 常見 OAuth callback path 是 /rest/oauth2-credential/callback,所以 provider 裡應該是類似 https://n8n.example.com/rest/oauth2-credential/callback。第二步檢查 n8n 的 public URL env vars:N8N_EDITOR_BASE_URL 是否是使用者實際開 editor 的 public URL,WEBHOOK_URL 是否是外部服務能呼叫的 public base URL,N8N_HOST、N8N_PROTOCOL 是否和 domain/HTTPS 一致。第三步檢查 reverse proxy:N8N_PROXY_HOPS 是否正確,proxy 是否傳 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto。第四步檢查 DNS 與 TLS:domain 是否解析到正確 public edge,certificate 是否有效。第五步檢查 tunnel 或 domain 是否穩定;如果用 random tunnel,callback 變掉是預期風險,不應當 production callback。
OAuth callback mismatch 先查 provider redirect URI、N8N_EDITOR_BASE_URL、WEBHOOK_URL、N8N_PROXY_HOPS、forwarded headers、DNS/TLS,以及 tunnel 或 domain 是否穩定;這些都正確後,才查 credential scopes 或 workflow。
這張表可以直接拿來驗收 public URL 是否真的 ready。全部通過前,不要把問題歸咎於 workflow node。
| 檢查項 | 通過標準 |
|---|---|
| Domain 已固定 | production 使用穩定 domain 或 named tunnel,不使用 random tunnel。 |
| DNS record 正確 | A、AAAA 或 CNAME 指向正確 server、platform 或 tunnel target。 |
| HTTPS 有效 | public URL 使用有效 TLS certificate。 |
| Reverse proxy upstream 正確 | public edge 能轉到 n8n internal port。 |
| Forwarded headers 正確 | proxy 傳 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto。 |
N8N_PROXY_HOPS 正確 | 單層 reverse proxy 設 1,多層依實際情境評估。 |
WEBHOOK_URL 正確 | 指向外部服務能呼叫的 HTTPS public base URL。 |
N8N_EDITOR_BASE_URL 正確 | 指向使用者實際打開 editor 的 HTTPS public base URL。 |
| Webhook URL 類型正確 | 測試使用 Test URL 與 Listen;正式使用 Production URL 與 published workflow。 |
| OAuth callback 正確 | provider redirect URI 精準等於 n8n callback URL。 |
| DNS/TLS 變更有等待 | 變更 DNS 或 certificate 後,考慮 TTL、propagation、certificate issuance 時間。 |
| Workflow 排查放後面 | DNS/TLS/proxy/public URL 都通過後,才查 method、auth、payload、response logic。 |
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 04 計畫要求 | 通過 |
| 已核對官方來源 | 通過 |
| 已完成 public URL troubleshooting flow | 通過 |
| 已完成 OAuth callback checklist | 通過 |
| 已完成 DNS/TLS glossary | 通過 |
| 已完成驗收說明 | 通過 |
| 已明確區分 Test webhook URL 與 Production webhook URL | 通過 |
| 已明確標示 OAuth callback path 與 provider redirect URI 必須精準一致 | 通過 |
| 未提前執行 Week 08 tunnel 實作或 Week 10 VPS/Caddy 部署 | 通過 |
Week 05 會進入本機快速啟動:Docker Desktop。Week 04 的公開 URL 模型會先放在腦中,不急著公開本機服務;Week 05 的目標是把 n8n 在本機穩定跑起來,確認 volume persistence,等 Week 08 才正式處理 tunnel 與本機 public webhook。
URL 問題要先分層:DNS 找不找得到、TLS 信不信任、proxy 轉不轉得到、n8n 知不知道 public URL、provider callback 是否逐字一致。這些都通過後,才進 workflow 本身。
5.0 本週定位
Week 05 的核心問題是:如何用最少摩擦在 macOS 或 Windows 上跑起可保存狀態的本機 n8n?本週不是 production 部署,而是用 Docker Desktop、官方 n8n image 與 named volume,建立一個可重建、可驗收、可學習的本機 baseline。
本週狀態為完成:三個主要交付物已產出,並已做 Docker Desktop 真機 persistence 驗證。判斷標準不是「UI 打得開」,而是「刪除並重建 container 後,workflow 與 credential 還在」。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| 本機部署紀錄 | 完成 | 5.3 | 使用 Docker Desktop、官方 n8n image、n8n_data volume 與 5678:5678 port mapping 啟動 n8n。 |
| container / volume 截圖或文字紀錄 | 完成 | 5.4 | 以 docker ps、docker inspect、docker volume inspect 留下文字紀錄。 |
| 重啟後 persistence 驗證 | 完成 | 5.5 | 刪除並重建 container 後,workflow 與 credential 仍可由 n8n CLI 匯出。 |
| 本週圖解與排錯流程 | 完成 | 5.6 | 能判斷資料是否在 volume,而不是 container writable layer。 |
| 驗收說明 | 完成 | 5.7 | 能說明重建 container 後 workflow 與 credential 為什麼仍存在。 |
Week 05 的主角不是 container,而是 volume。container 是可以重做的 runtime;n8n_data 才是本機 state 能跨重建保留下來的邊界。
整合來源:docs/week-05-local-docker-desktop.md
68本週只採用官方文件作為安裝與驗證依據。Docker Desktop 是本機 runtime;n8n 的 workflows、credentials、settings 與 encryption key 需要留在 persistent volume 才能跨 container 重建保存。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
n8n 官方 Docker 安裝範例使用 docker volume create n8n_data,並把 n8n_data 掛到 /home/node/.n8n。 | 確認。本週使用同一個 volume name 與 mount path。 | n8n Docker installation |
n8n 官方 Docker 安裝範例以 -p 5678:5678 將本機 port 對到 container port。 | 確認。本週實測 http://localhost:5678 回應 200。 | n8n Docker installation |
n8n Server CLI 可在 Docker container 內用 docker exec 執行。 | 確認。本週使用 n8n export:workflow --all 與 n8n export:credentials --all 驗證資料仍存在。 | n8n Server CLI commands |
| n8n Server CLI 支援匯入 workflow 與 credentials。 | 確認。本週使用 import:workflow 與 import:credentials 建立 persistence probes。 | n8n Server CLI commands |
| Docker volume 的內容存在於單一 container lifecycle 之外;container 被刪除時 writable layer 會被刪掉,但 volume 仍可保留資料。 | 確認。這是本週 persistence 驗證的核心。 | Docker volumes |
docker volume create [VOLUME] 會建立可供 container 使用與存放資料的 volume。 | 確認。本週建立 n8n_data。 | docker volume create |
| Docker Desktop for Mac 官方文件提供安裝、啟動與系統需求;本機 macOS 使用 Docker Desktop context。 | 確認。本週實測 context 為 desktop-linux。 | Install Docker Desktop on Mac |
| Docker Desktop for Windows 官方文件提供 WSL 2 / Hyper-V 安裝模式與啟動方式。 | 確認。Windows 使用者可依同一份 Docker command 模型啟動 n8n。 | Install Docker Desktop on Windows |
這一頁保留本週實際環境值。後續若要重跑 Week 05,先比對 Docker 版本、image tag、container name、volume name 與 mount path。
| 項目 | 本週實測值 |
|---|---|
| 作業系統端 | macOS Docker Desktop |
| Docker context | desktop-linux |
| Docker client | 29.2.1 |
| Docker server | 29.2.1 |
| Docker server OS / arch | linux / arm64 |
| n8n image | docker.n8n.io/n8nio/n8n:latest |
| n8n version | 2.22.4 |
| image digest | docker.n8n.io/n8nio/n8n@sha256:a3ea08b6b923d909b125c7b06273c16679491f07a05857a2dc0df9d9124080db |
| container name | n8n-week5-local |
| volume name | n8n_data |
| n8n data mount | n8n_data:/home/node/.n8n |
| port mapping | 0.0.0.0:5678->5678/tcp |
| local URL | http://localhost:5678 |
本機一開始 Docker CLI 已安裝,但 Docker Desktop daemon 尚未啟動,因此先啟動 Docker Desktop,再確認 daemon 可用。
open -a Docker
docker version --format 'client={{.Client.Version}} server={{.Server.Version}}'
client=29.2.1 server=29.2.1
docker volume create n8n_data
n8n_data
docker pull docker.n8n.io/n8nio/n8n
Using default tag: latest
Status: Downloaded newer image for docker.n8n.io/n8nio/n8n:latest
docker.n8n.io/n8nio/n8n:latest
測試 workflow 檔案:artifacts/week-05-persistence-workflow.json。這個 probe 用來在重建 container 後確認 workflow 仍能由 n8n CLI 匯出。
docker run --rm --name n8n-week5-import \
-e GENERIC_TIMEZONE=Asia/Taipei \
-e TZ=Asia/Taipei \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
-v /Users/linshangche/Desktop/projects/nuva-report/artifacts/week-05-persistence-workflow.json:/tmp/week-05-persistence-workflow.json:ro \
docker.n8n.io/n8nio/n8n \
import:workflow --input=/tmp/week-05-persistence-workflow.json
Importing 1 workflows
Successfully imported 1 workflow.
| 欄位 | 值 |
|---|---|
| workflow id | week05PersistenceProbe |
| workflow name | Week 05 Persistence Probe |
| node 1 | Manual Trigger |
| node 2 | Persistence Marker |
| marker payload | week=5、persisted=true、checkedDate=2026-05-27 |
本週以官方 n8n image 啟動單一 container,將本機 5678 對到 container 5678,並將 n8n_data 掛到 /home/node/.n8n。
docker run -d --name n8n-week5-local \
-p 5678:5678 \
-e GENERIC_TIMEZONE=Asia/Taipei \
-e TZ=Asia/Taipei \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
aa3a92326847edea6ff41de72f358a8fc70f59ad1923195f8cae4ec0615310c3
curl -s -o /dev/null -w '%{http_code}' http://localhost:5678
200
測試 credential 檔案:artifacts/week-05-persistence-credential.json。credential probe 只使用 dummy data,不包含真實 API key、OAuth token 或客戶資料。
docker cp /Users/linshangche/Desktop/projects/nuva-report/artifacts/week-05-persistence-credential.json n8n-week5-local:/tmp/week-05-persistence-credential.json
docker exec n8n-week5-local n8n import:credentials --input=/tmp/week-05-persistence-credential.json
Successfully imported 1 credential.
| 欄位 | 值 |
|---|---|
| credential id | week05CredentialProbe |
| credential name | Week 05 Credential Probe |
| credential type | httpBasicAuth |
| data 性質 | dummy username/password,僅用於 persistence 驗證 |
重建後目前仍在執行的 container:
CONTAINER ID NAMES IMAGE STATUS PORTS
4a1ae7f019d1 n8n-week5-local docker.n8n.io/n8nio/n8n Up 13 seconds 0.0.0.0:5678->5678/tcp, [::]:5678->5678/tcp
id=4a1ae7f019d1e4669201c3d91a834bb8a604a2cbbc861ba656cd32a1421c3a84
image=docker.n8n.io/n8nio/n8n
status=running
started=2026-05-27T14:21:05.621583133Z
mounts=n8n_data:/home/node/.n8n:volume
env=GENERIC_TIMEZONE=Asia/Taipei TZ=Asia/Taipei N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true N8N_RUNNERS_ENABLED=true
name=n8n_data driver=local mountpoint=/var/lib/docker/volumes/n8n_data/_data created=2026-05-27T14:17:22Z
這張表是 Week 05 的核心心智模型:container 是執行層,volume 是狀態層。把兩者混在一起,就會誤以為 container 刪掉還能自動保留資料。
| 元件 | 角色 | 被刪除時的影響 | 本週判斷 |
|---|---|---|---|
n8n-week5-local container | 執行 n8n process、提供 localhost:5678 UI。 | container writable layer 會消失。 | 可重建。 |
n8n_data volume | 保存 /home/node/.n8n 裡的 n8n state。 | 不會因 docker rm n8n-week5-local 自動刪除。 | 必須保留。 |
docker.n8n.io/n8nio/n8n image | 提供 n8n runtime。 | 可重新 pull。 | 可替換,但升級前要備份 volume。 |
/home/node/.n8n/config | 保存 auto-generated encryption key。 | 若遺失,credentials 可能無法解密。 | 已在 volume 內。 |
| SQLite database | 保存 workflows、credentials metadata、executions。 | 若 volume 遺失,workflow 與 credential 會消失。 | 已在 volume 內。 |
本週使用「刪除並重建 container」作為 persistence 驗證。這符合第 5 週驗收條件中的「重啟 Docker Desktop 或重建 container 後,workflow 與 credential 仍存在」。
停止舊 container、刪除舊 container,然後用同一個 n8n_data volume 重建。
docker stop n8n-week5-local
docker rm n8n-week5-local
docker run -d --name n8n-week5-local \
-p 5678:5678 \
-e GENERIC_TIMEZONE=Asia/Taipei \
-e TZ=Asia/Taipei \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
重建後 container id:
4a1ae7f019d1e4669201c3d91a834bb8a604a2cbbc861ba656cd32a1421c3a84
重建後 HTTP readiness:
http_status=200
container=4a1ae7f019d1 name=n8n-week5-local status=Up 5 seconds ports=0.0.0.0:5678->5678/tcp, [::]:5678->5678/tcp
docker exec n8n-week5-local n8n export:workflow --all
id=week05PersistenceProbe
name=Week 05 Persistence Probe
node=Manual Trigger
node=Persistence Marker
persisted=true
checkedDate=2026-05-27
判斷:workflow 在 container 刪除並重建後仍存在,通過。
docker exec n8n-week5-local n8n export:credentials --all
id=week05CredentialProbe
name=Week 05 Credential Probe
type=httpBasicAuth
data=encrypted payload
判斷:credential 在 container 刪除並重建後仍存在,通過。
| 驗收條件 | 實測結果 | 結論 |
|---|---|---|
| Docker Desktop 可用 | daemon 啟動後 client=29.2.1 server=29.2.1 | 通過 |
n8n_data volume 建立成功 | docker volume create n8n_data 回傳 n8n_data | 通過 |
| n8n container 可啟動 | n8n-week5-local running | 通過 |
localhost:5678 可回應 | HTTP status 200 | 通過 |
| workflow 寫入 persistent storage | Week 05 Persistence Probe 可匯出 | 通過 |
| credential 寫入 persistent storage | Week 05 Credential Probe 可匯出 | 通過 |
| 重建 container 後 workflow 仍存在 | 重建後 export:workflow --all 仍含 week05PersistenceProbe | 通過 |
| 重建 container 後 credential 仍存在 | 重建後 export:credentials --all 仍含 week05CredentialProbe | 通過 |
| 做法 | 命令片段 | 結果 |
|---|---|---|
| 正確 | -v n8n_data:/home/node/.n8n | n8n state 寫入 named volume,container 可刪可重建。 |
| 錯誤 | 不掛 volume | n8n state 留在 container writable layer,刪 container 後資料消失。 |
| 錯誤 | -v n8n_data:/tmp/n8n | volume 存在,但 n8n 不會把主要 state 寫到正確路徑。 |
| 高風險 | 每次用不同 volume name | 新 container 看不到舊 workflow 與 credential。 |
| 高風險 | 刪除 n8n_data | workflows、credentials、config 與 encryption key 會一起消失。 |
volume name 對,但 mount path 錯,也等於沒有把 n8n 主要 state 放到正確位置。Week 05 的正確答案必須同時包含 n8n_data 與 /home/node/.n8n。
| 檢查項 | 正確答案 |
|---|---|
| volume name | n8n_data |
| n8n state path | /home/node/.n8n |
| local port mapping | -p 5678:5678 |
| local URL | http://localhost:5678 |
| container 可重建嗎 | 可以,只要同一個 volume 還在。 |
| volume 可以隨手 prune 嗎 | 不可以,docker volume prune 可能刪掉未使用但仍重要的 n8n volume。 |
| credential persistence 只看 workflow 夠嗎 | 不夠,必須用 export:credentials --all 或 UI 確認 credential 仍存在。 |
| 本機 Docker 適合 production public webhook 嗎 | 不適合,本週只驗本機學習與低摩擦啟動。 |
重建 container 後,workflow 與 credential 為什麼仍存在?
因為 n8n 的本機狀態沒有留在 container writable layer,而是透過 -v n8n_data:/home/node/.n8n 寫進 Docker named volume。Docker 官方文件說明,volume 的內容存在於特定 container lifecycle 之外;container 被刪除時 writable layer 會消失,但 volume 仍保留。n8n 官方 Docker 安裝也把 n8n_data 掛到 /home/node/.n8n,這個路徑會保存 SQLite database、config、encryption key、workflow、credential metadata 與本機 instance state。本週已刪除並重建 n8n-week5-local container,重建後 n8n export:workflow --all 仍看到 Week 05 Persistence Probe,n8n export:credentials --all 仍看到 Week 05 Credential Probe,所以 persistence 驗證通過。
資料能留下來,是因為 n8n_data 掛到 /home/node/.n8n。container 可刪可重建,但同一個 volume 保留了 workflow、credential、SQLite database 與 encryption key。
docker start n8n-week5-localdocker stop n8n-week5-localdocker ps --filter name='^/n8n-week5-local$'docker logs --tail=120 n8n-week5-localdocker exec n8n-week5-local n8n export:workflow --alldocker exec n8n-week5-local n8n export:credentials --alldocker stop n8n-week5-local
docker rm n8n-week5-local
docker run -d --name n8n-week5-local \
-p 5678:5678 \
-e GENERIC_TIMEZONE=Asia/Taipei \
-e TZ=Asia/Taipei \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
docker stop n8n-week5-local
docker rm n8n-week5-local
docker volume rm n8n_data
清理 volume 會刪除本週 n8n 本機資料,包括 workflow、credential、config 與 encryption key。除非已完成備份或確定不再需要本機 n8n state,否則不要執行。
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 05 計畫要求 | 通過 |
| 已核對官方 n8n Docker 文件 | 通過 |
| 已核對官方 Docker volume 文件 | 通過 |
| Docker Desktop daemon 已啟動 | 通過 |
已建立 n8n_data volume | 通過 |
| 已拉取官方 n8n image | 通過 |
已啟動 n8n-week5-local container | 通過 |
已確認 localhost:5678 回應 | 通過 |
| 已建立 workflow persistence probe | 通過 |
| 已建立 credential persistence probe | 通過 |
| 已刪除並重建 container | 通過 |
| 已驗證 workflow 重建後仍存在 | 通過 |
| 已驗證 credential 重建後仍存在 | 通過 |
| 未使用真實 API key 或客戶 credential | 通過 |
| 未刪除既有 Supabase containers 或既有 user volumes | 通過 |
| 未提前執行 Week 06 npm 比較或 Week 10 VPS/Caddy 部署 | 通過 |
第 6 週可以進入 npm 與單容器路線比較。第 5 週已證明「本機 Docker Desktop + named volume」能低摩擦啟動並保留狀態;第 6 週要回答的是:如果不用 Docker,改用 npm 或直接跑單一 runtime,安裝、升級、資料保存、rollback、隔離性與可移植性會差在哪裡。
Week 05 的最低合格答案是:我能用 Docker Desktop 跑起 n8n,也能證明資料不是靠 container 活著,而是靠 n8n_data:/home/node/.n8n 這條 state boundary 活著。
6.0 本週定位
Week 06 的核心問題是:npm 為什麼快,但 Docker 為什麼通常更適合長期 self-host?本週不是否定 npm,而是把「快速啟動」和「可維運部署」拆開看,避免把能打開 UI 誤認成可以長期承載真實 credentials、public webhook 與 uptime。
本週狀態為完成:三個交付物已全部產出,並已做 npm/npx 實機啟動驗證。驗收重點是能同時承認 npm/npx 的速度價值,也能清楚指出何時必須停止把它當長期方案。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| npm vs Docker 比較表 | 完成 | 6.4 | 能從啟動速度、Node.js 版本、全域依賴、升級、rollback、隔離性、資料保存與 production 風險比較。 |
| 本機啟動命令筆記 | 完成 | 6.5 | 實際執行 npx --yes n8n --version 與 npx --yes n8n start,並避開第 5 週 Docker port。 |
| 不適合 production 的原因清單 | 完成 | 6.6 | 能說明 npm quick start 何時應停止作為長期方案。 |
| 路線決策圖 | 完成 | 6.7 | 能從 local learning、durable local self-host、team/production 三種狀態選路線。 |
| 驗收說明 | 完成 | 6.8 | 能同時說明 npm quick start 的價值與停止使用它的時機。 |
npx n8n 是很好的第一步,因為它讓你最快看到 n8n。但只要問題開始涉及資料保存、升級回退、團隊交接、public URL 或 uptime,就要從「快」切換到「可重建」。
整合來源:docs/week-06-npm-vs-docker-single-container.md
92本週只採用官方文件作為事實基礎。npm 路線不是錯;它的價值是快。真正要分清楚的是:快啟動不等於長期可維運。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
| n8n npm 安裝頁說明 npm 是在本機快速開始 n8n 的方式,且需要 Node.js。 | 確認。本週本機 Node.js 為 v24.13.1。 | n8n npm installation |
n8n npm 安裝頁要求 Node.js 版本介於 20.19 到 24.x,含兩端。 | 確認。本週本機 v24.13.1 符合要求。 | n8n npm installation |
n8n 可用 npx n8n 不安裝到 global 直接試跑。 | 確認。本週使用 npx --yes n8n --version 與 npx --yes n8n start 實測。 | n8n npm installation |
n8n 可用 npm install n8n -g 安裝到 global,啟動命令是 n8n 或 n8n start。 | 確認。本週保留為命令筆記,未污染 global install。 | n8n npm installation |
n8n npm 更新可用 npm update -g n8n,也可用 npm install -g n8n@next 安裝 next。 | 確認。這同時代表 npm 路線的升級責任落在本機 npm/global package 管理上。 | n8n npm installation |
| n8n tunnel 文件明確標示 tunnel 用於 local development/testing,不安全於 production。 | 確認。npm quick start 若要 public webhook,常會自然走到 tunnel,因此 production 界線要特別清楚。 | n8n npm installation |
這一頁補上 npx 的快啟動機制,以及 Docker / volume / N8N_USER_FOLDER 在 state boundary 上的差異。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
| npx 可以從 local 或 remote npm package 執行 command;缺少 package 時會裝到 npm cache 並加到 PATH。 | 確認。本週第一次 npx 執行下載了 n8n package 並出現 npm dependency warnings。 | npm npx command |
| n8n Docker 安裝頁建議 Docker 用於多數 self-host 需求,因為它提供乾淨、隔離的環境並降低 OS/tooling incompatibility。 | 確認。這是 Docker single-container 勝過 npm 長期路線的核心。 | n8n Docker installation |
n8n Docker 安裝頁使用 n8n_data:/home/node/.n8n 保存資料。 | 確認。第 5 週已真機驗證重建 container 後 workflow 與 credential 仍存在。 | n8n Docker installation |
| Docker volume 是 Docker 管理的 persistent data store。 | 確認。Docker single-container 以 named volume 取得比 npm user folder 更清楚的資料邊界。 | Docker volumes |
N8N_USER_FOLDER 可指定 n8n 建立 .n8n 的路徑,該目錄保存 database file 與 encryption key 等 user-specific data。 | 確認。本週使用獨立 user folder 實測後移除,避免把 encryption key 留在 repo。 | n8n deployment environment variables |
| n8n 預設使用 SQLite,也支援 PostgreSQL。 | 確認。第 6 週先比較 npm 與 single-container;第 7 週再進入 Docker Compose + PostgreSQL。 | n8n database environment variables |
| 項目 | 實測值 |
|---|---|
| Node.js | v24.13.1 |
| npm | 11.8.0 |
| npx | 11.8.0 |
| npx n8n version | 2.22.4 |
| npm/npx 測試 port | 5686 |
| npm/npx 測試 URL | http://localhost:5686 |
| npm/npx readiness | HTTP status 200 |
| npm/npx 測試 user folder | artifacts/week-06-npm-user-folder |
| npm/npx 測試 user folder 狀態 | 測試後已刪除,只保留去敏紀錄 |
| 去敏紀錄 | artifacts/week-06-npm-launch-record.json |
| 項目 | 實測值 |
|---|---|
| Docker container | n8n-week5-local |
| Docker n8n version | 2.22.4 |
| Docker image | docker.n8n.io/n8nio/n8n:latest |
| Docker volume | n8n_data |
| Docker mount | n8n_data:/home/node/.n8n |
| Docker port | 0.0.0.0:5678->5678/tcp |
| Docker persistence | 第 5 週已驗證 workflow 與 credential 重建 container 後仍存在 |
| 觀察 | 結果 | 判讀 |
|---|---|---|
npx --yes n8n --version | 回傳 2.22.4 | npm quick start 能快速取得 n8n。 |
| 首次 npx 下載 | 出現多個 ERESOLVE overriding peer dependency warning | npm 路線直接暴露在本機 npm dependency resolution 中。 |
| 首次 npx 下載 | 出現多個 deprecated package warning | npm quick start 不等於「無維運成本」。 |
npx --yes n8n start | 啟動成功,editor 可由 http://localhost:5686 存取 | 本機快速試跑通過。 |
| runtime user folder | 產生 .n8n/config、database.sqlite、WAL/SHM、event log、nodes package file | npm route 的 state 會落在 user folder,不是 Docker volume。 |
| n8n runtime warning | N8N_RUNNERS_ENABLED 在 2.22.4 已提示不再需要 | 實際版本與文件範例可能有時間差,production 應以當前版本 release notes 與 logs 校正。 |
| test cleanup | 已停止 port 5686 npx process,並刪除測試 user folder | 避免臨時 encryption key 與 SQLite state 留在 repo。 |
| 比較面向 | npm / npx quick start | npm global install | Docker single-container | 判斷 |
|---|---|---|---|---|
| 啟動速度 | 最快,npx n8n 可直接下載並跑。 | 快,但要先 global install。 | 中等,要有 Docker Desktop 或 Docker Engine。 | 學習與臨時 demo:npm/npx 勝。 |
| 本機污染 | 主要污染 npm cache;若不指定 N8N_USER_FOLDER,會寫到使用者 .n8n。 | 污染 global npm package space,升級也在 global。 | 狀態集中在 Docker volume,runtime 在 container。 | 長期管理:Docker 勝。 |
| Node.js 版本 | 依賴本機 Node.js,必須符合 n8n 支援範圍。 | 同左。 | image 內已封裝 runtime,不依賴 host Node.js。 | 版本隔離:Docker 勝。 |
| npm dependency warnings | 可能直接看到 peer/deprecated warnings。 | 同左,且 global 更容易累積歷史狀態。 | 使用 image 交付,host 不直接解 npm dependency tree。 | 降低本機 dependency friction:Docker 勝。 |
| 比較面向 | npm / npx quick start | npm global install | Docker single-container | 判斷 |
|---|---|---|---|---|
| 升級方式 | 下次 npx 可能抓新 package;可用版本 spec 固定。 | npm update -g n8n 或 npm install -g n8n@version。 | docker pull image,重建 container 並沿用 volume。 | 可重建性與 rollback:Docker 較清楚。 |
| rollback | 需指定舊 npm version,且 database migration 仍要小心。 | 同左。 | 可改用舊 image tag,但 database migration 仍要搭配備份與 release notes。 | 兩者都要備份;Docker 的 runtime 回退較明確。 |
| 資料保存 | 取決於 N8N_USER_FOLDER 或 default user .n8n。 | 同左。 | n8n_data:/home/node/.n8n 很明確。 | persistence 邊界:Docker 勝。 |
| encryption key | 存在 user folder 的 .n8n/config。 | 同左。 | 存在 volume 的 /home/node/.n8n/config。 | 兩者都要備份;Docker 更容易制度化。 |
| 比較面向 | npm / npx quick start | npm global install | Docker single-container | 判斷 |
|---|---|---|---|---|
| public URL / webhook | 常搭配 tunnel 做 local testing,但不該當 production。 | 同左。 | 可接 reverse proxy、fixed domain、TLS,但 single-container 仍不是完整 production 架構。 | public self-host:Docker 起步較合理。 |
| process supervision | 手動 terminal process,終端關掉就停。 | 仍需 PM2/systemd/launchd 等額外配置。 | Docker restart policy / Compose / orchestrator 更自然。 | 長期運行:Docker 勝。 |
| port 管理 | 直接占 host port,容易與其他本機服務衝突。 | 同左。 | port mapping 明確,例如 5678:5678。 | 可讀性:Docker 稍勝。 |
| team 可移植性 | 每個人本機 Node/npm 狀態可能不同。 | 同左,global install 更不一致。 | image、env、volume、compose file 可文件化。 | 團隊一致性:Docker 勝。 |
| 適合場景 | 快速學習、CLI 測試、短期 demo、探索 nodes。 | 個人長期本機開發但仍不建議 production。 | 本機 durable self-host、低摩擦保存狀態、進入 Compose 前的穩定過渡。 | npm 是入口,Docker 是更好的長期起點。 |
| 路線 | 一句話 |
|---|---|
npx n8n | 最快看到 n8n UI,但最不像 production。 |
npm install -g n8n | 比 npx 固定一點,但仍受 host Node/npm/global state 影響。 |
| Docker single-container | 還不是完整 production,但已把 runtime、port、volume 與重建流程整理成可維運的形狀。 |
| Docker Compose + PostgreSQL | 第 7 週目標,開始把 database、service definition、backup 與升級流程制度化。 |
npm/npx 是速度工具;Docker single-container 是秩序工具;Compose + PostgreSQL 才開始接近 production-like 維運工具。
node --version
npm --version
npx --version
v24.13.1
11.8.0
11.8.0
N8N_USER_FOLDER=/Users/linshangche/Desktop/projects/nuva-report/artifacts/week-06-npm-user-folder \
N8N_PORT=5686 \
GENERIC_TIMEZONE=Asia/Taipei \
TZ=Asia/Taipei \
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
N8N_RUNNERS_ENABLED=true \
npx --yes n8n --version
2.22.4
本週沒有直接使用 default ~/.n8n,而是指定獨立 N8N_USER_FOLDER,避免污染使用者真正的 n8n state。因第 5 週 Docker container 已占用 5678,本週 npm/npx route 使用 5686。
N8N_USER_FOLDER=/Users/linshangche/Desktop/projects/nuva-report/artifacts/week-06-npm-user-folder \
N8N_PORT=5686 \
GENERIC_TIMEZONE=Asia/Taipei \
TZ=Asia/Taipei \
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
N8N_RUNNERS_ENABLED=true \
npx --yes n8n start
No encryption key found - Auto-generating and saving to: /Users/linshangche/Desktop/projects/nuva-report/artifacts/week-06-npm-user-folder/.n8n/config
n8n ready on ::, port 5686
Version: 2.22.4
Editor is now accessible via:
http://localhost:5686
curl -s -o /dev/null -w 'npm_http_status=%{http_code}\n' http://localhost:5686
npm_http_status=200
.n8n/config
.n8n/database.sqlite
.n8n/database.sqlite-shm
.n8n/database.sqlite-wal
.n8n/n8nEventLog.log
.n8n/nodes/package.json
這些檔案說明 npm route 不是「無狀態」。只要 n8n 啟動,就會建立 user-specific state。.n8n/config 包含 encryption key,database.sqlite 保存本機 instance database。測試後已刪除該 user folder,只留下去敏的 artifacts/week-06-npm-launch-record.json。
本週未執行 global install,原因是它會改變使用者全域 npm 狀態;但依官方文件,正確命令如下。
npm install n8n -g
npm install -g n8n@2.22.4
n8n
n8n start
npm update -g n8n
npm install -g n8n@next
docker volume create n8n_data
docker run -d --name n8n-week5-local \
-p 5678:5678 \
-e GENERIC_TIMEZONE=Asia/Taipei \
-e TZ=Asia/Taipei \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-e N8N_RUNNERS_ENABLED=true \
-v n8n_data:/home/node/.n8n \
docker.n8n.io/n8nio/n8n
| 情境 | 為什麼 npm/npx 合理 |
|---|---|
| 第一次看 n8n UI | npx n8n 可以最快進入 editor。 |
| 本機短期 demo | 不需要先寫 Docker/Compose 文件。 |
| CLI command 試驗 | 可以快速跑 n8n --version 或其他 CLI command。 |
| 個人探索 nodes | 適合短時間確認功能概念。 |
| 教學現場 | 只要學員已有符合版本的 Node.js,就能快速進入操作。 |
npm/npx 的價值很真實:它降低第一步摩擦。但它應該停在 learning、demo、CLI 試驗與探索,不應默默升級成無人維護的 production runtime。
| 停止訊號 | 原因 | 建議下一步 |
|---|---|---|
| 開始放真實 credentials | encryption key、SQLite、credential state 要有明確備份與 restore discipline。 | 轉 Docker single-container,然後規劃 Compose + PostgreSQL。 |
| 需要穩定 public webhook | npm 本機 process 加 tunnel 只適合 development/testing。 | 轉固定 domain、reverse proxy、TLS。 |
| 需要 OAuth callback | random local/tunnel URL 會破壞 callback 穩定性。 | 用穩定 public URL 與正式 reverse proxy。 |
| 需要 uptime | terminal process、sleep、logout、OS reboot 都可能停服務。 | Docker restart policy、Compose 或 systemd。 |
| 多人共用 instance | host global npm state 不適合當團隊一致環境。 | 用 image tag、env file、Compose 文件化。 |
| 停止訊號 | 原因 | 建議下一步 |
|---|---|---|
| 要做可預期升級 | npm update 與 host dependency tree 會讓升級責任分散。 | image pinning、backup、staging、rollback procedure。 |
| 要做 rollback | npm rollback 還要面對 database migration,不只是降 package。 | 先備份 DB/user folder,再按 release notes 回退。 |
| 要處理大量 executions | SQLite 與本機 user folder 對長期 execution growth 不理想。 | 進入 PostgreSQL 與 pruning 策略。 |
| 要裝 community nodes | npm route 會加重 host package 與 supply-chain 管理責任。 | 容器化、鎖版本、審查來源。 |
| 需要監控與告警 | npm process 本身不提供 production supervision。 | Docker/Compose + logs/metrics/health check。 |
| # | 原因 |
|---|---|
| 1 | 它依賴 host Node.js 版本;n8n 支援範圍會隨版本變動。 |
| 2 | 它依賴 host npm/npx dependency resolution;本週實測出現 peer dependency 與 deprecated package warnings。 |
| 3 | 它的 state 預設落在使用者 .n8n,如果沒有明確設定 N8N_USER_FOLDER,很容易混在個人環境裡。 |
| 4 | 它沒有自然的 container boundary;Node runtime、package cache、global npm package 與 process 都在 host。 |
| 5 | 它沒有自然的 port mapping 文件;port 衝突常被當成 n8n 問題,但其實是 host process 管理問題。 |
| # | 原因 |
|---|---|
| 6 | 它沒有自然的 restart policy;terminal 關閉、登出、睡眠或 reboot 都會中斷服務。 |
| 7 | 它不自然支援固定 public URL、TLS termination、reverse proxy、headers 與 webhook/OAuth production flow。 |
| 8 | 它不自然支援 image pinning;production 更需要明確知道目前 runtime 從哪個 artifact 啟動。 |
| 9 | 它不自然支援 team handoff;另一台機器的 Node/npm/global state 可能完全不同。 |
| 10 | 它容易讓人誤判「能打開 UI」等於「能長期維運」。 |
Yes → npx n8n
No → npx n8n
No → npm global + explicit N8N_USER_FOLDER
n8n_data:/home/node/.n8n
Yes → Docker Compose + PostgreSQL
state 內容:config、SQLite、logs、nodes。風險是 host Node/npm 狀態與 user folder 管理必須自己制度化。
state 內容:/home/node/.n8n 裡的 config、SQLite、logs、nodes。優點是 runtime 與 state 邊界更清楚。
| 路線 | 升級動作 | 回退動作 | 風險 |
|---|---|---|---|
| npx | 下次執行可能解析到新 package,或用 npx n8n@version 固定。 | 改指定舊 version。 | package 可回退不代表 database migration 可安全回退。 |
| npm global | npm update -g n8n 或 npm install -g n8n@version。 | npm install -g n8n@olderVersion。 | global npm state、host Node.js、migration 都要一起考慮。 |
| Docker single-container | docker pull 新 image,stop/rm/run 新 container,沿用 volume。 | 使用舊 image tag 重建 container。 | volume 內 database 若已 migrate,仍需 backup/restore 或官方 revert 流程。 |
| Compose + PostgreSQL | 更新 compose image tag,配合 DB backup。 | 回退 compose tag 與 DB backup/restore。 | 較重,但最接近可制度化維運。 |
無論 npm 或 Docker,runtime 回退不等於資料庫 migration 回退。只要有真實資料,升級前都要有 backup 與 restore path。
npm quick start 的價值是什麼?何時該停止使用它當長期方案?
npm quick start 的價值是「最快看到 n8n 跑起來」。如果本機 Node.js 符合 n8n 支援版本,npx n8n 可以不用 global install 就下載並啟動 n8n;npm install n8n -g 則可以把 n8n 裝到 global 後用 n8n 或 n8n start 啟動。它非常適合第一次學習、短期 demo、CLI 試驗與個人探索。但一旦開始保存真實 workflow、credentials、OAuth callback、public webhook 或需要 uptime,就應停止把 npm 當長期方案。原因是 npm route 依賴 host Node.js、npm cache、global package 或 user folder;資料會落在 .n8n,包含 database 與 encryption key;process supervision、backup、public URL、TLS、rollback 與 team handoff 都不自然。長期 self-host 應先轉 Docker single-container,讓 runtime、port 與 volume 邊界清楚;再於第 7 週進入 Docker Compose + PostgreSQL。
npx n8n 很適合快速學習;但只要有真實 credentials、public webhook、OAuth、uptime、升級回退或團隊使用,就該停止把 npm 當長期方案,改走 Docker,下一步是 Compose + PostgreSQL。
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 06 計畫要求 | 通過 |
| 已核對 n8n npm 官方文件 | 通過 |
| 已核對 n8n Docker 官方文件 | 通過 |
| 已核對 npm npx 官方文件 | 通過 |
| 已核對 Docker volume 官方文件 | 通過 |
已核對 N8N_USER_FOLDER 官方說明 | 通過 |
| 已確認本機 Node.js 版本 | 通過,v24.13.1 |
| 已確認本機 npm/npx 版本 | 通過,11.8.0 |
已執行 npx --yes n8n --version | 通過,回傳 2.22.4 |
| 已短暫啟動 npm/npx n8n | 通過,http://localhost:5686 回應 200 |
| 已停止 npm/npx 測試 process | 通過 |
| 已移除 npm/npx 測試 user folder | 通過 |
| 已保留去敏啟動紀錄 | 通過,artifacts/week-06-npm-launch-record.json |
| 已完成 npm vs Docker 比較表 | 通過 |
| 已完成本機啟動命令筆記 | 通過 |
| 已完成不適合 production 的原因清單 | 通過 |
| 未污染 global npm install | 通過 |
未破壞第 5 週 Docker n8n_data volume | 通過 |
| 未提前執行 Week 07 Docker Compose + PostgreSQL | 通過 |
第 7 週要進入 Docker Compose + PostgreSQL。第 6 週的結論是:npm/npx 是最好的「第一眼看到 UI」路線;Docker single-container 是更穩的本機 self-host 路線;但只要開始需要 production-like reliability,就不能停在 SQLite + single container,下一步要把 database 與 service definition 拆清楚,讓 backup、restore、upgrade 與 rollback 進入可維運狀態。
Week 06 的核心能力,是把「可以跑」拆成三個等級:可以快速看到 UI、可以保留狀態、可以制度化維運。npm/npx 解第一題;Docker single-container 解第二題;Week 07 的 Compose + PostgreSQL 開始解第三題。
7.0 本週定位
Week 07 的核心問題是:如何把單一 container 升級成 production-shaped local stack?這週把 Week 05 的本機 container 與 Week 06 的路線比較往前推一步:用 Compose 描述 n8n 與 PostgreSQL,讓 service、network、volumes、healthcheck、env vars 與啟動順序都能被重建。
本週狀態為完成:三個交付物已全部產出,並已做 Docker Compose + PostgreSQL 實機啟動驗證。驗收重點不是只有 UI 可開,而是 n8n 確實以 PostgreSQL 作為 database backend。
| 交付物 | 狀態 | 對應章節 | 驗收方式 |
|---|---|---|---|
| Compose 架構解說 | 完成 | 7.4 | 能逐行說明 services、postgres、n8n、depends_on、volumes、ports、environment 的用途。 |
| env vars 對照表 | 完成 | 7.5 | 能說明 DB_TYPE=postgresdb、DB_POSTGRESDB_*、N8N_ENCRYPTION_KEY 與 Postgres POSTGRES_* 的用途。 |
| PostgreSQL-backed n8n 啟動紀錄 | 完成 | 7.6 | Compose stack 成功啟動,n8n 走 5687,PostgreSQL healthy,n8n tables 與 workflow probe 寫入 PostgreSQL。 |
| production-shaped local stack 判斷 | 完成 | 7.7 | 能說明為什麼它比單容器更接近 production,也能說明它尚未是完整 production。 |
| 驗收說明 | 完成 | 7.8 | 能逐行解釋 Compose 檔中的 n8n、postgres、volumes、environment。 |
Compose 的價值不是「多開幾個容器」,而是把 app、database、volume、env、network、healthcheck 與啟動順序寫成一份可重建的說明書。
整合來源:docs/week-07-docker-compose-postgresql.md
117本週只採用官方文件作為事實基礎。Compose 的任務是讓 multi-container stack 變成可以閱讀、重建與交接的 YAML。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
| Docker Compose 用單一 YAML 定義並啟動 multi-container application。 | 確認。本週用 compose.yaml 管理 n8n 與 postgres 兩個 service。 | Docker Compose |
Compose service 的 environment 可以用 map 或 array 設定 container environment variables。 | 確認。本週採 map syntax,避免布林與字串混淆。 | Compose services: environment |
Compose 的 top-level volumes 可宣告 named volumes;docker compose up 會建立缺少的 volume。 | 確認。本週建立 n8n-week7_postgres_data 與 n8n-week7_n8n_data。 | Compose volumes |
Compose 的 depends_on 可表達 service dependency;本週使用 health condition 讓 n8n 等 PostgreSQL healthy 後再啟動。 | 確認。n8n service 依賴 postgres: service_healthy。 | Compose services |
| n8n 預設使用 SQLite,也支援 PostgreSQL。 | 確認。本週明確設定 DB_TYPE=postgresdb。 | n8n database environment variables |
這一頁補上 n8n database environment variables、固定 encryption key,以及 Postgres 官方 image 的初始化變數。
| 事實 | 核對結果 | 官方來源 |
|---|---|---|
n8n PostgreSQL 設定包含 DB_POSTGRESDB_DATABASE、DB_POSTGRESDB_HOST、DB_POSTGRESDB_PORT、DB_POSTGRESDB_USER、DB_POSTGRESDB_PASSWORD、DB_POSTGRESDB_SCHEMA 等。 | 確認。本週使用 database、host、port、user、password;schema 採預設 public。 | n8n database environment variables |
n8n N8N_ENCRYPTION_KEY 可提供自訂 key,用於加密 database 中的 credentials;預設是首次啟動隨機產生。 | 確認。本週固定 local-only test key,避免重建 n8n user folder 時 credential key 漂移。 | n8n deployment environment variables |
| n8n 官方 Docker Compose setup 文件提供 Compose 路線,並提醒 self-hosting 需要 server、security、configuration 等知識。 | 確認。本週只是 production-shaped local stack,不宣稱已達完整 production。 | n8n Docker Compose setup |
Postgres Official Image 使用 POSTGRES_PASSWORD 設定 superuser password,並可用 POSTGRES_USER、POSTGRES_DB 指定使用者與初始 database。 | 確認。本週 Postgres service 使用 POSTGRES_DB=n8n_week7、POSTGRES_USER=n8n_week7、POSTGRES_PASSWORD local test value。 | Postgres Official Image |
| 檔案 | 用途 |
|---|---|
artifacts/week-07-compose/compose.yaml | 第 7 週 Docker Compose stack 定義。 |
artifacts/week-07-compose/.env | 第 7 週 local-only environment values。 |
artifacts/week-07-compose/week-07-postgres-workflow.json | 用來驗證 n8n workflow 會寫入 PostgreSQL 的 dummy workflow。 |
artifacts/week-07-compose/week-07-marker.sql | PostgreSQL 狀態檢查 SQL。 |
artifacts/week-07-compose/week-07-launch-record.json | 去敏後的第 7 週啟動與驗證紀錄。 |
| 項目 | 實測值 |
|---|---|
| Docker Compose version | v5.1.0 |
| Compose project | n8n-week7 |
| n8n service | n8n-week7-n8n-1 |
| n8n image | docker.n8n.io/n8nio/n8n:2.22.4 |
| n8n version | 2.22.4 |
| n8n host URL | http://localhost:5687 |
| n8n HTTP readiness | 200 |
| Postgres service | n8n-week7-postgres-1 |
| Postgres image | postgres:16-alpine |
| Postgres status | running |
| Postgres health | healthy |
| Postgres host exposure | 未發布到 host,只在 Compose network 內提供 5432 |
| n8n data volume | n8n-week7_n8n_data:/home/node/.n8n |
| PostgreSQL data volume | n8n-week7_postgres_data:/var/lib/postgresql/data |
database_name | database_user | public_table_count
n8n_week7 | n8n_week7 | 93
credentials_entity
execution_entity
migrations
workflow_entity
id | name | active
week07PostgresProbe | Week 07 PostgreSQL Probe | f
http_status_after_restart=200
workflow_count=1
migration_count=184
n8n 並不是只啟動 UI,而是以 DB_TYPE=postgresdb 連到 Compose network 內的 postgres service,完成 migration,建立 PostgreSQL tables,並能將 workflow 寫入 PostgreSQL。
name: n8n-week7
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s
timeout: 5s
retries: 20
volumes:
- postgres_data:/var/lib/postgresql/data
n8n:
image: docker.n8n.io/n8nio/n8n:2.22.4
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
ports:
- "5687:5678"
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
DB_POSTGRESDB_USER: ${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_HOST: ${N8N_HOST}
N8N_PORT: ${N8N_PORT}
N8N_PROTOCOL: ${N8N_PROTOCOL}
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
TZ: ${TZ}
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
volumes:
- n8n_data:/home/node/.n8n
volumes:
postgres_data:
n8n_data:
| 行或區塊 | 用途 | 本週判斷 |
|---|---|---|
name: n8n-week7 | 固定 Compose project name。 | 讓 containers、network、volumes 都以 n8n-week7 命名,避免和第 5 週 n8n-week5-local 混淆。 |
services: | 宣告這個 stack 由哪些 container services 組成。 | 本週有 postgres 與 n8n 兩個 service。 |
postgres: | 定義 PostgreSQL database service。 | 讓 database 從 n8n container 分離出來。 |
image: postgres:16-alpine | 使用官方 Postgres image。 | local stack 使用輕量 Alpine 版本;真 production 要評估版本、備份與升級策略。 |
restart: unless-stopped | Docker daemon 重啟後,除非曾手動停止,否則嘗試重啟 service。 | 比手動 npm process 更接近長期運行。 |
| 行或區塊 | 用途 | 本週判斷 |
|---|---|---|
POSTGRES_DB | 初始化 database name。 | 本週為 n8n_week7。 |
POSTGRES_USER | 初始化 database user。 | 本週為 n8n_week7。 |
POSTGRES_PASSWORD | 初始化 database user password。 | 本週使用 local-only test value,不可重用於 production。 |
healthcheck: | 定義 Postgres 健康檢查。 | n8n 可等待 database ready 後再啟動。 |
pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB | 用 Postgres 工具確認 database 可接受連線。 | $$ 讓 Compose 保留 $ 給 container shell 展開。 |
interval: 5s / timeout: 5s / retries: 20 | 設定檢查頻率、timeout 與重試次數。 | 給首次 database init 足夠時間,同時避免健康檢查卡太久。 |
| 行或區塊 | 用途 | 本週判斷 |
|---|---|---|
postgres_data:/var/lib/postgresql/data | 把 Postgres data directory 放到 named volume。 | database 不會因 container 重建消失。 |
n8n: | 定義 n8n application service。 | 這是 workflow editor 與 execution runtime。 |
image: docker.n8n.io/n8nio/n8n:2.22.4 | 使用 pin 版 n8n image。 | 比 floating latest 更可追蹤。 |
depends_on: postgres: condition: service_healthy | n8n 等 Postgres healthy 後才啟動。 | 降低 n8n 啟動時 database 尚未 ready 的失敗機率。 |
ports: "5687:5678" | host 5687 對 container 5678。 | 避開第 5 週 5678,本週 editor URL 是 http://localhost:5687。 |
| 行或區塊 | 用途 | 本週判斷 |
|---|---|---|
DB_TYPE: postgresdb | 告訴 n8n 使用 PostgreSQL。 | 第 7 週核心設定。 |
DB_POSTGRESDB_HOST: postgres | n8n 用 Compose service name 連 database。 | 在 Compose network 裡,service name 可作 internal hostname。 |
DB_POSTGRESDB_PORT: 5432 | PostgreSQL container internal port。 | 不需要 publish 到 host。 |
DB_POSTGRESDB_DATABASE | n8n 要連的 database name。 | 與 POSTGRES_DB 對齊。 |
DB_POSTGRESDB_USER | n8n 要使用的 database user。 | 與 POSTGRES_USER 對齊。 |
DB_POSTGRESDB_PASSWORD | n8n 連 PostgreSQL 的 password。 | 與 POSTGRES_PASSWORD 對齊。 |
| 行或區塊 | 用途 | 本週判斷 |
|---|---|---|
N8N_ENCRYPTION_KEY | 固定 n8n credential encryption key。 | 避免 credentials 因 key 漂移而無法解密。 |
N8N_HOST | n8n 自身 host 設定。 | 本週 local 為 localhost。 |
N8N_PORT | n8n container 內部 port。 | 本週保持 5678,host port mapping 才是 5687。 |
N8N_PROTOCOL | n8n protocol 設定。 | 本週 local 為 http;production public edge 應使用 HTTPS。 |
GENERIC_TIMEZONE / TZ | n8n schedule-oriented nodes timezone 與 container OS timezone。 | 本週使用 Asia/Taipei。 |
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true" | 強制 n8n config file 權限更安全。 | 使用字串避免 YAML boolean 解析歧義。 |
n8n_data:/home/node/.n8n | 保存 n8n user folder。 | 即使用 PostgreSQL,仍要保存 config、encryption key 相關 local state。 |
top-level volumes: | 宣告 Compose-managed named volumes。 | Compose 會建立並管理 n8n-week7_postgres_data 與 n8n-week7_n8n_data。 |
.env 檔內容POSTGRES_DB=n8n_week7
POSTGRES_USER=n8n_week7
POSTGRES_PASSWORD=week7_local_postgres_password_do_not_reuse
N8N_ENCRYPTION_KEY=week7_fixed_local_encryption_key_2026_05_27_do_not_reuse
N8N_HOST=localhost
N8N_PORT=5678
N8N_PROTOCOL=http
GENERIC_TIMEZONE=Asia/Taipei
TZ=Asia/Taipei
這是 local-only test .env。其中 POSTGRES_PASSWORD 與 N8N_ENCRYPTION_KEY 是第 7 週驗證用固定值,不可重用在 production。
| 變數 | 設定值 | 給誰用 | 用途 | 錯誤後果 |
|---|---|---|---|---|
POSTGRES_DB | n8n_week7 | postgres service | 初始化 database name。 | n8n 連到不存在的 database,或連到錯誤 database。 |
POSTGRES_USER | n8n_week7 | postgres service | 初始化 database user。 | n8n 使用者不存在,連線失敗。 |
POSTGRES_PASSWORD | local-only test value | postgres service | 初始化 user password。 | password 不一致時 n8n 無法連 DB。 |
| 變數 | 設定值 | 給誰用 | 用途 | 錯誤後果 |
|---|---|---|---|---|
DB_TYPE | postgresdb | n8n service | 讓 n8n 使用 PostgreSQL,不使用預設 SQLite。 | 忘記時 n8n 可能回到 SQLite。 |
DB_POSTGRESDB_HOST | postgres | n8n service | Compose network 內的 Postgres service hostname。 | 寫 localhost 會指向 n8n container 自己,不是 Postgres container。 |
DB_POSTGRESDB_PORT | 5432 | n8n service | Postgres internal port。 | port 錯誤會 connection refused 或 timeout。 |
DB_POSTGRESDB_DATABASE | ${POSTGRES_DB} | n8n service | n8n 要連的 database。 | database name 不一致時連線或 migration 失敗。 |
DB_POSTGRESDB_USER | ${POSTGRES_USER} | n8n service | n8n 要使用的 database user。 | user 不一致時 authentication failed。 |
DB_POSTGRESDB_PASSWORD | ${POSTGRES_PASSWORD} | n8n service | n8n 連 DB 的 password。 | password 不一致時 authentication failed。 |
| 變數 | 設定值 | 用途 | 第 7 週判斷 |
|---|---|---|---|
N8N_ENCRYPTION_KEY | fixed local-only test value | 加密 database 中的 credentials。 | 必須固定,不能靠首次啟動隨機 key。 |
N8N_HOST | localhost | n8n host 設定。 | local stack 合理;public self-host 時要改成正式 domain。 |
N8N_PORT | 5678 | n8n container 內部 port。 | 不等於 host port;host port 是 5687。 |
N8N_PROTOCOL | http | n8n protocol。 | local stack 合理;production public edge 應改成 HTTPS。 |
GENERIC_TIMEZONE | Asia/Taipei | n8n schedule-oriented nodes timezone。 | 保持工作流排程符合台北時間。 |
TZ | Asia/Taipei | container OS timezone。 | 讓 container 內系統時間行為一致。 |
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS | "true" | 強制 config file 權限。 | 使用字串避免 YAML boolean 解析歧義。 |
docker compose --env-file artifacts/week-07-compose/.env -f artifacts/week-07-compose/compose.yaml config
| 項目 | 結果 |
|---|---|
| project name | n8n-week7 |
| n8n image | docker.n8n.io/n8nio/n8n:2.22.4 |
| Postgres image | postgres:16-alpine |
| n8n port mapping | host 5687 to container 5678 |
| n8n database host | postgres |
| top-level volumes | n8n_data、postgres_data |
| depends_on | postgres: service_healthy |
docker compose --env-file artifacts/week-07-compose/.env -f artifacts/week-07-compose/compose.yaml up -d
Network n8n-week7_default Created
Volume n8n-week7_n8n_data Created
Volume n8n-week7_postgres_data Created
Container n8n-week7-postgres-1 Healthy
Container n8n-week7-n8n-1 Started
NAME IMAGE SERVICE STATUS
n8n-week7-n8n-1 docker.n8n.io/n8nio/n8n:2.22.4 n8n Up
n8n-week7-postgres-1 postgres:16-alpine postgres Up healthy
n8n readiness:
http_status=200
restart 後 readiness:
http_status_after_restart=200
Version: 2.22.4
Building workflow dependency index
Finished building workflow dependency index
Editor is now accessible via:
http://localhost:5678
log 裡 editor 顯示的是 container 內部 n8n port 5678;從 host 瀏覽器要開的是 Compose port mapping 後的 http://localhost:5687。
database 與 table count:
select
current_database() as database_name,
current_user as database_user,
count(*) filter (where schemaname = 'public') as public_table_count
from pg_tables;
database_name=n8n_week7
database_user=n8n_week7
public_table_count=93
必要 tables:
select tablename
from pg_tables
where schemaname='public'
and tablename in ('workflow_entity','credentials_entity','execution_entity','migrations')
order by tablename;
credentials_entity
execution_entity
migrations
workflow_entity
匯入命令:
docker cp artifacts/week-07-compose/week-07-postgres-workflow.json n8n-week7-n8n-1:/tmp/week-07-postgres-workflow.json
docker compose --env-file artifacts/week-07-compose/.env -f artifacts/week-07-compose/compose.yaml exec -T n8n n8n import:workflow --input=/tmp/week-07-postgres-workflow.json
Importing 1 workflows
Successfully imported 1 workflow.
PostgreSQL 查詢:
select id, name, active
from workflow_entity
where id='week07PostgresProbe';
week07PostgresProbe | Week 07 PostgreSQL Probe | f
restart n8n 後:
workflow_count=1
這證明 workflow state 寫入 PostgreSQL,而不是留在 n8n container layer。
| 改善點 | 單容器 Docker | Compose + PostgreSQL |
|---|---|---|
| database | 通常預設 SQLite。 | PostgreSQL 獨立 service。 |
| service boundary | n8n process 與 local DB state 容易綁在同一 user folder。 | n8n 與 database 分 service。 |
| startup order | 手動啟動單 container。 | depends_on + healthcheck。 |
| state boundary | n8n_data 保存 .n8n。 | n8n_data 保存 n8n local state,postgres_data 保存 DB state。 |
| network | 單 container 對外 port。 | n8n 與 postgres 走 internal Compose network。 |
| DB host | 不需要 DB host。 | n8n 用 service name postgres 連 DB。 |
| image control | 可 pin,也常被寫成 latest。 | 本週 pin docker.n8n.io/n8nio/n8n:2.22.4。 |
| migration visibility | SQLite file 內部狀態較不直覺。 | 可用 psql 查 migrations 與 n8n tables。 |
| production 過渡 | 離正式架構較遠。 | 可延伸 reverse proxy、TLS、backup、monitoring。 |
| 缺口 | 為什麼還不夠 |
|---|---|
| TLS | 本週仍是 local HTTP。 |
| Reverse proxy | 尚未接 Caddy/Nginx/Traefik。 |
| Public URL | 尚未有穩定 domain 與 WEBHOOK_URL。 |
| Secrets management | .env 仍是 local file,production 應改用 secrets manager 或至少權限嚴格控管。 |
| Backups | 尚未做 pg_dump、volume backup、restore drill。 |
| Monitoring | 尚未做 health alerts、log retention、metrics。 |
| Upgrade staging | 尚未做 staging stack 與 release notes 驗證。 |
| External task runners | n8n log 提醒 Python task runner internal mode 不建議 production。 |
| Resource limits | 尚未設定 CPU/memory limits。 |
| Access control | 尚未完成正式使用者、SSO、network policy 或 firewall。 |
Week 07 是 production-shaped local stack,不是 production。它把資料庫、service definition 與 volume 邊界拆清楚,但還沒補上 public edge、backup、monitoring 與安全治理。
能逐行說明 Compose 檔裡 n8n、postgres、volumes、environment 的用途。
這份 Compose 檔用 name: n8n-week7 固定 project name,避免和其他 Docker 資源混在一起。services.postgres 使用 postgres:16-alpine,透過 POSTGRES_DB、POSTGRES_USER、POSTGRES_PASSWORD 初始化 n8n_week7 database 與 user,並把 /var/lib/postgresql/data 掛到 postgres_data named volume,確保 DB state 不因 container 重建消失。healthcheck 用 pg_isready 確認 PostgreSQL healthy。services.n8n 使用 docker.n8n.io/n8nio/n8n:2.22.4,透過 depends_on.postgres.condition=service_healthy 等 database ready 後再啟動,ports 將 host 5687 對到 container 5678。n8n 的 environment 裡最重要的是 DB_TYPE=postgresdb 與 DB_POSTGRESDB_HOST=postgres,這讓 n8n 透過 Compose network 連 PostgreSQL,而不是用 SQLite;DB_POSTGRESDB_DATABASE、USER、PASSWORD 要和 Postgres 初始化變數一致。N8N_ENCRYPTION_KEY 必須固定,因為 credentials 需要同一把 key 才能解密。volumes.n8n_data:/home/node/.n8n 保存 n8n local state,top-level volumes 讓 Compose 建立並管理 postgres_data 與 n8n_data。
postgres service 保存 PostgreSQL data,n8n service 用 DB_TYPE=postgresdb 與 DB_POSTGRESDB_HOST=postgres 連它;depends_on 等 DB healthy;postgres_data 存 DB,n8n_data 存 n8n user folder;N8N_ENCRYPTION_KEY 固定 credential 加密 key。
| 檢查項 | 結果 |
|---|---|
| 已讀 Week 07 計畫要求 | 通過 |
| 已核對 Docker Compose 官方文件 | 通過 |
| 已核對 Compose services / environment / volumes 官方文件 | 通過 |
| 已核對 n8n PostgreSQL environment variables | 通過 |
已核對 N8N_ENCRYPTION_KEY 官方說明 | 通過 |
| 已核對 Postgres Official Image environment variables | 通過 |
已建立 artifacts/week-07-compose/compose.yaml | 通過 |
已建立 artifacts/week-07-compose/.env | 通過 |
已固定 N8N_ENCRYPTION_KEY | 通過 |
已設定 DB_TYPE=postgresdb | 通過 |
已設定 DB_POSTGRESDB_* | 通過 |
已使用 depends_on 與 Postgres healthcheck | 通過 |
| 已建立 Postgres named volume | 通過 |
| 已建立 n8n named volume | 通過 |
| 已啟動 PostgreSQL-backed n8n | 通過 |
已確認 http://localhost:5687 回應 | 通過 |
| 已確認 PostgreSQL 有 n8n tables | 通過 |
| 已匯入 workflow probe 並查到 PostgreSQL row | 通過 |
| 已重啟 n8n service 後確認 workflow 仍存在 | 通過 |
未影響第 5 週 n8n-week5-local container | 通過 |
| 未提前執行 Week 08 tunnel 與穩定網域 | 通過 |
第 8 週要處理本機公開、tunnel 與穩定網域。第 7 週已把 n8n 從單容器升級為 Compose + PostgreSQL local stack;第 8 週的重點不是再換 database,而是讓外部服務能穩定呼叫這個 stack,並處理 tunnel URL、WEBHOOK_URL、OAuth callback 與 public URL 穩定性。
Week 07 的成果,是把 n8n 從「一個 container」升級成「可描述的 local stack」:n8n app、PostgreSQL database、named volumes、healthcheck、env vars 與啟動順序都能被閱讀、重建與驗收。
8.0 本週定位
Week 08 的目標是讓外部服務真的碰到本機 n8n,同時明確切開 learning-only tunnel 與 production-ready public URL。本週完成 Cloudflare Quick Tunnel 公開 POST webhook 測試,HTTP 200;測試完成後已取消發布 workflow、移除 live container 的臨時公開 URL、停止 quick tunnel。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| tunnel comparison table | 完成 | 本章 8.4 |
| public webhook 測試紀錄 | 完成 | artifacts/week-08-tunnel/week-08-public-webhook-record.json |
| learning-only vs production-ready 判斷表 | 完成 | 本章 8.6 |
| n8n public URL override | 完成 | artifacts/week-08-tunnel/compose.public-url.override.yaml |
| webhook workflow artifact | 完成 | artifacts/week-08-tunnel/week-08-public-webhook-workflow.json |
| Week 08 驗證腳本 | 完成 | scripts/verify-week-eight.mjs |
本週真正驗證的不是「可以開一個公開網址」,而是 public URL 真的能進入 production webhook。測試完成後立刻收回公開入口,這是本週安全邊界的一部分。
整合來源:docs/week-08-tunnel-public-webhook.md
143| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Webhook 測試與 production webhook | n8n Webhook workflow development | Test URL 只適合建置與調試;Production URL 需要 workflow 已保存並發布。 |
WEBHOOK_URL 與 reverse proxy | n8n webhook URL with reverse proxy | n8n 在 proxy 後面時,要用 WEBHOOK_URL 讓 editor 與外部服務看到正確公開 URL。 |
| deployment env vars | n8n deployment environment variables | 本週使用 WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS;計劃書的 EDITOR_BASE_URL 在 n8n 實際變數名稱是 N8N_EDITOR_BASE_URL。 |
| n8n built-in tunnel | n8n Docker installation | n8n built-in tunnel 是 local development/testing convenience,不是 production 安全做法。 |
| Cloudflare Quick Tunnel | Cloudflare Quick Tunnel | Quick Tunnel 會產生 random trycloudflare.com subdomain,適合測試與開發,不適合 production。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Cloudflare named tunnel / routing | Cloudflare Tunnel routing | production 需要把穩定 hostname 映射到 tunnel service,通常搭配 Cloudflare DNS CNAME 或 tunnel route dns。 |
| ngrok domains | ngrok domains | ngrok 可用 managed/custom domain;random domain 適合臨時分享,reserved/custom domain 才比較適合 callback。 |
| Tailscale Funnel | Tailscale Funnel | Tailscale Funnel 可把 tailnet 內本機服務公開到 broader internet;適合 controlled sharing,但仍要看 beta、policy 與 domain 穩定性。 |
| DDNS | Cloudflare DDNS | DDNS 是把動態 IP 更新到 DNS 的方法,仍需要 TLS、reverse proxy、firewall 與 ISP port 條件。 |
| 項目 | 實測值 |
|---|---|
| 本機 n8n stack | Week 07 Compose stack:n8n-week7 |
| n8n URL | http://localhost:5687 |
| n8n image | docker.n8n.io/n8nio/n8n:2.22.4 |
| database | PostgreSQL 16 Alpine,DB n8n_week7 |
| quick tunnel image | cloudflare/cloudflared:latest |
| cloudflared version | 2026.5.2 |
| quick tunnel public URL | https://gif-decent-pharmacies-eligibility.trycloudflare.com |
temporary WEBHOOK_URL | https://gif-decent-pharmacies-eligibility.trycloudflare.com |
temporary N8N_EDITOR_BASE_URL | https://gif-decent-pharmacies-eligibility.trycloudflare.com |
temporary N8N_PROXY_HOPS | 1 |
| workflow ID | week08PublicWebhookProbe |
| production webhook path | /webhook/week-08-public-post |
| POST result | HTTP 200 |
| cleanup result | workflow 已取消發布;n8n 已重啟回 local-only;quick tunnel 已停止 |
本週採取「短時間公開、完成測試、立刻收回」的方式。這讓我們可以證明 public webhook pipeline 成立,同時不留下長時間公開的本機 editor 或 webhook。
| 路線 | 網域穩定性 | 設定複雜度 | 優點 | 主要風險 | 建議定位 |
|---|---|---|---|---|---|
| n8n built-in tunnel | 通常是臨時或版本實作相關 | 低 | 與 n8n local dev 整合,快速測試 trigger webhook | 官方明確定位 local development/testing;production 安全性與穩定性不足 | learning-only |
| Cloudflare Quick Tunnel | random trycloudflare.com | 低 | 不需 Cloudflare account 或 DNS,能快速驗證外部 POST | random URL 無 uptime 保證,不適合 OAuth callback 或長期 webhook | learning-only |
| Cloudflare named tunnel | 自有穩定 hostname | 中 | 不需開 inbound port,可配 DNS、Access、WAF、DDoS protection | 需管理 Cloudflare account、DNS、tunnel lifecycle 與 access policy | production-ready candidate |
| ngrok random domain | random domain | 低 | 開發者體驗好,適合短期分享與 webhook debug | random URL 會變,外部 service callback 容易失效 | learning-only |
| 路線 | 網域穩定性 | 設定複雜度 | 優點 | 主要風險 | 建議定位 |
|---|---|---|---|---|---|
| ngrok reserved/custom domain | reserved ngrok domain 或自有 domain | 中 | 穩定 callback、TLS 與 inspection tooling 友善 | 依方案、流量、domain ownership 與帳號設定 | production-ready candidate |
| Tailscale Funnel | tailnet DNS name,公開到 internet | 中 | 對既有 Tailscale 使用者很方便,可用 policy 控制誰能建立 Funnel | 公開面要小心權限;Funnel 狀態、beta 屬性與 DNS propagation 需納入 runbook | controlled sharing / selective production |
| DDNS + reverse proxy | 自有 domain 或 subdomain | 中到高 | 可用家用或小型辦公室動態 IP,成本低 | ISP CGNAT、port blocking、TLS renew、router/firewall、IP 更新延遲都會影響可靠性 | lab / small self-host candidate |
Quick Tunnel / random ngrok / n8n built-in tunnel
必須穩定 hostname。
named tunnel / reserved ngrok / VPS reverse proxy / DDNS with TLS
WEBHOOK_URL + N8N_EDITOR_BASE_URL驗證 production webhook。
| 步驟 | 執行結果 |
|---|---|
| 1. 匯入 workflow | week08PublicWebhookProbe 成功匯入 PostgreSQL-backed n8n。 |
| 2. 發布 workflow | n8n publish:workflow --id=week08PublicWebhookProbe 成功,並重啟 n8n 讓 production webhook 生效。 |
| 3. 啟動 quick tunnel | cloudflared tunnel --url http://host.docker.internal:5687 產生 https://gif-decent-pharmacies-eligibility.trycloudflare.com。 |
| 4. 注入公開 URL | Compose override 設定 WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS=1。 |
| 5. 外部 POST | POST https://gif-decent-pharmacies-eligibility.trycloudflare.com/webhook/week-08-public-post 回 HTTP 200。 |
| 6. 回應確認 | n8n 回傳 ok=true、week=8、receivedSource=week08-external-post、forwardedProto=https。 |
| 7. 清理 | unpublish:workflow 後重啟 n8n,移除 TryCloudflare env,停止 cloudflared container。 |
{
"ok": true,
"week": 8,
"probe": "public-webhook",
"tunnel": "cloudflare-quick-tunnel",
"receivedSource": "week08-external-post",
"receivedWeek": 8,
"publicHost": "gif-decent-pharmacies-eligibility.trycloudflare.com",
"forwardedProto": "https",
"checkedDate": "2026-05-27"
}
| 判斷項 | learning-only 可以接受 | production-ready 必須具備 | Week 08 實測結論 |
|---|---|---|---|
| URL 穩定性 | random URL 可接受 | stable hostname、可長期持有、可被外部服務固定設定 | Quick Tunnel 是 random URL,因此只屬 learning-only。 |
| OAuth callback | 不接 OAuth,或只做短期 sandbox | provider callback URL 固定、HTTPS、domain ownership 清楚 | random tunnel URL 不可作正式 OAuth callback。 |
| Webhook lifetime | 單次測試,測完就關 | webhook URL 長期不變,並有監控與重試策略 | 本週測完立刻停止 tunnel。 |
| TLS | provider 自動給臨時 HTTPS 即可 | TLS renew、proxy headers、secure cookie、domain policy 都要有 runbook | Quick Tunnel 可驗證 HTTPS path,但不等於 production TLS ownership。 |
| n8n env | 臨時注入 WEBHOOK_URL | env 持久化、版本控管、secret 管理、restart 流程可重複 | 本週 override 留作學習 artifact,live stack 已還原 local-only。 |
| access control | 本機短期測試 | editor 不應裸露;需 SSO、2FA、IP/access policy 或 Cloudflare Access | Quick Tunnel 不應長時間公開 editor。 |
| operational ownership | 手動可接受 | backup、restore、logging、incident response、update cadence | 第 14 週後才進入正式維運 runbook。 |
OAuth provider 通常要求 callback URL 事先登錄,random tunnel 一旦重開就換網址,callback mismatch 會讓授權流程失敗。就算今天能登入,明天重啟 tunnel 也可能失效。
Slack、GitHub、Stripe、Line、Meta 或任何 webhook provider 一旦保存舊 URL,新 URL 不會自動同步。random tunnel 對「一次打通」很方便,對「下週還要穩定收事件」不可靠。
production URL 應該能回答誰擁有 domain、誰能改 DNS、TLS 如何續期、proxy headers 是否正確、editor 是否受保護、出事時如何切回。random trycloudflare.com URL 不能承擔這些責任。
random tunnel URL 對 OAuth callback 與長期 webhook 的風險不是小瑕疵,而是 architecture mismatch。Week 08 只能把它標記為 learning-only;production-ready 必須換成 named tunnel、reserved/custom domain、VPS reverse proxy、DDNS with TLS-aware reverse proxy,或 n8n Cloud 這類穩定入口。
| 檢查項 | 結果 |
|---|---|
| 已比較 n8n built-in tunnel、Cloudflare Quick Tunnel、Cloudflare named tunnel、ngrok、Tailscale Funnel、DDNS | 通過 |
已設定並驗證 WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS | 通過 |
| 已完成外部 POST production webhook 測試 | 通過 |
| 已記錄 public webhook 測試紀錄 | 通過 |
| 已指出 random tunnel URL 對 OAuth callback 與長期 webhook 的風險 | 通過 |
| 已避免把 quick tunnel 留在 live production-like 狀態 | 通過 |
可以明確說明 random tunnel URL 不適合 OAuth callback 與長期 webhook,並能用實測紀錄證明 production webhook pipeline 成功。
Week 09 會進入 n8n Cloud 與最低維運路線。第 8 週留下的核心判斷是:如果團隊不想管理 public URL、TLS、DB、backup 與 patch cadence,n8n Cloud 是合理的低維運起點;如果要 self-host,就不能只看「能不能公開」,還要把 stable URL、資料保存、安全與操作責任一起納入。
Week 08 的成果是一條短暫但完整的 public webhook pipeline,以及一條清楚的紅線:random tunnel 能用來學,不能默默變成 production callback。
9.0 本週定位
Week 09 要回答「什麼情況下最好的部署就是不要 self-host?」本週結論是:beginner 或非工程團隊預設應先選 n8n Cloud,除非已經有明確的 custom nodes、CLI、bash、host-level control、特殊資料治理或高階 scaling 需求。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| Cloud 適用情境卡 | 完成 | 本章 9.3;artifacts/week-09-cloud/week-09-cloud-fit-matrix.json |
| execution volume 估算表 | 完成 | 本章 9.4;artifacts/week-09-cloud/week-09-execution-volume-estimator.csv |
| Cloud vs self-host 責任分界 | 完成 | 本章 9.5 |
| beginner / 非工程團隊建議 | 完成 | 本章 9.7 |
| Week 09 驗證腳本 | 完成 | scripts/verify-week-nine.mjs |
第 8 週證明本機可以透過 tunnel 收公開 webhook,但也證明 random tunnel 不該承擔 production callback。第 9 週把問題往前推一步:如果團隊真正需要穩定 public URL、低維運、可預估費用與快速上線,那最好的部署可能就是 n8n Cloud。
整合來源:docs/week-09-n8n-cloud-low-maintenance.md
157| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n Cloud / pricing snapshot | n8n pricing | 官方 pricing page 顯示 Cloud Starter / Pro / Enterprise 的 executions、concurrency、saved executions、retention、projects、users 與部分功能差異;本文件數字是 2026-05-27 查核快照。 |
| execution quota | n8n executions | paid plan 的 quota 只計 production executions;manual executions 不計入 quota。 |
| Cloud data management | n8n Cloud data management | Cloud 仍有 memory、storage、execution data retention 與 pruning 限制;heavy workflow 需要降低保存資料與切批。 |
| Cloud concurrency | n8n Cloud concurrency | Cloud 依 plan 限制 concurrent production executions;超過限制會排隊,且 regular mode 的 concurrency 是 instance-level。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Cloud version update | n8n Cloud updates | Cloud 仍需要 owner 管理版本選擇;n8n 建議至少每月更新,且長期不更新會進入自動更新節奏。 |
| Cloud workflow export | Download workflows from Cloud | Cloud instance owner 可從最新 backup 下載 workflows;trial 結束後有 90 天下載窗口。 |
| Projects / RBAC | n8n Projects and RBAC | n8n 用 projects 管理 workflows 與 credentials,並按角色控制權限;不同 plan 的 projects/roles 數量不同。 |
本章不把 Cloud 說成「不用管任何事」,而是把責任縮到 workflow correctness、execution volume、版本選擇與團隊權限;底層 hosting、public URL 與資料庫維護則由 Cloud 承擔較多。
| 情境 | 建議 | 為什麼 |
|---|---|---|
| beginner、創辦人、行銷或營運團隊要把 webhook 與 schedule workflow 放上正式環境 | Cloud first | 不需要自行管理 DNS、TLS、reverse proxy、PostgreSQL、volume、encryption key、OS patch、Docker image update。 |
| 小團隊有多個 production workflows,但沒有特殊 runtime 控制需求 | Cloud with plan review | 用 execution volume 和 concurrency 選 Starter、Pro 或 Enterprise,比一開始維運 VPS 更少摩擦。 |
| 團隊需要穩定 public URL 與 OAuth callback,但沒有 DevOps 能量 | Cloud first | Cloud 的 hosted URL 比本機 random tunnel 更適合長期 callback。 |
| 情境 | 建議 | 為什麼 |
|---|---|---|
| 工作流程以 SaaS API、webhook、schedule、HTTP Request、Google Sheets、Slack、Notion、CRM 等常見節點為主 | Cloud first | 這些通常不需要主機層權限,讓團隊把精力放在 workflow correctness。 |
| 工作流程需要 custom nodes、CLI、bash scripts、host-level packages、私有網段直連、特殊 file system、特殊 binary storage | Self-host candidate | 這些需求不是單純 workflow 問題,而是 runtime / infrastructure control 問題。 |
| 工作流程長時間處理大型檔案、AI 批次、上萬列資料、影音或大量 binary data | Cloud only with proof | Cloud 有 memory 與 storage guardrails;先切批與降低 execution data saving,仍不夠才 self-host 或 Enterprise。 |
No:看執行量;Yes:進 self-host evaluation。
能估就做 Cloud plan review;不能估就先試算。
把精力放在 workflow correctness 與團隊使用。
這些才是 self-host 的真理由。
執行量估算的核心規則很簡單:production execution 是 workflow 自動被 trigger、schedule、polling 或 webhook 啟動的一次完整執行。manual testing 不計入 paid execution quota,但仍會吃 instance memory。
| 工作負載 | trigger 型態 | 估算公式 | 月執行量 | 對 Cloud 的含義 |
|---|---|---|---|---|
| Daily CRM cleanup | schedule | 1 run/day * 31 days | 31 | Starter 友善,主要看 credential 與錯誤通知。 |
| Hourly support digest | schedule | 24 runs/day * 31 days | 744 | Starter 友善,但 7 天 execution retention 可能只夠短期 debug。 |
| Every 5 minute monitor | schedule | 12 runs/hour * 24 hours/day * 31 days | 8,928 | 接近或超過 Pro 起點;要看 peak concurrency。 |
| Lead intake webhook | webhook | 80 events/day * 31 days | 2,480 | 幾乎吃滿 Starter baseline,launch 前要留 buffer。 |
| 工作負載 | trigger 型態 | 估算公式 | 月執行量 | 對 Cloud 的含義 |
|---|---|---|---|---|
| Payment event webhook | webhook | 500 events/day * 31 days | 15,500 | Pro 或 Enterprise candidate;burst concurrency 比平均值更重要。 |
| Support chatbot | chatbot | 120 conversations/week * 8 messages/conversation * 4.345 weeks/month | 4,172 | 通常 Pro candidate;還要另估 AI provider 成本。 |
| AI document processing | webhook | 50 documents/day * 31 days | 1,550 | execution 數不高,但 binary data 與 memory 可能先成為瓶頸。 |
| Manual workflow testing | manual | manual testing during development | 0 | 不計 quota,但大型 manual run 仍會消耗 memory。 |
| 類型 | 公式 |
|---|---|
| schedule | 每次排程觸發 = 1 production execution;每月量等於觸發次數。 |
| webhook | 外部事件數 = production executions;每天事件數乘以 30 或 31。 |
| polling trigger | polling 次數 = production executions;即使沒有新資料,也要確認 trigger 行為與實際 execution 計算。 |
| chatbot | conversation 數 * 平均 message 數;每則 message 是否啟動一次 workflow 要按設計確認。 |
| manual test | 不計 paid execution quota;但仍可能造成 memory 壓力。 |
Cloud plan review 要同時看月 production executions 與 peak concurrency。payment event、webhook burst、chatbot message 這類流量,平均值看起來溫和,尖峰時才會把 queue、timeout 與 retry 問題暴露出來。
| 責任項 | n8n Cloud | self-host |
|---|---|---|
| public URL | 由 hosted instance 提供穩定入口 | 自行處理 DNS、TLS、reverse proxy、port、proxy headers、callback URL。 |
| database | 不需要自行維護 PostgreSQL | 自行維護 PostgreSQL、backup、restore、migration、capacity。 |
| encryption key | 不需要自行保存 host volume 的 key | 必須保存 N8N_ENCRYPTION_KEY,否則 credential 復原會出問題。 |
| updates | Cloud dashboard 管理版本;長期不更新會觸發自動更新節奏 | 自行決定 image、版本、maintenance window、rollback。 |
| execution quota | 按 plan 與 production executions 管理 | 仍可能有 license quota;硬體資源由自己負責。 |
| 責任項 | n8n Cloud | self-host |
|---|---|---|
| concurrency | plan-based production concurrency;超過會 queue | 可用 own sizing、queue mode、workers 調整,但維運成本上升。 |
| execution data retention | Starter / Pro / Enterprise 有不同 saved executions 與 retention | 自行設定 pruning、DB 容量、binary data storage。 |
| custom nodes | 需按 Cloud 支援與 policy | 自行安裝與維護,承擔供應鏈與相容性風險。 |
| CLI / bash / host-level control | 不適合作為主要理由 | self-host 的核心理由之一,但也意味著要負責安全邊界。 |
| incident response | Cloud 承擔底層 hosting,團隊仍要處理 workflow-level errors | 團隊要處理 infrastructure + workflow 雙層事故。 |
Cloud 不是把責任歸零,而是把底層 hosting 責任降到最低;self-host 不是能力展示題,而是把 infrastructure + workflow 的雙層事故都接到自己身上。
| Plan | hosted by | execution 起點 | concurrency | saved executions | log retention | shared projects | 適合 |
|---|---|---|---|---|---|---|---|
| Starter | n8n | 2,500 / month | 5 | 2,500 | 7 days | 1 | 初學、低量正式 automation、早期 validation。 |
| Pro | n8n | 10,000 / month 起 | 20 | 25,000 | 30 days | 3 | 小團隊、需要 execution search、global variables、更多 collaboration。 |
| Enterprise | n8n or self-hosted | custom | 200+ | 50,000 | extended / unlimited per Cloud data docs | unlimited | governance、SLA、SSO、external secrets、log streaming、scale。 |
| 限制 | Starter | Pro | Enterprise | 設計含義 |
|---|---|---|---|---|
| Memory | 320MiB RAM | Pro-1 640MiB;Pro-2 1280MiB | 4096MiB | execution 數低不代表安全;大型資料、Code node、binary data 仍可能 OOM。 |
| CPU | 10 millicore burstable | 20 或 80 millicore burstable | 80 millicore burstable | 長時間 CPU-heavy workflow 不應只用 execution count 判斷。 |
| Data storage | up to 100GB per instance | up to 100GB per instance | up to 100GB per instance | 要降低不必要 execution data 保存,避免靠人工 pruning 救火。 |
| Queue mode | 不適用 | 不適用 | Cloud Enterprise 可洽 n8n | 若 queue mode 是剛需,通常已不是 beginner 路線。 |
大型資料、Code node、binary data、AI enrichment、PDF 或影音處理,可能先撞到 memory、CPU 或 storage,而不是先撞到 execution quota。
對 beginner 或非工程團隊,n8n Cloud 優先不是因為 self-host 不好,而是因為它把錯誤面積縮小。前 8 週已經看到 self-host 要同時處理 volume、PostgreSQL、encryption key、public URL、tunnel、proxy、webhook、OAuth callback 與 cleanup。這些都不是 workflow automation 本身,卻都會讓 production 失敗。
| 理由 | 實際價值 |
|---|---|
| 少掉 infrastructure choices | 團隊不用先成為 Docker、PostgreSQL、DNS、TLS、reverse proxy 專家。 |
| stable public URL | webhook provider 與 OAuth callback 不必依賴 random tunnel。 |
| execution billing 可估算 | 用 schedule、webhook、chatbot 的觸發頻率估月量,比估 VPS incident 成本容易。 |
| manual testing 不計 quota | 初學者能先測 workflow correctness,不會因手動測試直接吃掉 paid execution quota。 |
| 可以晚點再 self-host | 只有在 custom nodes、CLI、bash、host-level control、data residency、heavy binary / AI workload 真的出現時再轉。 |
| 問題 | 答案是「否」時 | 答案是「是」時 |
|---|---|---|
| 需要 custom nodes 嗎? | Cloud first | self-host candidate |
| 需要 CLI 或 bash 嗎? | Cloud first | self-host candidate |
| 需要安裝 host-level packages 或私有網段直連嗎? | Cloud first | self-host candidate |
| 月 production executions 能被估算嗎? | 先做試算,不急著部署 | Cloud plan review |
| 有專人負責 DB / backup / TLS / patch / incident 嗎? | Cloud first | 可以評估 VPS / Compose |
| 需要 queue mode、workers、external storage 或 multi-main 嗎? | Cloud / Pro 足夠 | Enterprise 或成熟 self-host |
| 工作負載 | 建議 | 判斷理由 |
|---|---|---|
| 小量 SaaS sync、daily report、CRM cleanup、Slack/Notion 通知 | 留在 Cloud | 低量、標準節點、低 runtime 控制需求。 |
| 穩定 webhook,例如 lead form、calendar booking、support ticket | 留在 Cloud | 需要 stable URL,Cloud 比 random tunnel 更合理。 |
| 小團隊 production workflows,月量 10k 左右 | Cloud Pro review | execution search、global variables、更多 concurrency 對 production debugging 有價值。 |
| 高峰 webhook burst、payment events、大量 chatbot message | Cloud Pro / Enterprise review | 要看 peak concurrency、retry、queue 行為,不只看月量。 |
| 工作負載 | 建議 | 判斷理由 |
|---|---|---|
| 大型檔案、影音、PDF、AI enrichment 批次 | Proof before Cloud | 先用小批量證明 memory 與 storage;必要時 self-host 或 Enterprise。 |
| 私有套件、custom nodes、shell scripts、內網 database 直連 | self-host | 這些是 runtime control,不只是 plan upgrade。 |
| 合規要求指定 data residency、private network、external secret store、central log streaming | Enterprise / self-host | 需求本質是 governance 與 control。 |
留在 Cloud 的關鍵不是「流量永遠小」,而是需求仍然是 workflow 與 hosted plan 可處理的問題;需要 self-host 的關鍵也不是「我想更自由」,而是 runtime control、governance 或 infrastructure ownership 已經成為必要條件。
| 檢查項 | 結果 |
|---|---|
| 已理解 n8n Cloud hosted plan 與 execution billing | 通過 |
| 已估算 schedule / webhook / chatbot 月執行量 | 通過 |
| 已列出 self-host 才適合的需求:custom nodes、CLI、bash、host-level control | 通過 |
| 已完成 Cloud 適用情境卡 | 通過 |
| 已完成 execution volume 估算表 | 通過 |
| 已完成 Cloud vs self-host 責任分界 | 通過 |
| 已能為 beginner 或非工程團隊提出 n8n Cloud 優先理由 | 通過 |
beginner 或非工程團隊若沒有硬性的 runtime control 需求,應先選 n8n Cloud。self-host 不是能力展示題,而是責任承接題;等需求真的超出 Cloud plan、Cloud policy 或 hosted runtime,再進入 Week 10 的 VPS + Docker Compose + Caddy 設計。
Week 10 會設計 VPS + Docker Compose + Caddy 藍圖。第 9 週留下的門檻是:只有當 Cloud 不符合需求,才值得承接 VPS 的 DNS、firewall、Caddy、PostgreSQL、n8n env、backup 與 public URL 責任。這能避免把「我想 self-host」誤當成「我已經準備好維運 production」。
Week 09 的成果是一個乾淨的部署選擇模型:先用 Cloud 降低維運面積;只有 custom runtime、host-level control、governance、heavy data 或 advanced scaling 成為硬需求時,才把 self-host 放回桌上。
10.0 本週定位
Week 10 建立最平衡的 self-hosted n8n production 起點:單台 VPS、Docker Compose、PostgreSQL、Caddy automatic HTTPS。實作結果是完成 https://n8n.example.com 架構模擬,重點驗收是 production webhook URL 不會指回 localhost。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| VPS 部署藍圖 | 完成 | artifacts/week-10-vps-caddy/vps-deployment-blueprint.json |
| Docker Compose 模擬檔 | 完成 | artifacts/week-10-vps-caddy/compose.yaml |
| Caddyfile 與 env vars 解說 | 完成 | artifacts/week-10-vps-caddy/Caddyfile;本章 10.5 |
| firewall / DNS / HTTPS 檢查表 | 完成 | artifacts/week-10-vps-caddy/firewall-dns-https-checklist.csv |
| Week 10 驗證腳本 | 完成 | scripts/verify-week-ten.mjs |
第 9 週說明 Cloud 優先;第 10 週只在 Cloud 不適合時才上場。這條路線比 Kubernetes 簡單,但已經承接 production 責任,所以 public URL、TLS、proxy、DB、volume、firewall 和 webhook URL 要一起檢查。
整合來源:docs/week-10-vps-docker-compose-caddy.md
177| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n reverse proxy webhook URL | n8n webhook URL behind proxy | n8n 在 reverse proxy 後方時,要設定 WEBHOOK_URL,並設定 N8N_PROXY_HOPS=1。 |
| n8n Docker + PostgreSQL | n8n Docker installation | n8n 支援 PostgreSQL;即使使用 PostgreSQL,仍建議持久化 .n8n 目錄,因為其中還有 encryption keys、logs、source control feature assets 等資料。 |
| n8n deployment env vars | Deployment environment variables | 本週固定 N8N_HOST、N8N_PROTOCOL、WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS、N8N_ENCRYPTION_KEY。 |
| n8n database env vars | Database environment variables | PostgreSQL 使用 DB_TYPE=postgresdb 與 DB_POSTGRESDB_*。 |
| n8n security env vars | Security environment variables | N8N_SECURE_COOKIE=true 適合 HTTPS production;N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true 強化設定檔權限。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Docker Compose | Docker Compose | Compose 用單一 YAML 定義 services、networks、volumes,並管理 start/stop/logs/lifecycle。 |
| Docker Compose services | Compose services | 本週使用 depends_on.condition: service_healthy、named volumes、service networks 與不公開 n8n/PostgreSQL host ports。 |
| Caddy reverse proxy | Caddy reverse_proxy | Caddy reverse_proxy 將 request proxy 到 upstream;本週 upstream 是 Docker service name n8n:5678。 |
| Caddy automatic HTTPS | Caddy automatic HTTPS | Caddy 會自動管理憑證並把 HTTP 導向 HTTPS;public domain 需要 DNS 指到機器且 80/443 對外可達。 |
| Caddy reverse proxy quick-start | Caddy reverse proxy quick-start | 以 domain name 作為 Caddyfile site address,Caddy 會嘗試取得 publicly-trusted certificate。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Ubuntu UFW firewall | Ubuntu firewall / UFW | Ubuntu 預設防火牆工具是 ufw;本週 checklist 僅開 SSH、HTTP、HTTPS,不開 5678/5432。 |
| DNS records | Cloudflare DNS records | DNS 需建立 A record,將 n8n.example.com 指向 VPS public IPv4;是否代理需依 provider 與 TLS 策略決定。 |
Week 10 的事實基礎是「n8n 在 Caddy 後方,Caddy 是唯一 public HTTP/HTTPS 入口,PostgreSQL 和 n8n application port 都不直接暴露」。只要這條邊界被破壞,就不是本週設計的 VPS 路線。
| Layer | 設計 | 對外暴露 | 持久化 |
|---|---|---|---|
| DNS | A n8n.example.com -> VPS_PUBLIC_IPV4 | public DNS | DNS provider |
| Firewall | allow 22/tcp、80/tcp、443/tcp;deny public 5678/tcp、5432/tcp | 22/80/443 only | OS firewall rules |
| Caddy | caddy:2-alpine,接收 80/443,reverse proxy 到 n8n:5678 | 80/443 | caddy_data、caddy_config |
| n8n | docker.n8n.io/n8nio/n8n:2.22.4,只在 Docker network expose 5678 | no host port | n8n_data |
| PostgreSQL | postgres:16-alpine,只在 internal Docker network 5432 | no host port | postgres_data |
| 原則 | 具體做法 |
|---|---|
| Public traffic 只走 Caddy | Compose 只有 caddy publish 80:80 與 443:443。 |
| n8n 不直接對外 | n8n 使用 expose: 5678,不使用 ports: 5678:5678。 |
| PostgreSQL 不直接對外 | postgres 沒有 host ports,且只接到 internal Docker network。 |
| Webhook URL 必須是 public HTTPS | WEBHOOK_URL=https://n8n.example.com/,不是 http://localhost:5678/。 |
| Editor URL 必須是 public HTTPS | N8N_EDITOR_BASE_URL=https://n8n.example.com/。 |
| Proxy hop 明確 | N8N_PROXY_HOPS=1,代表 n8n 信任前方一層 Caddy reverse proxy。 |
| Encryption key 固定 | N8N_ENCRYPTION_KEY 由 .env 提供,不能讓 n8n 隨機生成後遺失。 |
只允許 SSH、HTTP、HTTPS;不開 5678/5432。
唯一 public HTTP/HTTPS 入口,負責 automatic HTTPS 與 reverse proxy。
n8n 只 expose 5678;PostgreSQL 只在 internal network。
Week 10 的安全感不是來自「服務能開」,而是來自「只有該公開的東西公開」。Caddy 可以被 internet 看到,n8n application port 和 PostgreSQL 不可以。
| Compose 區塊 | 設計 | 解說 |
|---|---|---|
services.caddy | image: caddy:2-alpine,publish 80/443 | VPS 的唯一 public HTTP/HTTPS 入口。 |
services.caddy.volumes | bind ./Caddyfile,named volumes caddy_data、caddy_config | Caddyfile 由版本控管;certificate 與 Caddy runtime data 持久化。 |
services.n8n | no host ports,expose: 5678 | 只讓 Caddy 在 Docker network 內連到 n8n。 |
services.n8n.environment | DB_TYPE=postgresdb、WEBHOOK_URL=https://n8n.example.com/ | 同時處理 state layer 與 public URL layer。 |
services.n8n.volumes | n8n_data:/home/node/.n8n | 保存 n8n user folder 內的重要資料。 |
| Compose 區塊 | 設計 | 解說 |
|---|---|---|
services.postgres | postgres:16-alpine,healthcheck pg_isready | n8n 要等 PostgreSQL healthy 後才啟動。 |
networks.frontdoor | caddy + n8n | reverse proxy 到 app。 |
networks.internal | n8n + postgres,internal: true | DB network 不接 public gateway。 |
volumes | caddy_data、caddy_config、n8n_data、postgres_data | 更新 container 不等於刪除 state。 |
artifacts/week-10-vps-caddy/compose.yaml
這份 Compose 檔是 production-shaped blueprint,不會在本機直接啟動 public domain,因為 n8n.example.com 必須先有真實 DNS A record 指向 VPS public IP。驗證腳本會用 docker compose config 確認 YAML、env interpolation、services、ports、networks、volumes 都能正確 render。
這裡驗證的是架構可部署、public ports 正確、internal networks 清楚、env vars render 正確,而不是假裝本機已經擁有 n8n.example.com 的公開 DNS。
artifacts/week-10-vps-caddy/compose.yamlname: n8n-week10-vps
services:
caddy:
image: caddy:2-alpine
restart: unless-stopped
depends_on:
n8n:
condition: service_started
ports:
- "80:80"
- "443:443"
volumes:
- type: bind
source: ./Caddyfile
target: /etc/caddy/Caddyfile
read_only: true
- caddy_data:/data
- caddy_config:/config
networks:
- frontdoor
n8n:
image: docker.n8n.io/n8nio/n8n:2.22.4
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
DB_POSTGRESDB_USER: ${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
DB_POSTGRESDB_SCHEMA: public
N8N_HOST: ${N8N_DOMAIN}
N8N_PORT: 5678
N8N_PROTOCOL: https
WEBHOOK_URL: ${N8N_PUBLIC_URL}
N8N_EDITOR_BASE_URL: ${N8N_PUBLIC_URL}
N8N_PROXY_HOPS: 1
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
N8N_RUNNERS_ENABLED: "true"
N8N_SECURE_COOKIE: "true"
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
TZ: ${TZ}
expose:
- "5678"
volumes:
- n8n_data:/home/node/.n8n
networks:
- frontdoor
- internal
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 10s
timeout: 5s
retries: 10
start_period: 20s
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- internal
networks:
frontdoor:
internal:
internal: true
volumes:
caddy_data:
caddy_config:
n8n_data:
postgres_data:
n8n.example.com {
encode zstd gzip
reverse_proxy n8n:5678 {
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
}
}
| 行為 | 解說 |
|---|---|
n8n.example.com | Caddy 的 site address;有真實 public DNS 且 80/443 可達時,Caddy 會嘗試自動 HTTPS。 |
encode zstd gzip | 對支援的 response 做壓縮。 |
reverse_proxy n8n:5678 | Docker network 內用 service name 找到 n8n。 |
X-Forwarded-For | 告訴 n8n 原始 client IP 資訊。 |
X-Forwarded-Host | 告訴 n8n 原始 public host。 |
X-Forwarded-Proto | 告訴 n8n 原始 request 是 HTTPS。 |
| 變數 | 範例值 | 目的 |
|---|---|---|
N8N_DOMAIN | n8n.example.com | n8n 對外 hostname。 |
N8N_PUBLIC_URL | https://n8n.example.com/ | 同時餵給 WEBHOOK_URL 與 N8N_EDITOR_BASE_URL。 |
N8N_HOST | ${N8N_DOMAIN} | n8n 自身 public host 設定。 |
N8N_PROTOCOL | https | public access protocol。 |
WEBHOOK_URL | ${N8N_PUBLIC_URL} | webhook node 顯示與外部服務註冊使用的 base URL。 |
N8N_EDITOR_BASE_URL | ${N8N_PUBLIC_URL} | editor public URL,也會影響部分 redirect URL。 |
| 變數 | 範例值 | 目的 |
|---|---|---|
N8N_PROXY_HOPS | 1 | n8n 前方有一層 reverse proxy。 |
N8N_ENCRYPTION_KEY | fixed secret | 加密 credentials;必須備份。 |
N8N_SECURE_COOKIE | true | production HTTPS cookie 安全設定。 |
DB_TYPE | postgresdb | n8n 使用 PostgreSQL。 |
DB_POSTGRESDB_HOST | postgres | Docker network 內的 Postgres service name。 |
N8N_PROTOCOL=https 與 WEBHOOK_URL=https://n8n.example.com/ 描述的是 public side;n8n container 內部仍然聽 5678,由 Caddy 在 Docker network 內用 HTTP 代理。這是正常的 reverse proxy pattern。
artifacts/week-10-vps-caddy/.env.exampleN8N_DOMAIN=n8n.example.com
N8N_PUBLIC_URL=https://n8n.example.com/
GENERIC_TIMEZONE=Asia/Taipei
TZ=Asia/Taipei
POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=CHANGE_ME_postgres_password_32_chars_minimum
N8N_ENCRYPTION_KEY=CHANGE_ME_fixed_n8n_encryption_key_32_chars_minimum
CHANGE_ME 不能進 production。正式部署前要替換 PostgreSQL password 與固定的 N8N_ENCRYPTION_KEY,並把 secret 備份到受控位置。
| Layer | 檢查 | 預期結果 |
|---|---|---|
| DNS | A n8n.example.com -> VPS_PUBLIC_IPV4 | 網域解析到 VPS。 |
| DNS | TTL 合理,例如 300 秒到 1 小時 | 初次部署與切換時不會被長 TTL 卡太久。 |
| Firewall | allow 22/tcp from admin IP range | 能管理 VPS,且降低 SSH 暴露面。 |
| Firewall | allow 80/tcp from internet | Caddy 可處理 HTTP redirect 與 ACME HTTP challenge。 |
| Firewall | allow 443/tcp from internet | 使用者與 webhook provider 走 HTTPS。 |
| Firewall | deny public 5678/tcp | n8n 不繞過 Caddy。 |
| Layer | 檢查 | 預期結果 |
|---|---|---|
| Firewall | deny public 5432/tcp | PostgreSQL 不暴露到 internet。 |
| HTTPS | curl -I https://n8n.example.com | 回應來自 Caddy 後方的 n8n,HTTP status 為 200 或 302。 |
| Caddy | docker compose logs caddy | 可看到 certificate issuance / renewal 或正常 HTTPS serving log。 |
| n8n | editor webhook base URL | 不出現 localhost、127.0.0.1、:5678 public host。 |
| OAuth | provider callback URL | 使用 https://n8n.example.com/rest/oauth2-credential/callback 類型的 stable HTTPS URL。 |
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
如果管理者 IP 固定,SSH 應改成只允許該 IP 或 VPN 範圍。5678/tcp 和 5432/tcp 不應開給 internet;Compose 也不 publish 這兩個 port。
SSH、HTTP redirect / ACME、HTTPS。
n8n application port 與 PostgreSQL 不直接公開。
https://n8n.example.com 模擬與驗收本週沒有把 n8n.example.com 指到一台真 VPS,因此驗收採「完整架構模擬」。
| 驗收項 | 模擬方式 | 通過條件 |
|---|---|---|
| Compose 可部署 | docker compose --env-file .env.example -f compose.yaml config | render 後有 caddy、n8n、postgres。 |
| Public ports 正確 | 檢查 rendered config | 只有 Caddy publish 80/443。 |
| n8n 不公開 host port | 檢查 rendered config | 不存在 5678:5678。 |
| PostgreSQL 不公開 host port | 檢查 rendered config | 不存在 5432:5432。 |
| Caddyfile 語法正確 | caddy validate | Caddyfile 可被 Caddy 接受。 |
| Webhook URL 正確 | 檢查 env/rendered config | WEBHOOK_URL=https://n8n.example.com/。 |
| Editor URL 正確 | 檢查 env/rendered config | N8N_EDITOR_BASE_URL=https://n8n.example.com/。 |
| localhost 不進入 public URL | 檢查 env/rendered config | WEBHOOK_URL 與 N8N_EDITOR_BASE_URL 不含 localhost、127.0.0.1、:5678。 |
localhosthttp://localhost:5678/webhook/...,代表 public URL layer 沒設好。
應先查 WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS、DNS、Caddyfile,而不是先改 workflow。
| 步驟 | 命令或動作 | 驗收 |
|---|---|---|
| 1 | 建立 VPS,取得 public IPv4 | 能 SSH 登入。 |
| 2 | 建立 DNS A record:n8n.example.com -> VPS_PUBLIC_IPV4 | dig n8n.example.com 回 VPS IP。 |
| 3 | 安裝 Docker Engine 與 Compose plugin | docker compose version 成功。 |
| 4 | 放置 compose.yaml、Caddyfile、.env 到部署目錄 | ls 可看到三個檔案。 |
| 5 | 編輯 .env,替換 password 與 N8N_ENCRYPTION_KEY | 不使用 CHANGE_ME。 |
| 6 | 設定 firewall | 只開 22/80/443。 |
| 步驟 | 命令或動作 | 驗收 |
|---|---|---|
| 7 | 驗證 Compose render | docker compose --env-file .env -f compose.yaml config 成功。 |
| 8 | 啟動 stack | docker compose --env-file .env -f compose.yaml up -d。 |
| 9 | 查看 Caddy logs | 憑證取得或 HTTPS serving 無錯誤。 |
| 10 | 開啟 https://n8n.example.com | 能進入 n8n editor setup/login。 |
| 11 | 建立 webhook workflow | Production URL 顯示 https://n8n.example.com/webhook/...。 |
| 12 | 打外部 POST webhook | HTTP 200 或 workflow 預期 response。 |
| 禁止項 | 原因 |
|---|---|
不固定 N8N_ENCRYPTION_KEY | credential backup/restore 會失去可預期性。 |
不開 public 5678/tcp | n8n 應在 Caddy 後方。 |
不開 public 5432/tcp | PostgreSQL 不需要暴露給 internet。 |
| 不用 random tunnel URL 當 production callback | 會破壞 OAuth callback 與長期 webhook。 |
不讓 WEBHOOK_URL 指向 localhost | 外部服務無法呼叫使用者本機的 localhost。 |
| 症狀 | 優先檢查 |
|---|---|
| Caddy 拿不到憑證 | DNS A record 是否指向 VPS;80/443 是否開放;Caddy logs 是否出現 ACME challenge 錯誤。 |
https://n8n.example.com 打不開 | VPS firewall、cloud provider security group、Caddy container、Caddyfile domain。 |
| editor 開了但 webhook URL 是 localhost | WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS、container env。 |
| OAuth callback mismatch | OAuth provider callback 是否使用 stable HTTPS domain;n8n editor URL 是否也一致。 |
| 症狀 | 優先檢查 |
|---|---|
| n8n 起不來 | docker compose logs n8n、PostgreSQL healthcheck、DB env vars、encryption key。 |
| workflow 或 credential 更新後消失 | named volumes 是否存在;是否誤刪 n8n_data 或 postgres_data。 |
| database connection refused | postgres service health、internal network、DB_POSTGRESDB_HOST=postgres。 |
先確認入口層:DNS、firewall、Caddy、HTTPS。入口層通了,再查 n8n env、PostgreSQL health、volume 與 workflow。不要看到 webhook 失敗就先改 workflow,很多時候真正壞的是 public URL layer。
Week 11 會比較 Railway、Zeabur、Render、Fly.io。第 10 週的底線會沿用到 PaaS:服務能啟動不等於 state 可長期存活,網址能開不等於 webhook URL 正確。任何平台都必須回答 persistent storage、managed PostgreSQL、custom domain、TLS、env vars 與 redeploy 後 state 是否保存。
Week 10 的成果是一個 production-shaped VPS blueprint:Caddy 是唯一 public 入口,n8n 與 PostgreSQL 留在 Docker network,public webhook URL 固定為 HTTPS domain,state 由 named volumes 與 PostgreSQL 承接。
11.0 本週定位
Week 11 比較 Railway、Zeabur、Render、Fly.io 在 n8n self-host 情境下能省下的維運,以及最容易踩到的持久化陷阱。驗收重點鎖定在一句話:服務能啟動不代表 n8n state 能在 redeploy 後存活。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| PaaS 平台比較表 | 完成 | artifacts/week-11-paas/week-11-paas-platform-matrix.json;本章 11.3 |
| persistent storage risk card | 完成 | artifacts/week-11-paas/week-11-persistent-storage-risk-card.json;本章 11.4 |
| 平台選型建議 | 完成 | artifacts/week-11-paas/week-11-platform-selection-recommendations.csv;本章 11.5 |
| n8n PaaS env vars 檢查表 | 完成 | 本章 11.7 |
| Week 11 驗證腳本 | 完成 | scripts/verify-week-eleven.mjs |
Week 10 把 VPS 的 DNS、firewall、Caddy、PostgreSQL、volume、env vars 攤開;Week 11 轉到 PaaS 後,平台替你省掉部分入口層維運,但 n8n 的 state layer 仍然要明確指定。
整合來源:docs/week-11-paas-persistence-platforms.md
203| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n Docker + PostgreSQL | n8n Docker installation | n8n 支援 PostgreSQL;即使用 PostgreSQL,仍建議持久化 .n8n user folder,因為其中包含 encryption keys、logs、source control assets 等資料。 |
| n8n reverse proxy webhook URL | n8n webhook URL behind proxy | reverse proxy 或 PaaS ingress 後方要設定 WEBHOOK_URL,讓 editor 與外部服務註冊正確 public webhook URL。 |
| n8n encryption key | n8n encryption key | self-host 時應固定 N8N_ENCRYPTION_KEY;credentials 依賴 encryption key 可解密。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Railway volumes | Railway volumes | Railway volume 可讓服務有持久化資料,但一個 service 只能掛一個 volume,且使用 volume 會限制 replicas。 |
| Railway PostgreSQL | Railway PostgreSQL | Railway PostgreSQL template 能快速建立 PostgreSQL service,會提供 DATABASE_URL 與 PG* 連線變數;Railway database templates 屬於平台模板,不等於完全代管資料庫營運。 |
| Railway public networking | Railway public networking | Railway 提供 Railway domain、custom domain 與自動 SSL。 |
| Railway variables | Railway variables | Railway 以 service variables、shared variables、reference variables 管理環境變數與 secrets。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Render n8n guide | Render deploy n8n | Render 有 n8n 官方部署指南;建議使用 Render Postgres 儲存 workflow data,並提醒 free web service 會 idle spin down、free Postgres 會過期。 |
| Render persistent disks | Render disks | Render service 預設 filesystem 是 ephemeral;persistent disk 只保存掛載路徑下的資料,且 disk 會取消 zero-downtime deploy。 |
| Render custom domains | Render custom domains | Render custom domain 會自動建立與更新 TLS certificates,HTTP 會 redirect 到 HTTPS。 |
| Render env vars | Render environment variables | Render 使用 dashboard 或 environment groups 管理 service env vars 與 secrets。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Zeabur volumes | Zeabur volumes | Zeabur service 預設偏 stateless;需要持久化時必須把目錄掛到 Volume;啟用 Volume 後 restart 不再是 zero-downtime。 |
| Zeabur public networking | Zeabur public networking | Zeabur 支援 *.zeabur.app domain 與 custom domain。 |
| Zeabur env vars | Zeabur variables | Zeabur 可在 service Variables tab 設定環境變數,並自動注入服務與資料庫相關變數。 |
| Zeabur templates | Zeabur templates | Zeabur templates 可一鍵部署 n8n、Postgres 等服務,並預先定義 service、env vars 與連線關係。 |
| Zeabur pricing | Zeabur pricing | Zeabur 目前採 subscription tier 加 resource usage fee;resource usage 包含 memory、network egress、persistent volume 等項目,需以最新 pricing page 為準。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Fly.io volumes | Fly.io volumes | Fly Machine root filesystem 是 ephemeral;Fly Volumes 是 local persistent storage,volume 位於單一 server/region,且不自動複製。 |
| Fly.io Managed Postgres | Fly Managed Postgres | Fly.io Managed Postgres 是 fully-managed database service,包含 HA、automatic failover、backups、monitoring、support 等能力。 |
| Fly Postgres unmanaged warning | Fly Postgres warning | 傳統 Fly Postgres 不是 managed database;production 應優先使用 Managed Postgres 或外部 managed PostgreSQL。 |
| Fly.io custom domains | Fly custom domains | Fly.io 支援 custom domain、DNS setup 與 TLS certificates。 |
| Fly.io secrets | Fly secrets | fly secrets 會把 secrets 注入 Fly App 的 Machines runtime environment。 |
| 維度 | Railway |
|---|---|
| 持久化模型 | App service filesystem 不能當 durable state;需要 volume 掛到 n8n user folder,PostgreSQL service 另有 volume。Volume 有 service-scoped、single volume、no replicas 等限制。 |
| PostgreSQL 模型 | PostgreSQL template 快速建立 service 並提供 DATABASE_URL、PGHOST、PGUSER 等變數;官方文件也提醒 database templates 屬 unmanaged service,需要自己處理 backups、monitoring、maintenance。 |
| custom domain / TLS | 支援 Railway domain、custom domain、自動 SSL。 |
| env vars / secrets | Service variables、shared variables、reference variables,可引用 Postgres service 的連線變數。 |
| usage pricing / always-on 成本 | subscription + usage;always-on n8n 會持續吃 compute、memory、volume、egress。 |
| n8n 適配判斷 | 適合 prototype、solo builder、小型 production,但要明確加 volume、Postgres、backup policy、固定 N8N_ENCRYPTION_KEY。 |
| 維度 | Zeabur |
|---|---|
| 持久化模型 | 預設服務 restart 會回到預設 state;需要把持久化目錄掛到 Volumes。啟用 Volume 後 restart 不支援 zero-downtime。 |
| PostgreSQL 模型 | templates 與 Databases 流程可建立 PostgreSQL;n8n template 很快,但仍要確認 template 是 PostgreSQL 還是 SQLite/volume 路線。 |
| custom domain / TLS | 支援 *.zeabur.app、custom domain 與 public networking;custom domain 需照 dashboard DNS 設定。 |
| env vars / secrets | Service Variables tab 設定,平台會注入 service host、port 與資料庫相關變數。 |
| usage pricing / always-on 成本 | subscription tier + resource usage fee;memory、network egress、persistent volume 會累積費用;suspend 可停 compute,但 volume 仍需檢查保留與費用。 |
| n8n 適配判斷 | 最 beginner-friendly 的 PaaS 候選之一,尤其適合 template deployment;風險在於把「模板成功啟動」誤當成「state model 已驗證」。 |
| 維度 | Render |
|---|---|
| 持久化模型 | 預設 filesystem 是 ephemeral。可選 Render Postgres 儲存 workflow data,或 paid persistent disk 儲存 SQLite/n8n local files;disk 只保存 mount path。 |
| PostgreSQL 模型 | Render 官方 n8n guide 推薦 Render Postgres;free Postgres 會過期,production 需 paid DB。 |
| custom domain / TLS | 支援 custom domain、自動 TLS、HTTP redirect HTTPS。 |
| env vars / secrets | Environment variables、secrets、environment groups;Blueprint 可一起定義 service 與 DB。 |
| usage pricing / always-on 成本 | free web service idle 會 spin down,free Postgres 30 天過期;paid always-on 才適合 production。 |
| n8n 適配判斷 | 最適合用「Render Postgres + n8n web service」當 low-maintenance PaaS 路線;不要用 free DB 做長期 state。 |
| 維度 | Fly.io |
|---|---|
| 持久化模型 | Machine root filesystem 是 ephemeral。Fly Volumes 是 local persistent storage,單一 volume 綁單一 Machine/server/region,不自動複製。 |
| PostgreSQL 模型 | 可用 Fly.io Managed Postgres;傳統 Fly Postgres 是 unmanaged,不適合沒有 DB ops 能力的 production。 |
| custom domain / TLS | 支援 .fly.dev 與 custom domain,透過 Fly Proxy 管理 TLS。 |
| env vars / secrets | fly secrets 注入 runtime env;fly.toml 管理 app config。 |
| usage pricing / always-on 成本 | 按 Machines、volumes、egress、Managed Postgres 計費;長期 always-on 和 Managed Postgres 會比簡單 VPS 更需要成本估算。 |
| n8n 適配判斷 | 適合有工程能力、需要 global edge / Machines 控制的人;對 beginner 不是最低風險路線。 |
| 維運項 | PaaS 通常會省下 | 仍需自己確認 |
|---|---|---|
| Public ingress | 不用自己裝 Caddy/Nginx;平台提供 domain、routing、TLS。 | WEBHOOK_URL 是否是 public HTTPS URL;proxy headers 是否正確。 |
| Build/deploy | Git push、Docker image 或 template deploy 可自動化。 | image tag 是否 pin;更新後 workflows 是否回歸測試。 |
| Secrets UI | Dashboard 管理 env vars。 | N8N_ENCRYPTION_KEY、DB password、OAuth secrets 是否可備份與輪替。 |
| Database creation | 多數平台有 PostgreSQL template 或 managed DB。 | 是 managed DB 還是 unmanaged template;backup/restore/RPO/RTO 誰負責。 |
| Monitoring basics | Logs、metrics、restart controls 較容易。 | n8n execution backlog、DB storage growth、workflow failure alerts 仍要設計。 |
| 責任 | 為什麼重要 |
|---|---|
| n8n state 分層 | workflows、credentials、executions 多在 DB;encryption key 與部分 user folder assets 仍不可忽略。 |
| Redeploy persistence | container image 更新常會建立新 instance;沒有 persistent DB/volume 時,啟動成功只是新空白實例成功。 |
| Backup / restore | volume 存在不等於有可用備份;DB snapshot 也要演練 restore。 |
| Public URL stability | webhook、OAuth callback、AI tool callback 都依賴 stable HTTPS domain。 |
| 成本上限 | subscription + usage 或 usage-based 平台容易因 always-on、memory、volume、egress、DB plan 而超過預期。 |
| Risk ID | 風險卡 | 典型症狀 | 影響 | 第一個檢查 | 降低風險做法 |
|---|---|---|---|---|---|
ephemeral-filesystem | 把 n8n state 寫在 ephemeral filesystem | redeploy 後 workflow/credential/execution 不見,或回到 setup 畫面 | 高 | 平台是否明說 filesystem ephemeral;n8n user folder 是否有 volume | 使用 PostgreSQL 儲存主要 state,並為 /home/node/.n8n 或平台等價 user folder 掛 durable storage 或固定 key/env。 |
managed-db-without-app-volume | 有 DB 但忽略 n8n user folder | workflow 還在,但 encryption key、binary data、source-control assets、logs 或本機檔案相關功能異常 | 高 | 是否固定 N8N_ENCRYPTION_KEY;是否保存 .n8n user folder | 固定 N8N_ENCRYPTION_KEY,掛載 user folder,檢查 binary data mode。 |
app-volume-without-db-backup | 只掛 volume,沒有 DB backup | redeploy 沒事,但 DB 壞掉或誤刪後無法還原 | 高 | 有沒有 Postgres backup/snapshot/restore drill | 設定 managed Postgres backup 或外部備份,建立 restore runbook。 |
| Risk ID | 風險卡 | 典型症狀 | 影響 | 第一個檢查 | 降低風險做法 |
|---|---|---|---|---|---|
free-or-sleeping-service | 使用 free tier 跑 production webhook | webhook 延遲、timeout、DB 到期、service idle spin down | 高 | plan 是否會 sleep;free DB 是否會 expire | production 使用 paid always-on web service 與 paid DB。 |
single-region-local-volume | 把 volume 視為跨區 durable storage | region/host 問題時 service 或資料不可用 | 中到高 | volume 是否 local to single host/region;是否自動 replication | 對 production 使用 managed DB 或多副本策略;設計 off-platform backup。 |
redeploy-reset | 只驗證初次啟動,沒有驗證 redeploy | 第一次能登入,下一次 deploy 後資料消失 | 高 | 手動觸發 redeploy 後 workflows/credentials 是否仍在 | 建立 smoke test:新增 workflow、credential mock、redeploy、確認仍存在。 |
| Risk ID | 風險卡 | 典型症狀 | 影響 | 第一個檢查 | 降低風險做法 |
|---|---|---|---|---|---|
custom-domain-mismatch | URL 能開但 n8n webhook base URL 不對 | webhook node 顯示平台臨時 URL、localhost、http 或舊 domain | 中到高 | WEBHOOK_URL、N8N_EDITOR_BASE_URL、domain/TLS | 固定 custom domain,設定 public HTTPS URL,更新 OAuth callback。 |
secret-loss-or-rotation | secrets 沒有備份或亂輪替 | credentials 解不開,OAuth token 失效 | 高 | N8N_ENCRYPTION_KEY 是否固定且存在 secret manager | secrets 變更前備份 DB,記錄 rotation plan。 |
binary-data-location | binary data 寫到不持久的路徑 | 檔案節點、附件、AI document processing 重跑或下載失敗 | 中 | workflow 是否產生 binary files;binary data mode 與 storage path | 把 binary data path 放在 durable volume;Enterprise 可評估 external storage。 |
execution-history-growth | execution history 長期膨脹 | Postgres storage 增長、備份變慢、費用上升 | 中 | executions retention、DB storage trend | 設定 execution pruning、監控 DB size、定期驗證備份大小。 |
把「平台會幫我 deploy container」理解成「平台會理解 n8n 的 state model」。PaaS 只知道 container、port、env、disk、DB,它不知道哪些 workflows 是生意流程、哪些 credentials 不能失效、哪些 binary files 是客戶資料。
| 情境 | 首選 | 次選 | 不建議 | 理由 |
|---|---|---|---|---|
| beginner / 非工程團隊 | n8n Cloud | Render Postgres blueprint | Fly.io unmanaged Postgres | 最低維運是 Cloud;如果要 PaaS,選有明確 n8n guide 與 Postgres blueprint 的路線。 |
| solo creator 想快速公開 webhook | Railway 或 Zeabur | Render paid service + Postgres | free tier 長期 production | Railway/Zeabur 上手快,但要檢查 volume、Postgres、custom domain、WEBHOOK_URL。 |
| 需要低維運又要官方 n8n PaaS guide | Render Postgres | Railway + Postgres | SQLite on ephemeral FS | Render 有 n8n guide,且文件直接區分 Postgres 與 persistent disk 儲存方法。 |
| 有工程能力、想靠近 global edge | Fly.io + Managed Postgres | Railway | Fly Postgres unmanaged without backup | Fly 強在 Machines/networking,但 DB 與 local volumes 要更懂操作。 |
| 情境 | 首選 | 次選 | 不建議 | 理由 |
|---|---|---|---|---|
| 需要 template 一鍵啟動 | Zeabur n8n template,並確認 PostgreSQL/volume | Railway template | 不明 template state model | template 可省 setup,但 template 內容要核對,不可只看 deploy 成功。 |
| 長期 production with low ops | n8n Cloud 或 managed DB PaaS | VPS + Compose + Caddy | free/sleeping PaaS | production 需要 always-on、backup、restore、stable domain、monitoring。 |
| 想學真實 self-host ops | Week 10 VPS route | Fly.io advanced route | 只用 PaaS dashboard 但不懂 state | VPS 能完整理解 DNS、proxy、DB、volume;PaaS 可作為下一層抽象比較。 |
| 結論 | 建議 |
|---|---|
| 最低維運 | n8n Cloud。若必須 self-host,Render Postgres 是文件最清楚的低維運 PaaS 起點。 |
| 最快 PaaS 上手 | Zeabur 或 Railway,但必須完成 redeploy persistence test。 |
| 最佳學習深度 | VPS + Compose + Caddy,因為每個 layer 都看得見。 |
| 最適合工程玩家 | Fly.io + Managed Postgres,適合願意處理 Machines、volumes、regions、secrets 的人。 |
| 最應避免 | SQLite 或 user folder 寫在 ephemeral filesystem,尤其又搭配 free/sleeping service。 |
| Layer | 應設定 | 檢查重點 |
|---|---|---|
| n8n container | Docker image 或 repo deploy | pin image tag,不要長期漂在 untracked latest。 |
| DB | Railway PostgreSQL service 或外部 managed Postgres | 確認 DB_TYPE=postgresdb、DB_POSTGRESDB_* 或 DATABASE_URL 對應方式,並建立 backup strategy。 |
| User folder | Railway volume mount 到 n8n user folder | Railway 一個 service 只能掛一個 volume,replicas 不能與 volume 一起用。 |
| Secrets | Railway service variables | 固定 N8N_ENCRYPTION_KEY,用 reference variables 接 DB credentials。 |
| Domain | Railway custom domain + automatic SSL | 設 WEBHOOK_URL=https://你的網域/。 |
Railway 的優點是速度快、UI 清楚、Postgres template 方便;主要風險是把 template database 當成完全免責任 managed database。
| Layer | 應設定 | 檢查重點 |
|---|---|---|
| n8n container/template | 選 n8n template 或 Docker image | 確認 template 使用 PostgreSQL 還是 SQLite 路線。 |
| DB | Databases / PostgreSQL template | 確認 service variables 自動注入後,n8n 真的連到 Postgres。 |
| User folder | Zeabur Volume | Zeabur 文件明說 service 預設 restart 後會 reset data;需要持久化就掛 Volume。 |
| Secrets | Service Variables | 固定 N8N_ENCRYPTION_KEY,不要只依賴一次性生成。 |
| Domain | *.zeabur.app 或 custom domain | production 用 stable custom domain,並同步 WEBHOOK_URL。 |
Zeabur 的優點是 template-centric,上手很快;主要風險是「一鍵部署」讓人以為檢查結束。template 啟動後仍要做 redeploy persistence test。
| Layer | 應設定 | 檢查重點 |
|---|---|---|
| n8n web service | official n8n Docker image | 使用 Render n8n guide 或 Blueprint,pin n8n image tag。 |
| DB | Render Postgres | Render guide 推薦 Postgres 儲存 workflow data;free DB 會過期,production 要 paid。 |
| User folder | 依部署模式決定 | Postgres 保存 workflows/credentials/executions;仍需固定 N8N_ENCRYPTION_KEY,若使用 filesystem/binary data 要掛 disk。 |
| Persistent disk | 若用 SQLite 或需要 local files | Render disk only preserves mount path,且 disables zero-downtime deploy。 |
| Domain | custom domain + TLS | 設定 WEBHOOK_URL 為 https://你的網域/ 或 service public URL。 |
Render 是四個平台中對 n8n 文件最直白的一個:它直接告訴使用者 storage method 有 Render Postgres 和 persistent disk 兩種,也直接說 free service/DB 的限制。
| Layer | 應設定 | 檢查重點 |
|---|---|---|
| n8n Machine | Docker image + fly.toml | root filesystem ephemeral,不可放 durable state。 |
| DB | Fly.io Managed Postgres 或外部 managed Postgres | 傳統 Fly Postgres 是 unmanaged;沒有 DB ops 能力不要作為 production 預設。 |
| User folder | Fly Volume | volume local to single server/region,一個 volume attach one Machine,不自動 replication。 |
| Secrets | fly secrets | secrets 更新會使 Machine 更新或重啟,要回歸 credential 解密。 |
| Domain | .fly.dev 或 custom domain | fly certs add,DNS 與 TLS 檢查完成後設定 WEBHOOK_URL。 |
Fly.io 的價值是控制力與全球網路,而不是 beginner 省心。n8n 可以跑在 Fly,但 production 應使用 Managed Postgres 或外部 managed DB。
| env var | 必要性 | 建議值或來源 | 為什麼重要 |
|---|---|---|---|
DB_TYPE | PostgreSQL route 必填 | postgresdb | 避免 n8n 使用預設 SQLite 寫到 ephemeral filesystem。 |
DB_POSTGRESDB_HOST | PostgreSQL route 必填 | 平台 DB host 或 private hostname | 連到 durable DB,不連到 container local DB。 |
DB_POSTGRESDB_PORT | PostgreSQL route 必填 | 通常 5432 | 明確連線到 PostgreSQL。 |
DB_POSTGRESDB_DATABASE | PostgreSQL route 必填 | n8n 或平台建立的 database | workflows、credentials、executions 的主要 state。 |
DB_POSTGRESDB_USER | PostgreSQL route 必填 | 平台 DB user | DB auth。 |
DB_POSTGRESDB_PASSWORD | PostgreSQL route 必填 | platform secret/reference variable | DB auth secret 不進 Git。 |
| env var | 必要性 | 建議值或來源 | 為什麼重要 |
|---|---|---|---|
DB_POSTGRESDB_SSL_ENABLED 或平台等價設定 | 視平台而定 | managed DB 若要求 TLS 則開啟 | 外部 DB 連線常需要 TLS。 |
N8N_ENCRYPTION_KEY | production 必填 | 固定、長度足夠、保存在 secret manager | credentials 解密依賴它;遺失會造成嚴重事故。 |
WEBHOOK_URL | public webhook 必填 | https://n8n.example.com/ | 外部服務註冊與 editor 顯示 production webhook URL。 |
N8N_EDITOR_BASE_URL | 建議設定 | https://n8n.example.com/ | editor redirect 與 public base URL 一致。 |
N8N_HOST | 建議設定 | n8n.example.com | public hostname。 |
| env var | 必要性 | 建議值或來源 | 為什麼重要 |
|---|---|---|---|
N8N_PROTOCOL | 建議設定 | https | public side protocol。 |
N8N_PROXY_HOPS | reverse proxy/PaaS ingress 建議 | 1 或依 ingress hops 調整 | 告訴 n8n 信任前方 proxy headers。 |
N8N_SECURE_COOKIE | HTTPS production 建議 | true | 強化 cookie 安全。 |
N8N_RUNNERS_ENABLED | 新版 self-host 建議 | true | 對應 n8n Docker 文件中的 runner 建議。 |
EXECUTIONS_DATA_PRUNE 與相關 retention vars | 長期 production 建議 | 依資料保留政策設定 | 控制 execution history 成長與 DB 成本。 |
PaaS 的成功啟動通常只證明五件事:image 能拉下來、port 有 listen、health check 通過、env vars 基本可讀、平台 ingress 能連到服務。這些都不等於 n8n 的 state layer 被保存。
| 啟動成功代表 | 不代表 |
|---|---|
| container process 活著 | DB 是 durable,且有 backup。 |
| editor 可開 | workflows、credentials、executions 已寫到 persistent PostgreSQL。 |
| 可以建立帳號 | 下一次 redeploy 不會回到空白 setup。 |
| webhook URL 能顯示 | URL 是 stable custom domain,而不是暫時平台 domain 或 localhost。 |
| service restart 正常 | volume mount path 正確,binary data 和 encryption key 都能保留。 |
| 步驟 | 動作 | 通過條件 |
|---|---|---|
| 1 | 部署 n8n service + PostgreSQL + volume/secret | n8n editor 可開,DB env vars 生效。 |
| 2 | 設定 N8N_ENCRYPTION_KEY、WEBHOOK_URL、N8N_EDITOR_BASE_URL | editor 顯示 public HTTPS URL。 |
| 3 | 建立測試 workflow 與測試 credential | workflow、credential 能儲存。 |
| 4 | 觸發一次 production webhook | 外部 request 成功打到 n8n。 |
| 5 | 手動 redeploy 或 restart service | redeploy 完成後不是空白 instance。 |
| 6 | 重新登入檢查 workflow、credential、execution | workflow 還在,credential 可用,execution history 符合保留政策。 |
| 7 | 檢查 DB backup 與 volume backup | 至少有明確可操作的 restore path。 |
服務能啟動只代表 runtime 起來了,不代表 n8n state 能在 redeploy 後存活。n8n 的持久化要同時檢查 PostgreSQL、user folder volume、N8N_ENCRYPTION_KEY、binary data storage、backup/restore、stable public URL。
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 PaaS 平台比較表 | 通過 | week-11-paas-platform-matrix.json 與第 3 節 |
| 完成 persistent storage risk card | 通過 | week-11-persistent-storage-risk-card.json 與第 4 節 |
| 完成平台選型建議 | 通過 | week-11-platform-selection-recommendations.csv 與第 5 節 |
| 檢查 persistent volume、managed PostgreSQL、custom domain、TLS、env vars | 通過 | 第 2、3、6、7 節 |
| 辨認 Render/Fly/Zeabur/Railway 狀態保存模型 | 通過 | 第 6 節 |
| 理解 usage pricing 與 always-on 成本 | 通過 | 第 3、5 節 |
| 能說明服務能啟動不代表 state 能在 redeploy 後存活 | 通過 | 第 8 節 |
Week 12 會進入 Cloud Run、AWS App Runner、Lightsail、EC2、RDS 的比較。Week 11 的判斷會繼續沿用:任何平台選型都先問 state layer。Cloud Run 與 App Runner 更偏 stateless service,Lightsail/EC2 更像 VPS,RDS 則是 managed PostgreSQL 的典型選項。
Week 11 的成果,是把「PaaS 比 VPS 省事」拆成可驗證的判斷:入口層可能省事,但 state、secret、volume、DB backup、public URL、成本與 redeploy persistence 仍要逐一驗收。
12.0 本週定位
Week 12 判斷何時值得使用 hyperscaler,而不是普通 VPS 或 PaaS。實作結果是完成 Cloud Run durable 架構圖、AWS 三階段演進圖、hyperscaler adoption checklist,並把驗收重點鎖定在「AWS 的強大來自 building blocks,也帶來組裝與維運成本」。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| Cloud Run durable 架構圖 | 完成 | artifacts/week-12-hyperscaler/week-12-cloud-run-durable-architecture.json;本章 12.3 |
| AWS 三階段演進圖 | 完成 | artifacts/week-12-hyperscaler/week-12-aws-three-stage-evolution.json;本章 12.4 |
| hyperscaler adoption checklist | 完成 | artifacts/week-12-hyperscaler/week-12-hyperscaler-adoption-checklist.csv;本章 12.5 |
| Cloud Run easy mode vs durable mode 判斷 | 完成 | 本章 12.3 |
| AWS Lightsail/EC2/ECS/RDS/Secrets Manager/ALB/CloudWatch 階梯 | 完成 | 本章 12.4 |
| Week 12 驗證腳本 | 完成 | scripts/verify-week-twelve.mjs |
Week 11 說明 PaaS 能省下 ingress、TLS、deploy UI、logs、secrets UI,但 state layer 仍要明確設計。Week 12 往 hyperscaler 推進,判斷標準不是「GCP/AWS 比較大所以一定比較好」,而是你是否真的需要 managed database、IAM、secret manager、load balancer、observability、autoscaling、VPC controls、backup/restore 與 multi-environment governance。
整合來源:docs/week-12-cloud-run-aws-hyperscaler.md
234| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n on Google Cloud Run | n8n Cloud Run guide | n8n 官方 Cloud Run guide 區分 Easy mode 與 Durable mode;Durable mode 加入 Cloud SQL、Secret Manager、service account 與正確 env vars。 |
| Cloud Run to Cloud SQL PostgreSQL | Cloud Run connect to Cloud SQL | Cloud SQL 是 fully-managed database;Cloud Run 連 Cloud SQL 需要設定 instance connection,建議同區以降低 latency、成本與跨區故障風險。 |
| Cloud Run Secret Manager | Cloud Run secrets | Cloud Run 可把 Secret Manager secrets 掛成檔案或注入為環境變數;服務身分需要 roles/secretmanager.secretAccessor。 |
| Cloud Run service identity | Cloud Run service identity | Cloud Run service identity 是 container 存取 Google Cloud API 的 service account;應使用 least-privilege user-managed service account。 |
| Cloud Run environment variables | Cloud Run environment variables | Cloud Run env vars 綁定到 service revision;敏感值不應直接放普通環境變數,應使用 Secret Manager。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Lightsail containers | Lightsail container services | Lightsail container services 提供 container、default domain、custom domain、logs、metrics,比 ECS/Fargate 更像簡化的 AWS 入口。 |
| Lightsail custom domains | Lightsail custom domains | Lightsail container service 可啟用 custom domains,需建立並驗證 SSL/TLS certificate。 |
| EC2 security groups | EC2 security groups | EC2 security group 是 instance 的 virtual firewall;入站與出站 rules 仍由使用者設計。 |
| ECS Fargate tasks | ECS Fargate tasks | Fargate task 使用 awsvpc network mode,並有 task definition、CPU/memory/network/logging/storage 限制。 |
| RDS automated backups | RDS automated backups | RDS 自動備份依 backup window 與 retention policy 執行;production 需要明確 retention、restore、maintenance window。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| AWS Secrets Manager | AWS Secrets Manager | Secrets Manager 用於加密、儲存、取回 database credentials 與其他 secrets,並支援 rotation。 |
| ALB target groups | ALB target groups | Application Load Balancer 透過 target groups 將 request route 到 registered targets,並用 health checks 判斷 target 狀態。 |
| ECS logs to CloudWatch | ECS awslogs | ECS/Fargate tasks 可透過 awslogs log driver 將 container logs 發送到 CloudWatch Logs。 |
| CloudWatch Container Insights | CloudWatch Container Insights | Container Insights 可收集、彙總 containerized applications 的 metrics/logs,支援 ECS/EKS/Fargate。 |
Cloud Run durable 與 AWS Stage 2/3 都把 n8n 拆成多個 building blocks。這會提升治理能力,也會增加 IAM、網路、備份、監控、成本與 release runbook 的責任。
| 模式 | 適用 | state model | 主要資源 | 最大風險 |
|---|---|---|---|---|
| Easy mode | demo、短期試跑、教學展示 | 容器內暫存或非 durable state | Cloud Run service + n8n image | scale to zero、redeploy、revision replacement 後資料不可靠。 |
| Durable mode | production-oriented self-host | Cloud SQL PostgreSQL 保存主要 state;Secret Manager 保存 secrets;service account 控制權限 | Cloud Run、Cloud SQL、Secret Manager、service account、env vars、public URL | 組件設定較多;如果 DB backup、IAM、secrets、public URL 沒設好,仍會 production 事故。 |
editor、webhook、API request。
workflows、credentials、executions。
DB password、N8N_ENCRYPTION_KEY。
cloudsql.client + secretAccessor。
WEBHOOK_URL、N8N_EDITOR_BASE_URL。
| Component | 目的 | n8n 對應設定 |
|---|---|---|
| Cloud Run service | 執行 n8n container,處理 editor、webhook、API request | n8n image、port 5678、CPU/memory/concurrency/min instances 依 workload 設定。 |
| Cloud SQL PostgreSQL | 保存 workflows、credentials、executions 等主要 state | DB_TYPE=postgresdb、DB_POSTGRESDB_HOST=/cloudsql/PROJECT:REGION:n8n-db、DB_POSTGRESDB_DATABASE=n8n。 |
| Secret Manager | 保存 DB password、N8N_ENCRYPTION_KEY 與 OAuth/API secrets | Cloud Run --update-secrets 或 revision secret references。 |
| Service account | Cloud Run runtime identity,以最小權限存取 Cloud SQL 與 secrets | roles/cloudsql.client、roles/secretmanager.secretAccessor,不要把 broad Editor role 當預設做法。 |
| Component | 目的 | n8n 對應設定 |
|---|---|---|
| Public URL | 讓 webhook/OAuth callback 對外穩定 | WEBHOOK_URL=https://n8n.example.com/、N8N_EDITOR_BASE_URL=https://n8n.example.com/。 |
| Health endpoint | 避免 Cloud Run reserved path 衝突 | n8n guide 提到 Cloud Run 保留 /healthz,應改 N8N_ENDPOINT_HEALTH。 |
| Cloud Logging/Monitoring | 觀察 revision、errors、latency、request count、container logs | 建立 dashboard、alerts、error budget 與 incident playbook。 |
| env var | Cloud Run durable 建議 | 說明 |
|---|---|---|
DB_TYPE | postgresdb | 強制 n8n 使用 PostgreSQL,不把主 state 放在 container filesystem。 |
DB_POSTGRESDB_HOST | /cloudsql/PROJECT:REGION:n8n-db | Cloud SQL Unix socket route;具體 connection name 依專案而定。 |
DB_POSTGRESDB_DATABASE | n8n | n8n database name。 |
DB_POSTGRESDB_USER | n8n-user | Cloud SQL DB user。 |
DB_POSTGRESDB_PASSWORD | Secret Manager reference | 不放普通 env var,不寫入 image。 |
| env var | Cloud Run durable 建議 | 說明 |
|---|---|---|
N8N_ENCRYPTION_KEY | Secret Manager reference | credentials 解密與敏感資料保護的核心 key。 |
WEBHOOK_URL | https://n8n.example.com/ | production webhook base URL。 |
N8N_EDITOR_BASE_URL | https://n8n.example.com/ | editor public base URL。 |
N8N_ENDPOINT_HEALTH | health 或其他非 /healthz path | 避免 Cloud Run reserved path 衝突。 |
N8N_PROXY_HOPS | 1 或依實際 proxy hops 調整 | Cloud Run/外部 proxy 後方要讓 n8n 正確理解 forwarded headers。 |
| 驗收項 | 通過條件 |
|---|---|
| Cloud SQL | n8n 實際連到 Cloud SQL PostgreSQL;redeploy 後 workflows/credentials/executions 不消失。 |
| Secret Manager | DB password 與 N8N_ENCRYPTION_KEY 由 Secret Manager 注入,service account 有最小必要權限。 |
| Service account | Cloud Run runtime 使用專用 service account,不依賴 broad default identity。 |
| URL | webhook node 顯示 stable HTTPS public URL,不是 localhost 或臨時 URL。 |
| Health | Cloud Run health check 不使用 /healthz 與 n8n reserved/conflicting route。 |
| Backup | Cloud SQL production 設定 backup retention、restore drill、maintenance window。 |
n8n 官方 Durable mode guide 的範例偏向教學起點。真正 production 應補上 automated backups、restore drill、region choice、connection limits、cost alert、Cloud Logging alert、image pinning 與 release rollback。
Docker Compose / local Postgres / simple domain。
Managed DB、separated secrets、load balancer、logs。
Task definitions、services、target groups、autoscaling。
| Stage | 適用情境 | AWS building blocks | 優點 | 組裝與維運成本 |
|---|---|---|---|---|
| Stage 1:Lightsail 或 EC2 single-server | 想要 AWS 帳號內的 VPS-like 起點;流量小;團隊仍在學 self-host | Lightsail instance/container service,或 EC2 + security group + EBS + Docker Compose + domain/TLS | Mental model 接近 Week 10 VPS,成本與架構較容易理解。 | 仍要自己管理 OS patch、Docker update、firewall/security group、backup、Caddy/TLS 或 Lightsail certificate。 |
| Stage 2:EC2 + RDS + Secrets Manager + ALB + CloudWatch | n8n 已承載重要流程,需要 managed DB、分離 secrets、健康檢查、集中 logs | EC2、RDS PostgreSQL、Secrets Manager、Application Load Balancer、target groups、CloudWatch Logs/Metrics | DB、secrets、ingress、monitoring 開始拆成專門元件,資料層比單機更可靠。 | VPC/subnet/security group/IAM/ALB/target group/RDS/backup/logs 都要設計,費用項目變多。 |
| Stage 3:ECS/Fargate + RDS + Secrets Manager + ALB + CloudWatch | 需要 container orchestration、rolling deploy、scaling、task isolation、multi-environment pipeline | ECS cluster/service/task definition、Fargate、ECR、RDS、Secrets Manager、ALB target groups、CloudWatch Logs、Container Insights | 不再手管 EC2 host;部署、擴縮、observability 與 IAM boundary 更雲原生。 | task definition、IAM execution role/task role、network mode、log driver、autoscaling、DB connection limits、deployment rollback 都要成熟管理。 |
| 從 | 移到 | 當這些訊號出現 |
|---|---|---|
| Lightsail/EC2 single-server | EC2 + RDS + Secrets Manager | SQLite 或 local Postgres 已不夠;需要 automated backups、DB restore、secret rotation、集中 logs。 |
| EC2 + RDS | EC2 + ALB + CloudWatch | 需要健康檢查、TLS termination、domain routing、instance replacement、incident metrics。 |
| EC2 + ALB + RDS | ECS/Fargate + RDS | deploy 頻率上升;需要 immutable task revisions、service autoscaling、container-level logs、清楚分離 execution role/task role。 |
| ECS/Fargate single service | ECS queue-mode architecture | workflow execution concurrency、webhook burst、worker separation、Redis queue mode 變成瓶頸議題。 |
| 情境 | 比較合理的路線 |
|---|---|
| 只有個人自動化、低流量 webhook、沒有合規要求 | n8n Cloud、VPS + Compose、Render Postgres、Railway/Zeabur verified template。 |
| 團隊還不能解釋 security group、IAM role、target group、RDS backup | 先做 Week 10 VPS 或 Week 11 PaaS,再進 AWS。 |
| 只是想要 custom domain + HTTPS | VPS+Caddy 或 PaaS 已足夠。 |
| 沒有人會看 CloudWatch alerts 或操作 restore | managed building blocks 只會變成未維護的帳單項目。 |
| 類別 | 採用前問題 | 通過訊號 | 未通過時建議 |
|---|---|---|---|
| Durable state | workflows、credentials、executions 是否需要 managed PostgreSQL 與 restore drill? | 已定義 RPO/RTO、backup retention、restore owner。 | 留在 VPS/PaaS,先完成 Postgres backup/restore。 |
| Secrets | N8N_ENCRYPTION_KEY、DB password、OAuth secrets 是否需要 secret manager 與 rotation? | Secret Manager/Secrets Manager 權限和 rotation plan 已明確。 | 先用平台 secrets 或 password manager,避免把 AWS/GCP 當保險箱但沒設 IAM。 |
| IAM/service account | 是否能清楚分辨 deployer identity、runtime service account、task role? | least privilege role 已列出,沒有 broad admin runtime identity。 | 先不要進 Stage 3,否則 debug 權限會吃掉大量時間。 |
| Ingress | 是否需要 ALB/Cloud Run custom domain、health check、TLS、target group routing? | health path、TLS、domain、webhook URL 都可驗證。 | 若只需一個 domain,Caddy/PaaS 即可。 |
| Observability | 是否有人會維護 CloudWatch/Cloud Logging dashboards 與 alerts? | 有 alert threshold、on-call owner、log retention policy。 | 不要只打開 logs,要先定義誰會看。 |
| 類別 | 採用前問題 | 通過訊號 | 未通過時建議 |
|---|---|---|---|
| Scaling | 是否真的需要 autoscaling、multiple tasks、worker separation? | 有 execution volume、concurrency、webhook burst 證據。 | 單機或 PaaS paid plan 可能更穩。 |
| Cost guardrails | 是否能估算 compute、DB、load balancer、egress、logs、secret、backup 成本? | 有 monthly estimate、budget alert、tagging policy。 | 先不要用多 building blocks,避免小系統變複雜帳單。 |
| Operations | 是否有 patch、upgrade、rollback、backup、restore、incident runbook? | runbook 可演練,不只是架構圖。 | 先完成 Week 10/11 的基本 runbook。 |
| Compliance | 是否有 audit logs、IAM boundary、private networking、data residency 需求? | 需求明確且普通 VPS/PaaS 無法合理滿足。 | 無合規需求時,不要為了品牌感進 hyperscaler。 |
| Team skill | 團隊是否能 debug VPC、security group、IAM、target group、DB connection limits? | 至少一人能操作,一人能 review。 | 選 n8n Cloud 或低維運 PaaS。 |
| 結果 | 判斷 |
|---|---|
| 多數需求是「穩定 URL、Postgres、HTTPS、便宜」 | 不需要 hyperscaler;VPS、PaaS 或 n8n Cloud 更合理。 |
| 需求包含 IAM、managed DB、central logs、autoscaling、private network、audit、multi-env | 可以進 Cloud Run durable 或 AWS Stage 2。 |
| 需求包含 container orchestration、rolling deploy、task isolation、worker autoscaling | 可以評估 AWS Stage 3 ECS/Fargate。 |
| 團隊不會維護 alerts、backup、IAM、cost | 暫停 hyperscaler adoption;先補操作能力。 |
| 路線 | 適合誰 | 最小合理組合 | 主要限制 |
|---|---|---|---|
| Cloud Run durable | 想用 GCP managed serverless container,但願意接受 stateless runtime + external state | Cloud Run + Cloud SQL PostgreSQL + Secret Manager + service account + Cloud Logging | 本機 filesystem 不應當主要 state;DB connection limits、cold start、revision/env var 管理要理解。 |
| AWS Stage 1 | 想留在 AWS,但仍要 VPS-like mental model | Lightsail container service 或 EC2 + Docker Compose + domain/TLS + backup | AWS building blocks 用得少,省心有限;仍有 server patch 與單點問題。 |
| AWS Stage 2 | 需要 managed DB/secrets/ingress/observability,但還不需要 ECS | EC2 + RDS + Secrets Manager + ALB + CloudWatch | 組裝元件多,IAM/security group/VPC/ALB/RDS 都要設計。 |
| AWS Stage 3 | 需要 container orchestration 與 production pipeline | ECS/Fargate + RDS + Secrets Manager + ALB + CloudWatch Container Insights | 學習曲線與營運成本最高;DB connection pooling、task sizing、log costs 不能忽略。 |
| 成本類型 | Cloud Run durable | AWS Stage 2/3 |
|---|---|---|
| Compute | Cloud Run request/instance configuration 與 min instances 影響成本。 | EC2/Fargate 持續任務、service desired count、CPU/memory 直接影響成本。 |
| Database | Cloud SQL tier、storage、backup、region 設定。 | RDS instance class、storage、backup retention、Multi-AZ、I/O。 |
| Secrets | Secret Manager secret versions/access。 | Secrets Manager secret count、API calls、rotation Lambda 或 managed rotation。 |
| Ingress | Cloud Run domain/load balancing/network egress 規則。 | ALB hourly/LCU、Route 53、ACM、egress。 |
| Logs | Cloud Logging retention 與 ingest volume。 | CloudWatch Logs ingest/storage、Container Insights metrics。 |
| People | GCP IAM、Cloud SQL、Cloud Run revision 操作能力。 | VPC/IAM/security groups/ALB/ECS/RDS/CloudWatch 操作能力。 |
真正貴的通常不是單一 VM,而是「很多小 building blocks 每個都啟用一點點,再加上沒有人負責檢查」。hyperscaler 的價值要靠治理回收:標籤、budget alert、log retention、backup retention、least privilege、runbook、release rollback。
AWS 的強大來自 building blocks:你可以把 compute、networking、database、secrets、load balancing、logs、metrics、IAM、backup、container orchestration 拆成專門服務,再依需求組合。這種拆分讓 production 架構能逐步升級:從 Lightsail/EC2 single-server,到 EC2 + RDS + Secrets Manager + ALB + CloudWatch,再到 ECS/Fargate + RDS + ALB + Container Insights。
但這也帶來組裝與維運成本。每多一個 building block,就多一組 IAM 權限、網路邊界、健康檢查、計費項目、告警規則、備份策略、故障模式與文件責任。普通 VPS 或 PaaS 的價值是把很多選項收起來;hyperscaler 的價值是把每個選項交還給你。
只有當你的可靠性、安全性、合規、擴展或治理需求真的需要這些選項時,進 AWS/GCP 才是升級,不是繞遠路。
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 Cloud Run durable 架構圖 | 通過 | 第 3 節與 week-12-cloud-run-durable-architecture.json |
| 完成 AWS 三階段演進圖 | 通過 | 第 4 節與 week-12-aws-three-stage-evolution.json |
| 完成 hyperscaler adoption checklist | 通過 | 第 5 節與 week-12-hyperscaler-adoption-checklist.csv |
| 說明 Cloud Run easy mode vs durable mode | 通過 | 第 3 節 |
| 說明 Cloud SQL、Secret Manager、service account | 通過 | 第 2、3 節 |
| 說明 AWS Lightsail/EC2/ECS/RDS/Secrets Manager/ALB/CloudWatch 階梯 | 通過 | 第 4、6 節 |
| 說明何時用簡單平台,何時值得進 AWS/GCP | 通過 | 第 5、6、8 節 |
| 說明 AWS building blocks 與組裝維運成本 | 通過 | 第 8 節 |
Week 13 會進入資料庫、binary data 與容量規劃。Week 12 已經把 Cloud SQL/RDS 放進 durable state layer,下一週要更細地回答:PostgreSQL 應該怎麼備份、execution history 如何影響容量、binary data 應該放 DB、filesystem 還是 external storage,以及什麼時候需要 Redis queue mode 與 workers。
Week 12 的成果,是把 hyperscaler 從「比較大的雲」拆成可驗收的 building blocks。只有 state、secrets、IAM、ingress、observability、scaling、cost、operations、compliance 與 team skill 都有答案,Cloud Run durable 或 AWS Stage 2/3 才是升級。
13.0 本週定位
Week 13 回答如何為不同負載選擇初始規格,並避免 binary-heavy workflow 拖垮記憶體。實作結果是完成 sizing recommendation table、binary-heavy workflow 風險說明、容量觀察指標清單,驗收重點鎖定在 small business 的 4 vCPU / 8 GB RAM / PostgreSQL / backup / monitoring 合理起點與調整理由。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| sizing recommendation table | 完成 | artifacts/week-13-capacity/week-13-sizing-recommendation-table.json;本章 13.3 |
| binary-heavy workflow 風險說明 | 完成 | artifacts/week-13-capacity/week-13-binary-heavy-risk-register.json;本章 13.4 |
| 容量觀察指標清單 | 完成 | artifacts/week-13-capacity/week-13-capacity-observation-metrics.csv;本章 13.5 |
| server sizing table 解讀 | 完成 | 本章 13.2、13.3 |
| frequency、concurrency、binary size、wait states、AI calls、browser automation 影響整理 | 完成 | 本章 13.6 |
| Week 13 驗證腳本 | 完成 | scripts/verify-week-thirteen.mjs |
核心判斷不是「規格越大越安全」,而是先看 workflow 的資料形狀與執行模式,再用觀察指標決定是否升級。
整合來源:docs/week-13-database-binary-capacity-planning.md
258| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| server sizing table 與資源考量 | n8n prerequisites | n8n 官方 prerequisites 提醒需求會依 users、workflows、executions 而變;CPU 通常不是最先卡住的資源,memory 與資料形狀更關鍵。 |
| performance factors | n8n performance benchmarking | n8n 官方 performance page 把 workflow type、available resources、scaling configuration 列為效能因素;精準估算應做 benchmark。 |
| scaling overview | n8n scaling overview | 大量 users、workflows、executions 時需要調整設定;queue mode 是主要 scaling 路線,execution data/pruning 會影響 database performance。 |
| supported databases | Supported databases | n8n self-host 預設 SQLite,也支援 PostgreSQL;重要流程與多人使用應優先把 state 放在 PostgreSQL。 |
| database environment variables | Database environment variables | DB_TYPE=postgresdb 是切換到 PostgreSQL 的核心設定。 |
| queue mode | Queue mode | queue mode 用 Redis 與 workers 拆分 execution;n8n 建議 queue mode 使用 Postgres 13+,不建議 SQLite。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| concurrency control | Concurrency control | regular mode 預設不限制 production executions,同時過多會造成 event loop thrash;可用 N8N_CONCURRENCY_PRODUCTION_LIMIT 控制。 |
| execution data | Execution data | execution data pruning 預設啟用,會依 age 與 count 清理;waiting 狀態不會被 pruning。 |
| executions env vars | Executions environment variables | EXECUTIONS_DATA_PRUNE、EXECUTIONS_DATA_MAX_AGE、EXECUTIONS_DATA_PRUNE_MAX_COUNT、N8N_CONCURRENCY_PRODUCTION_LIMIT 是容量控制重點。 |
| binary data | Binary data | n8n 預設把 binary data 放在 memory,處理大檔可能 crash;filesystem mode 可把資料寫到 disk;queue mode 不支援 filesystem mode。 |
| binary data env vars | Binary data environment variables | N8N_DEFAULT_BINARY_DATA_MODE 可設為 filesystem、s3 或 database;active mode 會影響 binary data pruning。 |
| external storage | External storage | Self-hosted Enterprise 可把 binary data 放到 S3,用來避免依賴 filesystem 承載大量 binary data。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| memory-related errors | Memory-related errors | memory 問題通常來自 workflow 資料量、binary files、複製資料、並發與 node 行為,需要以 workload 方式分析。 |
| monitoring | Monitoring | production 要開監控指標與健康檢查,尤其是 execution、queue、worker、process 指標。 |
| logging | Logging | logs 是定位 crash、timeout、queue backlog、DB connection、external API error 的第一層證據。 |
| waiting | Waiting in n8n | Wait node 會讓 workflow 暫停後再從同一份資料恢復,會把 execution state 留在系統裡。 |
| AI workflows | n8n AI workflows | AI workflow 會引入 model latency、token payload、tool calls 與評估資料,容量規劃要把外部 API 時間與資料大小納入。 |
| host command execution | Execute Command | Execute Command 會在 host/container/worker 上執行 shell command;browser automation 若透過外部程序執行,會消耗 worker 所在節點的 CPU 與 memory。 |
本週的規格表不是把官方最小需求當 production 建議,而是把官方限制轉成操作規則:先用 workload profile 選一個保守起點,再用 metrics 決定升級。
| Profile | 初始規格 | Database | Binary data mode | Backup | Monitoring | 合理使用範圍 |
|---|---|---|---|---|---|---|
| learning | 1 vCPU / 1 到 2 GB RAM | SQLite 可接受 | default 或 filesystem | 手動 export workflows + credentials key 保存 | local logs | 學習 n8n UI、少量 manual executions、無重要 production webhook。 |
| personal | 2 vCPU / 4 GB RAM | SQLite 可用;重要流程改 PostgreSQL | filesystem 優先 | 每日 volume snapshot 或 DB dump | 基本 uptime + logs | 個人自動化、低頻 schedule、少量 webhook、binary file 偶發。 |
| freelancer | 2 vCPU / 4 GB RAM 起;客戶流程多時升到 4 vCPU / 8 GB RAM | PostgreSQL 建議 | filesystem;queue mode 時改 database | 每日 PostgreSQL backup + restore drill | HTTP、CPU、memory、disk、DB size | 多個客戶 workflow、需要穩定 webhook、仍是單機或低併發。 |
| Profile | 初始規格 | Database | Binary data mode | Backup | Monitoring | 合理使用範圍 |
|---|---|---|---|---|---|---|
| small business | 4 vCPU / 8 GB RAM | PostgreSQL | filesystem;高併發或 queue mode 改 database/S3 | 每日自動備份 + 每月 restore drill | monitoring dashboard + alerts | 多人使用、固定 business workflow、moderate webhook、需要可恢復資料層。 |
| agency | 4 到 8 vCPU / 16 GB RAM 起;依 worker 數拆分 | Managed PostgreSQL | database 或 S3;避免單機 filesystem 鎖死 workers | PITR 或快照 + restore runbook | Prometheus/CloudWatch/Grafana + log alert | 多客戶、多 workflow、併發 webhook、需要 worker separation 與環境隔離。 |
| AI-heavy | 8 vCPU / 16 到 32 GB RAM 起;worker 獨立 sizing | Managed PostgreSQL + Redis queue mode | S3 或 database;大檔不放 memory | DB + object storage backup + retention policy | model latency、error rate、queue depth、worker memory | RAG、document processing、multi-step agents、browser automation、長 latency external API calls。 |
4 vCPU / 8 GB RAM / PostgreSQL / backup / monitoring| 層面 | 判斷 |
|---|---|
| CPU | n8n 官方指出 CPU 通常不是最先卡住的資源,但 business workflow 會有多個 trigger、HTTP requests、transform、webhook response,4 vCPU 給 event loop、PostgreSQL client、background jobs、OS/container 留出餘裕。 |
| Memory | binary data、Code node、large JSON payload、AI response、browser automation 都會推高 memory,8 GB 比 2 到 4 GB 更能承受 business burst。 |
| Database | SQLite 適合學習與低風險個人使用;small business 需要 workflows、credentials、executions 可備份、可還原、可遷移,因此 PostgreSQL 是合理起點。 |
| Backup | business 不是只要「今天能跑」,而是要能從錯誤升級、誤刪 workflow、DB corruption、host failure 裡恢復;每日 backup 與 restore drill 是基本線。 |
| Monitoring | 沒有 monitoring 就無法知道是 CPU、memory、DB、binary disk、queue、AI API 還是 webhook latency 卡住;small business 起點必須把 alerts 納入,不是等事故後再看 logs。 |
| 若觀察到 | 調整 |
|---|---|
| CPU 長時間高於 70%,execution latency 上升,但 memory 與 DB 正常 | 增加 vCPU,或把重 CPU workflow 拆到 queue workers。 |
| memory RSS 長時間高於 70%,有 container restart 或 JavaScript heap error | 降低 concurrency、改 binary filesystem/database/S3、拆分大型 Code node、增加 RAM。 |
| PostgreSQL CPU、connection、storage 增長快 | 調整 execution data save/prune、升級 DB tier、檢查長時間 waiting executions。 |
| webhook burst 導致 response time 升高 | 設 N8N_CONCURRENCY_PRODUCTION_LIMIT,或進 queue mode + workers + Redis。 |
| binary data disk 增長快 | 啟用 pruning、改 external storage、限制檔案大小、縮短 retention。 |
| AI calls 與 browser automation 佔用時間長 | 以 worker pool 隔離,設定 timeout/retry/rate limit,避免拖慢一般 webhook。 |
binary-heavy workflow 指的是會處理 image、PDF、audio、video、large CSV、zip、document extraction、screenshots、headless browser downloads、AI document processing 的 workflow。這類 workflow 最大問題不是「檔案能不能進 n8n」,而是檔案在 execution 過程中會經過 memory、temporary storage、execution data、binary data mode、backup、pruning、download/upload API,每一層都可能被放大。
Crash or restart risk。
Volume durability / disk full。
Large backups / restore delay。
Bucket policy / retention / cleanup。
| 風險 | 為什麼危險 | 早期訊號 | 降低風險 |
|---|---|---|---|
| default memory mode 處理大檔 | n8n 預設 binary data 在 memory;大檔與多併發會讓 process crash。 | memory RSS 上升、container restart、workflow 卡在同一個 binary step。 | production 改 N8N_DEFAULT_BINARY_DATA_MODE=filesystem;queue mode 改 database 或 external storage。 |
| filesystem mode disk 增長 | 大量檔案會吃掉 volume;volume 沒持久化會在 redeploy 後遺失。 | disk usage 持續上升、binaryData 目錄過大、backup 時間增加。 | 使用 persistent volume、disk alert、pruning、retention policy。 |
| database mode 放大 DB | binary data 進 DB 會讓 storage、backup、restore、vacuum、query latency 都變重。 | DB size 快速成長、backup window 拉長、PostgreSQL I/O 高。 | 只在 queue mode 或共享 worker 需要時使用;大檔優先 external storage。 |
| 風險 | 為什麼危險 | 早期訊號 | 降低風險 |
|---|---|---|---|
| S3/external storage lifecycle 不清楚 | object storage 可減輕 filesystem,但權限、retention、pruning mode 一定要一致。 | DB execution 已清理但 bucket 仍成長,或 workflow 找不到 object。 | bucket lifecycle、IAM least privilege、mode migration checklist、restore test。 |
| Wait node 與 binary data 結合 | waiting status 不會被 execution pruning 清掉;暫停的 execution 會保留資料直到恢復。 | waiting executions 數量上升、old execution data 保留、DB/storage 未下降。 | 對 wait states 設計上限,避免把大型 binary data 帶進長等待。 |
| AI calls 處理文件 | AI workflow 會疊加文件抽取、prompt payload、response、tool calls、external API latency。 | AI API latency 上升、retry 多、execution duration 拉長。 | 先縮小文件、分段處理、把長任務放 queue worker,設定 timeout 與 retry。 |
| 風險 | 為什麼危險 | 早期訊號 | 降低風險 |
|---|---|---|---|
| browser automation | headless browser、screenshots、downloads 會在 host/container/worker 上吃 CPU、RAM、disk。 | worker memory spike、Chrome process 殘留、download 目錄暴增。 | worker 隔離、限制並發、清理 temp files、把 browser automation 與普通 webhook 分池。 |
| 大 webhook payload | 外部服務一次送大檔或高頻 burst,會同時壓 memory、disk、DB 與 response time。 | webhook latency 上升、HTTP timeout、queue backlog。 | 前置檔案大小限制、signed upload URL、queue mode、concurrency limit。 |
| 指標 | 為什麼要看 | 警訊 | 對應動作 |
|---|---|---|---|
| CPU usage | 判斷 event loop、transform、browser automation 是否吃滿 CPU | 5 到 15 分鐘平均高於 70% 且 latency 上升 | 增加 vCPU、拆 worker、降低並發。 |
| memory RSS / heap | binary data、large JSON、Code node、AI payload 會推高 memory | 高於 70% 且持續上升,或出現 restart | 調整 binary mode、增加 RAM、拆 workflow。 |
| container restarts / OOM | 直接反映 crash 與容量不足 | 任意非預期 restart | 查 logs、降低 concurrency、增加 memory、拆重任務。 |
| PostgreSQL storage | execution data 與 binary data 會讓 DB 成長 | DB 每週增長超出預期或 backup window 變長 | 調整 EXECUTIONS_DATA_MAX_AGE、prune count、改 binary storage。 |
| PostgreSQL connections | queue mode、workers、webhook burst 會增加 DB connection | 接近 DB limit 或連線等待 | 降低 worker 數、調 pool、升級 DB。 |
| 指標 | 為什麼要看 | 警訊 | 對應動作 |
|---|---|---|---|
| execution count and duration | 直接描述實際 workload | duration p95 上升或 failed execution 增加 | 找出慢 workflow,拆分與加上 timeout。 |
| active / waiting executions | waiting executions 會保留 state | waiting 數量持續增加 | 設等待上限,避免長時間保留大型 payload。 |
| queue depth / worker backlog | queue mode 是否處理得過來 | queue depth 持續增加 | 增加 workers、調整 concurrency、拆分重任務。 |
| webhook latency | 外部系統最直接感受到的 SLA | p95 超過外部 provider timeout 風險 | 快速回應,重任務放 background queue。 |
| binary storage size | filesystem/S3/database 的容量風險 | binary storage 持續上升且 pruning 未下降 | 檢查 active mode、lifecycle、retention、檔案大小。 |
| 指標 | 為什麼要看 | 警訊 | 對應動作 |
|---|---|---|---|
| AI API latency/error rate | 外部 model 會拖長 execution | latency 或 429/5xx 上升 | rate limit、retry backoff、fallback model。 |
| browser automation duration/memory | headless browser 容易吃掉 worker | duration 拉長、worker memory spike | 限制並發、獨立 worker pool、清 temp files。 |
| backup success and duration | backup 是可恢復性的底線 | backup 失敗或 restore 未演練 | 立即修復 backup,定期 restore drill。 |
| log error rate | 最早暴露 DB、queue、credentials、API、storage 問題 | 同類 error 增加 | 建立 alert,回到相關 runbook。 |
frequency 是 workflow 啟動頻率。每分鐘一個 schedule 與每天一次 manual run 的容量模型完全不同。高 frequency 會累積 execution count、DB writes、logs、API calls;如果每次又保存完整 execution data,PostgreSQL 與 backup 會比 CPU 更早成為瓶頸。
concurrency 是同時間執行數。n8n regular mode 預設不限制 production executions,同時太多會讓 event loop thrash。small business 起點可先用 N8N_CONCURRENCY_PRODUCTION_LIMIT 控制 burst;如果 webhook burst 變成常態,才進 queue mode、Redis、workers。
binary size 直接決定 memory、disk、DB、backup 壓力。default mode 下大檔會進 memory,filesystem mode 會壓 disk,database mode 會壓 DB,S3 mode 會壓 object lifecycle 與 permissions。binary-heavy workload 不應只看 vCPU/RAM,必須看檔案大小、保存時間、active binary mode 與 pruning。
wait states 會把 execution 暫停,再用同一份資料恢復。這對 rate limit 與人工確認很有用,但 waiting status 不會被 pruning,長時間等待加大型 payload 會讓 DB/storage 保留資料。設計時要避免把大型 binary data 帶入長等待。
AI calls 的容量瓶頸常常不是 CPU,而是外部 API latency、token payload、retry、rate limit、document extraction 與 response size。AI-heavy workflow 應使用 queue workers、分段文件、timeout、retry backoff、model error monitoring,不要讓一般 webhook 和長 AI execution 搶同一個單機 process。
browser automation 若透過 Execute Command、自建 node 或 worker 外部程序跑 headless browser,CPU、RAM、download directory、temp files 會在執行節點上爆量。它要獨立 worker pool、低 concurrency、明確 cleanup、process timeout;不要把它當普通 HTTP Request node 估容量。
| 項目 | 建議 |
|---|---|
| Runtime | 4 vCPU / 8 GB RAM |
| Database | PostgreSQL,避免把 business state 放在 SQLite |
| Binary data | 一般情境用 filesystem + persistent volume;queue mode 時改 database 或 external storage |
| Backup | 每日 automated backup,至少每月一次 restore drill |
| Monitoring | CPU、memory、restart、HTTP status、webhook latency、DB storage、DB connections、execution failures、binary storage、backup status |
| Concurrency | 先設定保守 N8N_CONCURRENCY_PRODUCTION_LIMIT,觀察後再增加 |
| Upgrade trigger | p95 latency 上升、memory 高水位、DB 增長過快、backup 超時、queue backlog、binary storage 成長不可控 |
2 vCPU / 4 GB RAM 可以跑很多 personal 或 freelancer 場景,但 small business 有幾個差異:多人使用、重要 webhook、固定工作流、更多 execution history、更多 credentials、更多錯誤重試、需要可預測 backup。8 GB RAM 不是浪費,而是給 binary data、large JSON、AI response、browser automation、Node.js heap、PostgreSQL client、OS/container 留一個事故緩衝。
| 狀態 | 升級路線 |
|---|---|
| 單機 CPU/RAM 偶爾尖峰,但平均正常 | 先調 workflow、pruning、concurrency,不急著加 workers。 |
| webhook latency 受重任務影響 | 把重任務轉 background workflow,或使用 queue mode。 |
| execution 量增加,DB writes/reads 明顯上升 | 升級 PostgreSQL、調 retention、避免保存不必要成功 execution data。 |
| binary data 成為主要容量來源 | 轉 S3/external storage 或縮短 retention,並測 restore。 |
| AI-heavy 或 browser automation 成為主業務 | 建立獨立 worker pool,規格從 8 vCPU / 16 GB RAM 起測。 |
| 步驟 | 動作 |
|---|---|
| 1 | 先分類 workflow:learning、personal、freelancer、small business、agency、AI-heavy。 |
| 2 | 填 frequency、concurrency、binary size、wait states、AI calls、browser automation 六項影響因素。 |
| 3 | 選初始規格:small business 以 4 vCPU / 8 GB RAM / PostgreSQL / backup / monitoring 起步。 |
| 4 | 設 execution data policy:成功 execution 是否保存、保存多久、最多保存幾筆、manual executions 是否保存。 |
| 5 | 設 binary data mode:default 只適合小型與低風險;production binary-heavy 不使用 default memory mode。 |
| 步驟 | 動作 |
|---|---|
| 6 | 設 alerts:CPU、memory、restart、DB storage、DB connections、disk、binary storage、queue depth、failed executions、backup failure。 |
| 7 | 跑 7 到 14 天觀察:看 p95 latency、memory high-water mark、DB growth、binary growth、backup duration。 |
| 8 | 按瓶頸調整:CPU 加 vCPU,memory 加 RAM 或改 binary mode,DB 升級或 prune,webhook burst 進 queue mode,AI/browser automation 拆 worker。 |
| 9 | 每次調整後做 restore drill,確認 backup 與 object storage lifecycle 沒有被規格變更破壞。 |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 讀 server sizing table | 通過 | 第 2、3 節,採用 n8n prerequisites 與 performance 官方說明 |
| 整理 learning、personal、freelancer、small business、agency、AI-heavy 初始規格 | 通過 | 第 3 節與 week-13-sizing-recommendation-table.json |
| 辨認 frequency、concurrency、binary size、wait states、AI calls、browser automation 影響 | 通過 | 第 6 節 |
| 完成 sizing recommendation table | 通過 | 第 3 節與 JSON artifact |
| 完成 binary-heavy workflow 風險說明 | 通過 | 第 4 節與 risk register JSON |
| 完成容量觀察指標清單 | 通過 | 第 5 節與 CSV artifact |
| 能為 small business 提出 4 vCPU / 8 GB RAM / PostgreSQL / backup / monitoring 起點或調整理由 | 通過 | 第 3、7、8 節 |
Week 14 會進入備份、還原與更新流程。Week 13 已定義 PostgreSQL、binary data、execution data、backup、monitoring 的容量基線,下一週要把這些基線變成可演練的 restore drill、upgrade runbook、rollback checklist 與版本更新節奏。
Week 13 的成果,是把容量規劃從「買大一點」轉成「看 workload、設 baseline、量 metrics、按瓶頸調整」。small business 的合理起點是 4 vCPU / 8 GB RAM / PostgreSQL / backup / monitoring,但 binary-heavy、AI-heavy、browser automation 都可能要求更早拆 worker 或改 storage mode。
14.0 本週定位
Week 14 回答如何讓 n8n 不只會跑,還能在升級失敗或資料遺失時回得來。本週完成 backup runbook、restore runbook、update / rollback checklist,並明確保存 database、volume、encryption key、Compose/env/proxy config,設計一次隔離還原演練。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| backup runbook | 完成 | artifacts/week-14-recovery/week-14-backup-runbook.json;本章 14.3 |
| restore runbook | 完成 | artifacts/week-14-recovery/week-14-restore-runbook.json;本章 14.4 |
| update / rollback checklist | 完成 | artifacts/week-14-recovery/week-14-update-rollback-checklist.csv;本章 14.5 |
| pg_dump 與 volume archive | 完成 | 本章 14.3、14.4 |
| restore command 與演練 | 完成 | 本章 14.4、14.6 |
| release notes、image pinning、pull、restart、test、rollback | 完成 | 本章 14.5、14.7 |
| Week 14 驗證腳本 | 完成 | scripts/verify-week-fourteen.mjs |
Week 13 說 small business 要有 backup / monitoring;Week 14 把 backup 變成四個不可缺項:database dump、volume archive、encryption key 保存、Compose/env/proxy config 保存。缺任何一項,都可能造成「服務能起來,但回不到可用狀態」。
整合來源:docs/week-14-backup-restore-update-runbook.md
283| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n Docker installation | n8n Docker installation | n8n Docker guide 建議 self-host 使用 Docker,並把 n8n_data volume 掛到 /home/node/.n8n 以保存資料;使用 PostgreSQL 時 .n8n 仍包含 encryption keys、logs、source control assets 等重要資料。 |
| n8n Docker Compose updating | Updating Docker Compose | n8n 官方更新 Docker Compose 的基本流程是進 compose 目錄、docker compose pull、docker compose down、docker compose up -d;production 需要加上 backup、image pinning、smoke test 與 rollback。 |
| n8n release notes | n8n release notes | n8n 發布節奏頻繁,release notes 說明 stable/beta、semantic versioning 與版本變更;升級前必須閱讀目標版本與中間版本資訊。 |
| n8n encryption key | n8n encryption key | n8n 用 encryption key 加密 credentials;若 key 遺失或更換,資料庫仍在也可能無法解密既有 credentials;queue mode 所有 workers 都要同一把 key。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n database env vars | Database environment variables | PostgreSQL 模式需要保存 DB_TYPE=postgresdb、host、database、user、password、schema 等設定,還原時要與 backup 對應。 |
| n8n webhook URL | Webhook URL | proxy/custom domain 後方要保存 WEBHOOK_URL 與 editor base URL,否則還原後 webhook 或 OAuth callback 會指錯位置。 |
| n8n binary data | Binary data | binary data mode 會影響要備份的 storage;filesystem mode 需要 volume archive,database mode 會進 database dump,S3 mode 要另有 bucket/lifecycle/restore 策略。 |
| PostgreSQL pg_dump | pg_dump | pg_dump 可匯出 PostgreSQL database;custom format -Fc 搭配 pg_restore 更適合還原演練與選擇性 restore。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| PostgreSQL pg_restore | pg_restore | pg_restore 可把 custom format dump 還原到指定 database;restore drill 應在隔離 database/project 中驗證,不直接覆蓋 production。 |
| Docker volumes | Docker volumes | Docker volumes 是持久化資料層;volume archive 可用臨時容器把 volume 掛進去後用 tar 打包或解開。 |
| Docker Compose pull | docker compose pull | docker compose pull 取得 service image;本 runbook 要求先 pin 目標 tag 再 pull。 |
| Docker Compose up/down | docker compose up 與 docker compose down | up -d 啟動或重建 service;down 停止並移除 containers/networks,但不能搭配 -v 用在一般更新,避免誤刪 volumes。 |
本週文件採用 Week 10 的 VPS + Docker Compose + Caddy 架構作為範本;如果實際 production 是 Cloud Run、AWS、Railway、Zeabur、Render 或 Fly.io,四個不可缺項仍相同,只是工具換成平台的 managed backup、volume snapshot、secret manager export policy 與 IaC config backup。
| 類別 | 必須保存 | 原因 |
|---|---|---|
| database | PostgreSQL dump:database.dump | workflows、credentials metadata、executions、users、settings 等主要 state。 |
| volume | n8n_data.tgz、必要時 caddy_data.tgz、caddy_config.tgz | /home/node/.n8n 仍可能保存 encryption keys、logs、source control assets;proxy volumes 可能保存 certificates 或 Caddy state。 |
| encryption key | N8N_ENCRYPTION_KEY 的受控副本 | credentials 解密依賴同一把 key;database 還原但 key 遺失仍會造成 credentials 無法使用。 |
| Compose/env/proxy config | compose.yaml、.env、Caddyfile、docker-compose.rendered.yaml、checksum manifest | 還原時要重建相同 image、env vars、DB connection、WEBHOOK_URL、N8N_EDITOR_BASE_URL、proxy routing 與 TLS 設定。 |
以下命令以 artifacts/week-10-vps-caddy 架構為範本,production 使用前要在真正 compose 目錄執行,並確認 backup 目的地是加密磁碟、受控 object storage 或離線保管空間。
set -euo pipefail
APP_DIR="artifacts/week-10-vps-caddy"
BACKUP_ID="$(date -u +%Y%m%dT%H%M%SZ)"
BACKUP_DIR="backups/${BACKUP_ID}"
cd "${APP_DIR}"
mkdir -p "${BACKUP_DIR}"
chmod 700 "${BACKUP_DIR}"
set -a
. ./.env
set +a
docker compose --env-file .env -f compose.yaml config > "${BACKUP_DIR}/docker-compose.rendered.yaml"
cp compose.yaml .env Caddyfile "${BACKUP_DIR}/"
awk -F= '/^N8N_ENCRYPTION_KEY=/{print $2}' .env > "${BACKUP_DIR}/n8n-encryption-key.txt"
chmod 600 "${BACKUP_DIR}/.env" "${BACKUP_DIR}/n8n-encryption-key.txt"
docker compose --env-file .env -f compose.yaml exec -T postgres \
pg_dump -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" -Fc --no-owner --no-acl \
> "${BACKUP_DIR}/database.dump"
docker run --rm \
-v n8n-week10-vps_n8n_data:/source:ro \
-v "${PWD}/${BACKUP_DIR}":/backup \
alpine:3.20 \
tar -czf /backup/n8n_data.tgz -C /source .
docker run --rm \
-v n8n-week10-vps_caddy_data:/source:ro \
-v "${PWD}/${BACKUP_DIR}":/backup \
alpine:3.20 \
tar -czf /backup/caddy_data.tgz -C /source .
docker run --rm \
-v n8n-week10-vps_caddy_config:/source:ro \
-v "${PWD}/${BACKUP_DIR}":/backup \
alpine:3.20 \
tar -czf /backup/caddy_config.tgz -C /source .
shasum -a 256 "${BACKUP_DIR}"/* > "${BACKUP_DIR}/SHA256SUMS"
find "${BACKUP_DIR}" -maxdepth 1 -type f -print | sort
| 檢查 | 通過條件 |
|---|---|
| database dump | database.dump 非空,pg_restore -l database.dump 可列出 archive contents。 |
| volume archive | n8n_data.tgz 非空,tar -tzf n8n_data.tgz 可列出檔案;若使用 filesystem binary data,能看到對應 binary data 路徑或設定。 |
| encryption key | n8n-encryption-key.txt 與 .env 中 N8N_ENCRYPTION_KEY 相同,檔案權限為 owner-only。 |
| Compose/env/proxy config | compose.yaml、.env、Caddyfile、rendered compose 都在同一份 backup set。 |
| checksum | SHA256SUMS 可在搬移後重新驗證。 |
| storage policy | backup set 已移到 production host 以外的位置,且存放位置加密、有存取紀錄、有 retention。 |
若 database.dump、n8n_data.tgz、N8N_ENCRYPTION_KEY、compose.yaml、.env、Caddyfile、docker-compose.rendered.yaml 任一項缺失,本次 backup 不算完成。不能在 backup 不完整時進行 production upgrade。
還原演練必須在隔離 project 中進行,例如 n8n-week14-restore-drill。隔離的意思是:不使用 production container name,不接 production domain,不覆蓋 production volume,不讓外部 webhook provider 打到演練環境。演練目標是證明 backup set 可以重建出可登入、可解密 credentials、可查看 workflows、可連 PostgreSQL、可使用正確 proxy/env config 的 n8n。
set -euo pipefail
APP_DIR="artifacts/week-10-vps-caddy"
BACKUP_DIR="backups/20260528T000000Z"
RESTORE_PROJECT="n8n-week14-restore-drill"
cd "${APP_DIR}"
shasum -a 256 -c "${BACKUP_DIR}/SHA256SUMS"
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" down --remove-orphans
docker volume rm "${RESTORE_PROJECT}_n8n_data" "${RESTORE_PROJECT}_caddy_data" "${RESTORE_PROJECT}_caddy_config" "${RESTORE_PROJECT}_postgres_data" 2>/dev/null || true
docker volume create "${RESTORE_PROJECT}_n8n_data"
docker volume create "${RESTORE_PROJECT}_caddy_data"
docker volume create "${RESTORE_PROJECT}_caddy_config"
docker volume create "${RESTORE_PROJECT}_postgres_data"
docker run --rm \
-v "${RESTORE_PROJECT}_n8n_data":/target \
-v "${PWD}/${BACKUP_DIR}":/backup:ro \
alpine:3.20 \
sh -c 'cd /target && tar -xzf /backup/n8n_data.tgz'
docker run --rm \
-v "${RESTORE_PROJECT}_caddy_data":/target \
-v "${PWD}/${BACKUP_DIR}":/backup:ro \
alpine:3.20 \
sh -c 'cd /target && tar -xzf /backup/caddy_data.tgz'
docker run --rm \
-v "${RESTORE_PROJECT}_caddy_config":/target \
-v "${PWD}/${BACKUP_DIR}":/backup:ro \
alpine:3.20 \
sh -c 'cd /target && tar -xzf /backup/caddy_config.tgz'
set -a
. "${BACKUP_DIR}/.env"
set +a
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" up -d postgres
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" exec -T postgres \
sh -c "dropdb -U \"${POSTGRES_USER}\" --if-exists \"${POSTGRES_DB}\" && createdb -U \"${POSTGRES_USER}\" \"${POSTGRES_DB}\""
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" exec -T postgres \
pg_restore -U "${POSTGRES_USER}" -d "${POSTGRES_DB}" --no-owner --no-acl --exit-on-error \
< "${BACKUP_DIR}/database.dump"
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" up -d n8n
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" ps
docker compose -p "${RESTORE_PROJECT}" --env-file "${BACKUP_DIR}/.env" -f "${BACKUP_DIR}/compose.yaml" logs --tail=120 n8n
| 驗收項 | 通過條件 |
|---|---|
| checksum | shasum -a 256 -c SHA256SUMS 全部通過。 |
| PostgreSQL restore | pg_restore exit code 為 0,logs 沒有 schema/owner/permission fatal error。 |
| n8n starts | docker compose ps 顯示 n8n 與 postgres running 或 healthy。 |
| credentials decrypt | 登入演練環境後,既有 credentials 不出現 encryption key 相關錯誤。 |
| workflows visible | 既有 workflows、tags、users、settings 可見。 |
| volume data | .n8n 相關資料存在;若使用 filesystem binary data,抽樣 execution 可讀取 binary data。 |
| Compose/env/proxy config | WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS、Caddy reverse proxy 設定與 production 設計一致。 |
| isolation | 演練環境未接 production DNS,沒有外部 provider 對它送 production webhook。 |
| 症狀 | 第一個檢查 |
|---|---|
| n8n 起來但 credentials 無法使用 | N8N_ENCRYPTION_KEY 是否與 backup 時完全相同。 |
| workflows 不見 | PostgreSQL restore 是否用錯 database、schema、project 或 .env。 |
| webhook URL 指錯位置 | .env、WEBHOOK_URL、N8N_EDITOR_BASE_URL、proxy config 是否保存並還原。 |
| binary data 讀不到 | binary data mode 是 filesystem、database 或 S3;對應 volume、DB 或 bucket 是否一起還原。 |
| Caddy/TLS 失效 | Caddyfile、caddy_data、caddy_config、domain DNS 是否一致。 |
| 階段 | 必做事項 | 通過訊號 | 失敗時動作 |
|---|---|---|---|
| release notes | 閱讀 n8n release notes、目標版本與中間版本,標記 breaking changes、deprecated nodes、migration notes。 | upgrade ticket 中列出版本差異與風險。 | 不升級,先補測試案例或等 patch release。 |
| image pinning | 把 docker.n8n.io/n8nio/n8n:2.22.4 這類明確 tag 寫進 compose,不用浮動 latest 當 production 依據。 | docker compose config 顯示 pinned tag。 | 停止流程,先 pin tag。 |
| backup | 執行第 3 節 backup runbook,確認 database、volume、encryption key、Compose/env/proxy config 都保存。 | backup set 完整且 checksum 通過。 | 不升級。 |
| restore drill | 用第 4 節 restore runbook 在隔離 project 演練。 | 登入、credentials、workflows、webhook URL、logs 都通過。 | 不升級,先修 backup 或 restore。 |
| 階段 | 必做事項 | 通過訊號 | 失敗時動作 |
|---|---|---|---|
| pull | 先 pull pinned target image。 | docker compose pull n8n 成功,image digest 已記錄。 | 不重啟 production。 |
| restart | 用 docker compose up -d n8n 重建 n8n service;必要時依官方流程使用 docker compose down 再 up -d,但一般更新不能加 -v。 | service 起來,docker compose ps 正常。 | 立即看 logs,必要時 rollback。 |
| test | 測 editor、login、workflow list、credential decrypt、manual execution、production webhook、proxy HTTPS、logs。 | smoke tests 全部通過。 | 啟動 rollback。 |
| rollback | 把 compose image tag 改回 previous version,docker compose pull n8n,docker compose up -d n8n,用 backup set 驗證資料未被破壞。 | previous version 起來,smoke tests 通過。 | 若 DB migration 已不可逆,改走 full restore plan。 |
| record | 記錄版本、image digest、backup id、restore drill result、測試結果、是否 rollback。 | release log 有完整證據。 | 不關閉 change window。 |
演練名稱:week-14-restore-drill-small-business-compose-postgres
證明一份 backup set 可以在隔離 project 重建 n8n,並且 database、volume、encryption key、Compose/env/proxy config 都能一起工作。這不是只測 pg_restore,而是測「使用者真的能回到可用狀態」。
| 資料 | 來源 |
|---|---|
database.dump | pg_dump -Fc 產生的 PostgreSQL dump。 |
n8n_data.tgz | Docker volume archive,來源為 n8n_data:/home/node/.n8n。 |
caddy_data.tgz、caddy_config.tgz | proxy volume archive。 |
n8n-encryption-key.txt | .env 中的 N8N_ENCRYPTION_KEY。 |
compose.yaml、.env、Caddyfile、docker-compose.rendered.yaml | Compose/env/proxy config。 |
SHA256SUMS | 備份完整性檢查。 |
| 時間 | 動作 |
|---|---|
| T-30 分鐘 | 宣告演練,不接 production DNS,不使用 production project name。 |
| T-20 分鐘 | 驗證 backup set 完整性與 checksum。 |
| T-15 分鐘 | 建立隔離 volumes,解開 n8n_data 與 proxy archives。 |
| T-10 分鐘 | 啟動 PostgreSQL,drop/create 演練 database,執行 pg_restore。 |
| T-5 分鐘 | 啟動 n8n,確認 logs 沒有 encryption、DB、migration、permission fatal error。 |
| T+0 分鐘 | 登入 editor,確認 workflows、credentials、webhook URL、manual execution。 |
| T+15 分鐘 | 記錄 RTO、restore duration、錯誤、修正項。 |
| T+20 分鐘 | 停止並清理演練 project,保留演練紀錄。 |
| 序號 | 演練通過條件 |
|---|---|
| 1 | SHA256SUMS 完整通過。 |
| 2 | pg_restore exit code 為 0。 |
| 3 | n8n 起動後 logs 沒有 credentials decryption error。 |
| 4 | workflows、credentials、users、settings 可見。 |
| 5 | WEBHOOK_URL 與 N8N_EDITOR_BASE_URL 仍指向預期 production domain 或演練覆寫 domain,沒有變成 localhost。 |
| 6 | 若 binary data 使用 filesystem mode,至少抽樣一筆含 binary data 的 execution 可以讀取附件。 |
| 7 | RTO 與 restore duration 有記錄,且不超過 small business 允許停機窗口。 |
| 步驟 | 更新前動作 |
|---|---|
| 1 | 看 n8n release notes:確認 target version、previous version、semantic versioning 風險、breaking changes、deprecated nodes、migration notes。 |
| 2 | 固定 image tag:把 docker.n8n.io/n8nio/n8n:2.22.4 改成目標版本,例如 docker.n8n.io/n8nio/n8n:2.23.0。 |
| 3 | 生成 rendered compose:docker compose --env-file .env -f compose.yaml config > docker-compose.pre-update.yaml。 |
| 4 | 執行 backup runbook,確認 database、volume、encryption key、Compose/env/proxy config 都在 backup set。 |
| 5 | 執行 restore drill,確認 backup set 真的可用。 |
set -euo pipefail
docker compose --env-file .env -f compose.yaml pull n8n
docker compose --env-file .env -f compose.yaml up -d n8n
docker compose --env-file .env -f compose.yaml ps
docker compose --env-file .env -f compose.yaml logs --tail=120 n8n
若此次更新涉及 database migration、major version、queue workers 或 schema 變更,先在 staging 或 restore drill project 跑一次,再進 production change window。
| 測試 | 通過條件 |
|---|---|
| editor | 可登入 n8n editor。 |
| workflows | workflow list 可讀取,重要 workflow 可打開。 |
| credentials | 既有 credentials 不出現 decrypt error。 |
| manual execution | 一條低風險 workflow 可手動執行成功。 |
| webhook | 測試 webhook 回傳預期 HTTP status,production URL 不指 localhost。 |
| proxy | HTTPS、Caddy reverse proxy、headers、N8N_PROXY_HOPS 正常。 |
| logs | 沒有 migration fatal error、DB connection error、permission error、encryption key error。 |
| monitoring | failed execution rate、latency、restart count 沒有異常上升。 |
set -euo pipefail
PREVIOUS_IMAGE="docker.n8n.io/n8nio/n8n:2.22.4"
perl -0pi -e "s#docker\\.n8n\\.io/n8nio/n8n:[0-9]+\\.[0-9]+\\.[0-9]+#${PREVIOUS_IMAGE}#g" compose.yaml
docker compose --env-file .env -f compose.yaml pull n8n
docker compose --env-file .env -f compose.yaml up -d n8n
docker compose --env-file .env -f compose.yaml ps
docker compose --env-file .env -f compose.yaml logs --tail=120 n8n
若新版本已執行不可逆 database migration,單純改回 image tag 可能不夠,這時要走 full restore:停止 service、還原 database dump、還原 volumes、放回 encryption key、放回 Compose/env/proxy config,再用 previous image 起動。這也是為什麼本週要求更新前必須先做 restore drill。
| 資產 | 若遺失會發生什麼 | 保存方式 |
|---|---|---|
| PostgreSQL database | workflows、credentials metadata、executions、users 可能消失。 | pg_dump -Fc、managed backup、restore drill。 |
n8n_data volume | .n8n 目錄內 encryption keys、logs、source control assets、binary data 可能遺失。 | Docker volume tar archive、persistent volume snapshot。 |
N8N_ENCRYPTION_KEY | credentials 可能無法解密,workflow 雖在但無法連外部服務。 | .env 受控備份、secret manager、離線密鑰保管。 |
compose.yaml | service、image、volumes、networks、env mapping 無法重建。 | Git/IaC、backup set、rendered compose。 |
.env | DB password、public URL、timezone、encryption key、runtime settings 遺失。 | 加密備份、secret manager、權限 600。 |
Caddyfile | reverse proxy、HTTPS、headers、upstream routing 遺失。 | Git/IaC、backup set。 |
caddy_data / caddy_config | Caddy certificates/state 可能重新申請或失效。 | volume archive,或確保可由 DNS/TLS 自動重建。 |
| release log | 無法知道哪個版本、backup id、image digest、測試結果與 rollback 決策。 | 變更紀錄與 artifact checksum。 |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 backup runbook | 通過 | 第 3 節與 week-14-backup-runbook.json |
| 完成 restore runbook | 通過 | 第 4、6 節與 week-14-restore-runbook.json |
| 完成 update / rollback checklist | 通過 | 第 5、7 節與 week-14-update-rollback-checklist.csv |
| 包含 pg_dump 與 volume archive | 通過 | 第 3、4 節 |
| 包含 restore command 與演練 | 通過 | 第 4、6 節 |
| 包含 release notes、image pinning、pull、restart、test、rollback | 通過 | 第 5、7 節 |
| 明確保存 database、volume、encryption key、Compose/env/proxy config | 通過 | 第 3、8 節 |
| 做一次還原演練設計 | 通過 | 第 6 節 |
Week 15 會進入安全責任、使用者管理與 patch cadence。Week 14 已經定義更新前必須 backup、restore drill、image pinning、smoke test、rollback,下一週要把這套流程延伸到 access control、2FA、user lifecycle、secret rotation、patch cadence 與安全事件責任分工。
Week 14 的成果,是把「有備份」變成「能演練還原」:database、volume、encryption key、Compose/env/proxy config 必須在同一個 backup set 裡,並且要先在隔離 project 驗證成功,才有資格進 production update。
15.0 本週定位
執行日期:2026-05-28。本週目標是回答公開 self-hosted n8n 時,哪些責任會回到自己身上。Week 14 已把 backup、restore drill、image pinning、smoke test、rollback 定成更新前底線;Week 15 把更新放回安全語境,明確定義 public instance 的責任分界、hardening checklist 與 patch cadence。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| security responsibility matrix | 完成 | artifacts/week-15-security/week-15-security-responsibility-matrix.json;本章 15.3 |
| public exposure hardening checklist | 完成 | artifacts/week-15-security/week-15-public-exposure-hardening-checklist.csv;本章 15.4 |
| patch cadence policy | 完成 | artifacts/week-15-security/week-15-patch-cadence-policy.json;本章 15.5 |
| Cloud/local/tunnel/VPS/PaaS/hyperscaler 責任分界 | 完成 | 本章 15.3、15.6 |
| HTTPS-only、secure cookies、SMTP/user management、2FA、SSO、secrets | 完成 | 本章 15.4、15.7 |
| 2026 之後 public instance 的 aggressively update 原則 | 完成 | 本章 15.5、15.8 |
| Week 15 驗證腳本 | 完成 | scripts/verify-week-fifteen.mjs |
公開 n8n instance 不是「workflow 工具開到網路上」而已。它同時接收 webhook、登入請求、API requests、OAuth callbacks、檔案、workflow data、credentials 與第三方 token。只要 self-host,安全邊界就回到部署方手上。
整合來源:docs/week-15-security-responsibility-patch-cadence.md
308| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| 選擇 Cloud 或 self-host | Choose n8n | n8n 明確說 self-hosting 需要設定伺服器、資源、security、configuration;若沒有 server 管理經驗,建議 n8n Cloud。 |
| n8n Cloud | n8n Cloud | n8n Cloud 是 hosted solution,提供 no technical setup/maintenance、uptime monitoring、managed OAuth、one-click upgrades;但 workflow、credentials、users、資料處理仍要由使用者治理。 |
| n8n Cloud 更新 | Update Cloud version | n8n Cloud 也建議 regular updates、檢查 release notes、先測試;Cloud instance 長期不更新會被通知並自動更新。 |
| Docker self-host | Docker installation | n8n Docker guide 說 self-hosting mistakes can lead to data loss, security issues, downtime;tunnel 是 local development/testing,不安全於 production。 |
| self-host 更新 | Updating n8n | n8n 官方建議 keep version up to date、frequent update、check release notes、至少每月一次、先用 test instance。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| release notes | Release notes | n8n 發布頻率高,stable/beta 與 semantic versioning 會影響 public instance 的風險判斷;patch cadence 必須看 release notes。 |
| Securing n8n | Securing overview | 官方安全總覽包含 security audit、SSL、SSO、2FA、redact execution data、disable public API、block nodes、SSRF protection、restrict account registration 等方向。 |
| Security audit | Security audit | n8n audit 可檢查 credentials、database、filesystem、nodes、instance,包括 unprotected webhooks、missing security settings、outdated instance。 |
| Disable public API | Disable public API | 若不用 public REST API,官方建議設定 N8N_PUBLIC_API_DISABLED=true;API playground 也可停用。 |
| User management | User management | n8n user management 包含 login/password、adding/removing users、Owner/Admin/Member。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Self-hosted user management | Self-hosted user management | Self-hosted n8n 建議設定 SMTP 以支援 invites 與 password resets;沒有 SMTP 時使用者不能 reset password。 |
| Manage users | Manage users | 刪除 active user 時要決定移轉或永久刪除 workflows/credentials;offboarding 必須有資料歸屬決策。 |
| Account types | Account types | Owner、Admin、Member 權限不同;官方建議 owner 建立 member-level account 做日常工作,降低覆寫他人工作風險。 |
| User management SMTP and 2FA env vars | SMTP and 2FA env vars | N8N_EMAIL_MODE、SMTP variables、N8N_MFA_ENABLED、N8N_INVITE_LINKS_EMAIL_ONLY 都是公開 instance 的 identity hardening 重點。 |
| SSO | Set up SSO | Business/Enterprise 可用 SAML/OIDC SSO;可用環境變數管理 SSO。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Security env vars | Security env vars | N8N_SECURE_COOKIE、N8N_SAMESITE_COOKIE、N8N_BLOCK_ENV_ACCESS_IN_NODE、N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS、security policy env vars 都屬於公開 instance hardening。 |
| SSRF protection | SSRF protection | N8N_SSRF_PROTECTION_ENABLED 與 blocked/allowed ranges 用來限制 workflow nodes 連到內網或 metadata services。 |
| Nodes env vars | Nodes env vars | NODES_EXCLUDE 可封鎖高風險 nodes,community packages 與 unverified packages 也可用環境變數控制。 |
| Community node risks | Community node risks | community nodes 可能有 system security、data security、breaking changes 風險;self-host 可停用 community nodes。 |
| External secrets | External secrets | Enterprise 可用 1Password、AWS Secrets Manager、Azure Key Vault、GCP Secrets Manager、HashiCorp Vault 管理 secrets,並用 project vaults 限制範圍。 |
public exposure 不是只要 Caddy/HTTPS 起來就完成。公開 instance 的安全邊界由版本新舊、登入與使用者管理、cookies、SMTP、2FA/SSO、secrets、API、SSRF、risky nodes、community nodes、logs、backup、audit、patch cadence 一起構成。
| 架構 | 平台承擔 | 使用者仍要承擔 | 不可誤解 |
|---|---|---|---|
| n8n Cloud | Hosting、基礎維運、uptime monitoring、managed OAuth、one-click upgrades、自動更新過舊 Cloud instances。 | workflow 設計、credentials hygiene、user access、2FA/SSO 設定、execution data 管理、版本測試與 release notes 判讀。 | Cloud 不是把所有安全責任交給 n8n;你的 workflow 仍可外洩資料或誤用 credentials。 |
| local only | 幾乎沒有公開 ingress;主要由本機 Docker/Desktop 與 OS 提供隔離。 | 本機帳號、Docker Desktop、volume、credentials、.env、backup、版本更新。 | local only 不代表不需要 security,只是 attack surface 比 public instance 小。 |
| local tunnel | tunnel 服務提供暫時 public URL。 | 所有 n8n security、webhook exposure、credentials、版本更新、log review、關閉 tunnel。 | n8n 官方 tunnel 是 local development/testing,不安全於 production。 |
| 架構 | 平台承擔 | 使用者仍要承擔 | 不可誤解 |
|---|---|---|---|
| VPS + Docker Compose + Caddy | VPS provider 提供 VM 與網路;Caddy 可處理 reverse proxy/HTTPS;Docker 提供 container packaging。 | OS patch、firewall、Docker update、n8n update、PostgreSQL、backup/restore、Caddy config、secrets、users、2FA、audit、monitoring。 | 80/443 開出去後,安全責任大部分都在你身上。 |
| PaaS | 平台通常處理 deploy、TLS、custom domain、logs、部分 secrets UI、managed PostgreSQL 選項。 | state persistence、env vars、database backup、n8n version、user access、2FA/SSO、public URL、cost、vendor limits。 | 服務能啟動不代表 state、安全設定、update cadence 正確。 |
| hyperscaler | Cloud Run/AWS 等提供 IAM、managed DB、secret manager、load balancer、logs、metrics、network controls。 | IAM least privilege、service account、security groups、secret scope、patch cadence、image pinning、backup/restore、incident response、cost controls。 | building blocks 強大,但組裝錯就是更大的 attack surface。 |
| 責任 | Cloud | local | tunnel | VPS | PaaS | hyperscaler |
|---|---|---|---|---|---|---|
| HTTPS-only | Cloud 平台處理大多數 ingress | 通常不公開 | 暫時 URL,不做 production | Caddy/proxy/firewall | 平台或自訂 domain | LB/Cloud Run/ALB/API Gateway |
| n8n upgrade | Cloud dashboard + 自動更新政策 | 使用者 | 使用者 | 使用者 | 使用者或平台 image | 使用者 image/revision/task |
| user management | 使用者 | 使用者 | 使用者 | 使用者 | 使用者 | 使用者 |
| 2FA/SSO | 使用者設定 | 使用者設定 | 使用者設定 | 使用者設定 | 使用者設定 | 使用者設定 |
| SMTP/invite/password reset | Cloud 或使用者設定依方案 | 使用者 | 使用者 | 使用者 | 使用者 | 使用者 |
| secrets | Cloud features + 使用者治理 | .env/password manager | .env/password manager | .env/secret store | platform secrets | Secret Manager/Secrets Manager |
| backup/restore | 依 Cloud plan 與 export 能力 | 使用者 | 使用者 | 使用者 | 使用者確認 | 使用者設計 |
| audit/monitoring | Cloud 提供部分能力 | 使用者 | 使用者 | 使用者 | 平台 + 使用者 | Cloud logs + 使用者 |
越接近 Cloud,平台承擔越多 infrastructure;越接近 VPS/hyperscaler,你得到越多控制權,也接手更多 patch、user lifecycle、secret scope、backup、monitoring 與 incident response。
公開 instance 的 hardening 要把 ingress、identity、secrets、runtime、workflow、operations 放在同一張表,不要只做一個 reverse proxy 就宣稱 production-ready。
| 類別 | 檢查項 | 必要設定或證據 | 失敗時風險 |
|---|---|---|---|
| HTTPS-only | 所有 editor、webhook、OAuth callback 都走 HTTPS | WEBHOOK_URL=https://n8n.example.com/、N8N_EDITOR_BASE_URL=https://n8n.example.com/、proxy TLS 通過 | cookie、token、OAuth callback 暴露,外部 provider 指錯 URL。 |
| secure cookies | cookies 只在 HTTPS 傳送 | N8N_SECURE_COOKIE=true,N8N_SAMESITE_COOKIE=lax 或更嚴格 | session cookie 可在錯誤 transport 下暴露。 |
| reverse proxy | proxy headers 正確 | N8N_PROXY_HOPS 依實際 hops 設定,Caddy/ALB/Cloud Run headers 通過 smoke test | n8n 生成 URL、IP、redirect 判斷錯誤。 |
| owner account | Owner 不做日常 workflow 編輯 | owner 建立 member-level account 供日常使用 | owner 權限過大,誤改他人 workflow/credentials。 |
| user lifecycle | invite、remove、transfer 都有流程 | Settings > Users 清單月檢;offboarding 決定 workflow/credentials 移轉或刪除 | 離職帳號仍可登入或資料歸屬不明。 |
| SMTP | user invites/password reset 可用 | N8N_EMAIL_MODE=smtp、N8N_SMTP_HOST、N8N_SMTP_SENDER、SSL/STARTTLS | 無法安全邀請、無法 reset password,導致人工分享 invite links。 |
| 類別 | 檢查項 | 必要設定或證據 | 失敗時風險 |
|---|---|---|---|
| invite links | invite links 不從 API 暴露 | N8N_INVITE_LINKS_EMAIL_ONLY=true | 高權限或程式化存取可取得 invite URL。 |
| 2FA | 所有互動使用者啟用 MFA | N8N_MFA_ENABLED=true,Business/Enterprise 可用 N8N_MFA_ENFORCED_ENABLED=true | 密碼外洩後沒有第二層防線。 |
| SSO | 有 IdP 的組織使用 SAML/OIDC | Business/Enterprise 啟用 SSO,role provisioning 決策已記錄 | 帳號 lifecycle 與企業 IdP 脫節。 |
| secrets | credentials secrets 不散落在 workflow text 或 .env | N8N_ENCRYPTION_KEY 保存;Enterprise 使用 external secrets 或平台 secret manager | secrets 複製、外洩、旋轉困難。 |
| environment access | workflow 使用者不能任意讀 env vars | N8N_BLOCK_ENV_ACCESS_IN_NODE=true,敏感 env 改用 secret store | Code node/expression 可能讀取 secrets。 |
| file access | 限制 workflow 讀寫檔案 | N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES=true,N8N_RESTRICT_FILE_ACCESS_TO | workflow 可碰到不該碰的 host/container 檔案。 |
| 類別 | 檢查項 | 必要設定或證據 | 失敗時風險 |
|---|---|---|---|
| SSRF | HTTP 類 nodes 不可打 metadata/internal ranges | N8N_SSRF_PROTECTION_ENABLED=true,blocked ranges 包含 default | workflow 可探測內網或 cloud metadata service。 |
| public API | 不用就關閉 | N8N_PUBLIC_API_DISABLED=true,N8N_PUBLIC_API_SWAGGERUI_DISABLED=true | 暴露不必要的管理 API surface。 |
| risky nodes | 高風險 nodes 要封鎖或限縮 | NODES_EXCLUDE 至少包含 n8n-nodes-base.executeCommand 與不信任的自訂風險 nodes | workflow 可在 host/container 執行命令或碰 filesystem。 |
| community nodes | 不信任供應鏈時停用或只允許 verified | N8N_COMMUNITY_PACKAGES_ENABLED=false 或 N8N_UNVERIFIED_PACKAGES_ENABLED=false | 安裝來自 npm 的未驗證程式碼。 |
| audit | 定期跑 n8n audit | n8n audit 或 API audit,記錄 credentials、database、filesystem、nodes、instance findings | unprotected webhooks、missing security settings、outdated instance 不被看見。 |
| execution data | 敏感 output 不長期保存 | redact execution data、成功 execution retention、manual execution discipline | logs/executions 成為敏感資料倉庫。 |
| 類別 | 檢查項 | 必要設定或證據 | 失敗時風險 |
|---|---|---|---|
| backup | security change 前可還原 | Week 14 backup + restore drill 通過 | patch 失敗或帳號誤刪後不能回復。 |
| patch cadence | public instance aggressive update | 每週 release note triage;critical 24 到 48 小時;high 7 天內;routine 至少每月 | 公開安全邊界長期停在舊漏洞面。 |
| monitoring | 登入、errors、restart、audit findings 可追蹤 | logs、alerts、failed execution rate、restart count、HTTP 5xx | 攻擊、錯誤、版本問題無人發現。 |
| data ownership | user/project/workflow/credential ownership 清楚 | project roles、account type、offboarding checklist | credentials 留在個人帳號,無法交接。 |
| webhook exposure | public webhooks 經過 authentication 或 secret path | random path、shared secret、HMAC、provider signature、rate limit | webhook 被猜測、濫用或重放。 |
| change record | 安全設定有版本紀錄 | .env/compose/proxy config in Git or encrypted change log | 設定漂移後無法復原。 |
| 序號 | 原則 |
|---|---|
| 1 | 每週檢查 n8n release notes、Docker image、OS packages、reverse proxy、database、PaaS/hyperscaler runtime。 |
| 2 | 每月至少完成一次 n8n stable update 或明確記錄為何不更新。 |
| 3 | security-related release、authentication、SSRF、API、webhook、credentials、community nodes、risky nodes、sandbox、dependency CVE 相關修補,不能等到功能更新窗口。 |
| 4 | critical public exposure 風險在 24 到 48 小時內處理;high 風險 7 天內處理;routine stable update 30 天內處理。 |
| 5 | 每次更新都走 Week 14 流程:backup、restore drill、image pinning、pull、restart、test、rollback。 |
公開 instance 不更新就是安全邊界破洞,升級不是只有新功能。更新也包含 bug fixes、security hardening、dependency fixes、permission model changes、SSRF/identity/API/node safety improvements。
| 風險級別 | 例子 | SLA | 必要動作 |
|---|---|---|---|
| Critical | public auth bypass、RCE、SSRF to cloud metadata、credential leakage、actively exploited CVE | 24 到 48 小時 | 緊急 maintenance window、backup、restore drill、patch、smoke test、監控、事後紀錄。 |
| High | webhook/API/security hardening bug、dependency security fix、risky node sandbox fix、cookie/session fix | 7 天內 | staging 或 restore drill project 測試,production 更新,security audit。 |
| Medium | minor security improvement、new policy setting、community package supply-chain improvement | 14 天內 | 排入本週或下週更新批次,確認設定是否需要變更。 |
| Routine | feature release、bug fixes、performance fixes | 30 天內 | 至少每月更新,避免跨太多版本造成 disruptive update。 |
| Deferred | 與部署無關或明確有重大相容性風險 | 每週重新評估 | 記錄 deferred reason、owner、next review date、mitigation。 |
公開 instance 不更新就是安全邊界破洞,升級不是只有新功能。原因是 public n8n 同時暴露 editor login、webhooks、API、OAuth callbacks、execution data、credentials usage、nodes that call external systems、possibly community code。
更新不只帶來新節點或 UI 改善,也會包含 bug fixes、security hardening、dependency fixes、permission model changes、SSRF/identity/API/node safety improvements。越久不更新,公開邊界與現行威脅之間的距離越大。
n8n Cloud 替你收掉 infrastructure maintenance、uptime monitoring、managed OAuth、one-click upgrades 等基礎工作。你仍要管理 users、2FA/SSO、workflow sharing、credentials、execution data、release timing、workflow security。Cloud 讓責任少很多,但不會替你判斷某個 workflow 是否把 customer data 發錯 API,也不會替你完成每個 user offboarding 決策。
local n8n 的 public exposure 最小,但資料和 secrets 都在本機。你要保護 Docker Desktop、volume、.env、N8N_ENCRYPTION_KEY、local credentials、backup。local 適合 learning、prototype、private automation,不適合作為未 harden 的公開服務。
tunnel 只適合 local development/testing。它能快速讓 webhook provider 打到本機,但它不是 production boundary。若 tunnel URL 被外部知道,你仍承擔 n8n login、webhook path、credentials、workflow behavior、版本更新與關閉 tunnel 的責任。
VPS 是最直覺的 self-host production 起點,也是責任最容易被低估的地方。OS patch、firewall、Docker、Caddy、PostgreSQL、n8n image、volume、backup、logs、users、2FA、SMTP、SSRF、API、nodes 都要自己管。這也是為什麼 Week 10 到 Week 15 一路要求 Caddy、PostgreSQL、backup、restore、update、hardening 連成一套。
PaaS 會替你處理 deploy、TLS、custom domain、logs、secrets UI、managed database 的一部分,但 n8n state、environment variables、backup/restore、user management、2FA/SSO、image tag、patch cadence 還是你的工作。PaaS 省掉一些主機維運,不會自動讓公開 instance 安全。
hyperscaler 給你 IAM、service account、Secret Manager/Secrets Manager、managed database、load balancer、CloudWatch/Cloud Logging、VPC/security group 等 building blocks。它讓安全治理更可控,也讓錯誤配置更危險。你的責任變成 least privilege、secret scope、network boundaries、image pinning、audit logs、cost guardrails、patch cadence、incident response。
| 步驟 | 公開 instance hardening runbook |
|---|---|
| 1 | 確認 hosting model:Cloud、local、tunnel、VPS、PaaS、hyperscaler。 |
| 2 | 若是 tunnel,標記為 development/testing,不進 production checklist。 |
| 3 | 設 HTTPS-only:WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_PROXY_HOPS、proxy TLS、secure redirect。 |
| 4 | 設 cookies:N8N_SECURE_COOKIE=true,N8N_SAMESITE_COOKIE=lax 或更嚴格。 |
| 5 | 設 user management:Owner/Admin/Member 最小權限,owner 日常使用 member account。 |
| 6 | 設 SMTP:N8N_EMAIL_MODE=smtp、N8N_SMTP_HOST、N8N_SMTP_SENDER、SSL/STARTTLS。 |
| 7 | 設 invite 安全:N8N_INVITE_LINKS_EMAIL_ONLY=true。 |
| 8 | 設 MFA:N8N_MFA_ENABLED=true,可用 policy 時啟用 N8N_MFA_ENFORCED_ENABLED=true。 |
| 9 | 有企業 IdP 時設定 SAML/OIDC SSO,並記錄 role provisioning 與手動登入例外。 |
| 10 | 設 secrets:固定 N8N_ENCRYPTION_KEY,優先用 secret manager 或 external secrets,不把 secrets 寫進 workflow text。 |
| 步驟 | 公開 instance hardening runbook |
|---|---|
| 11 | 限制 env/file access:N8N_BLOCK_ENV_ACCESS_IN_NODE=true、N8N_BLOCK_FILE_ACCESS_TO_N8N_FILES=true、N8N_RESTRICT_FILE_ACCESS_TO。 |
| 12 | 啟用 SSRF protection:N8N_SSRF_PROTECTION_ENABLED=true,使用 default blocked ranges,再加上組織內網範圍。 |
| 13 | 若不用 public REST API,設定 N8N_PUBLIC_API_DISABLED=true 與 N8N_PUBLIC_API_SWAGGERUI_DISABLED=true。 |
| 14 | 封鎖 risky nodes:用 NODES_EXCLUDE 管理 executeCommand、local file 類 nodes 與任何不信任的自訂高風險 node。 |
| 15 | 控制 community nodes:不需要時停用;需要時只允許 verified 或固定版本與 checksum。 |
| 16 | 設 execution data policy:敏感資料 redaction、成功 executions retention、manual execution discipline。 |
| 17 | 跑 security audit:n8n audit,把 credentials、database、filesystem、nodes、instance findings 轉成 action items。 |
| 18 | 接上 Week 14:backup、restore drill、image pinning、smoke test、rollback。 |
| 19 | 接上 monitoring:HTTP 5xx、login anomalies、failed executions、restart count、audit findings、outdated version。 |
| 20 | 接上 patch cadence:每週 triage,每月 update,critical/high security 依 SLA 處理。 |
每週固定一天檢查 release notes、image、host packages、platform runtime 與 audit findings。這不是形式作業,而是讓 public edge 不落後於安全修補。
| 項目 | 證據 |
|---|---|
| n8n release notes | 目標版本、目前版本、跳過版本、breaking changes、security relevance。 |
| Docker image | pinned tag、digest、是否有 base image 或 dependency risk。 |
| OS/packages | VPS host patch、Docker Engine/Compose、Caddy、PostgreSQL patch。 |
| platform | PaaS/hyperscaler runtime、managed database、secret manager、load balancer updates。 |
| audit | n8n audit findings,尤其 outdated instance、missing security settings、risky nodes。 |
若沒有 critical/high security update,公開 instance 仍要每月至少更新一次或記錄延後理由。官方 self-host update guidance 建議至少每月更新,因為跨太多版本會提高 disruptive update 風險。對 public instance,月更是最低線,不是最佳線。
若 release note、security advisory、dependency CVE、node sandbox、auth/session、SSRF、API、webhook、credential handling 相關修補出現,直接啟動 emergency patch。
| 步驟 | emergency patch 動作 |
|---|---|
| 1 | 宣告 change window。 |
| 2 | 執行 Week 14 backup。 |
| 3 | 在 restore drill/staging project 測 target image。 |
| 4 | 更新 production pinned image。 |
| 5 | 跑 smoke tests:login、credentials decrypt、workflow list、manual execution、webhook、proxy、logs、monitoring。 |
| 6 | 若失敗,先 rollback;若 DB migration 已不可逆,走 full restore。 |
| 7 | 記錄版本、digest、backup id、測試結果、SLA 是否達成。 |
emergency patch 仍然要經過 Week 14 的 recovery gate。快,不等於跳過 backup;快,是把 backup、restore drill、smoke test、rollback 做成固定肌肉記憶。
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 security responsibility matrix | 通過 | 第 15.3、15.6 節與 week-15-security-responsibility-matrix.json |
| 完成 public exposure hardening checklist | 通過 | 第 15.4、15.7 節與 week-15-public-exposure-hardening-checklist.csv |
| 完成 patch cadence policy | 通過 | 第 15.5、15.8 節與 week-15-patch-cadence-policy.json |
| 覆蓋 Cloud/local/tunnel/VPS/PaaS/hyperscaler 責任分界 | 通過 | 第 15.3、15.6 節 |
| 覆蓋 HTTPS-only、secure cookies、SMTP/user management、2FA、SSO、secrets | 通過 | 第 15.4、15.7 節 |
| 覆蓋 2026 之後 public instance 的 aggressively update 原則 | 通過 | 第 15.5、15.8 節 |
| 能明確說出公開 instance 不更新就是安全邊界破洞,升級不是只有新功能 | 通過 | 第 15.1、15.5、15.9 節 |
Week 16 會進入 Scaling:單機、Redis queue、workers。Week 15 已定義公開 instance 的安全與 patch cadence,下一週要在這條安全基線上拆解 scaling:regular mode、Redis queue、workers、concurrency、webhook response、DB connections、worker separation 與 queue-mode security boundaries。
Week 15 的成果,是把 public n8n 的安全責任具體化:平台選型只決定誰負責哪一層,不能消除 user lifecycle、secrets、SSRF、risky nodes、audit、backup、monitoring 與 patch cadence。公開 instance 不更新,就是安全邊界停在舊世界。
16.0 本週定位
執行日期:2026-05-28。本週目標是回答何時該加大單機,何時該上 queue mode,何時才值得 Kubernetes。Week 15 的結論是公開 instance 的安全邊界要靠 hardening 與 patch cadence 維持;Week 16 把 scaling 放在這條安全基線上處理。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| scaling ladder | 完成 | artifacts/week-16-scaling/week-16-scaling-ladder.json;本章 16.3 |
| queue mode architecture diagram | 完成 | artifacts/week-16-scaling/week-16-queue-mode-architecture.json;本章 16.4 |
| anti-overengineering checklist | 完成 | artifacts/week-16-scaling/week-16-anti-overengineering-checklist.csv;本章 16.5 |
| single instance first | 完成 | 本章 16.3、16.6 |
| PostgreSQL first | 完成 | 本章 16.3、16.6 |
| Redis queue mode 與 workers | 完成 | 本章 16.4、16.7 |
| separate webhook processors、managed DB/Redis、centralized logs | 完成 | 本章 16.4、16.7、16.8 |
| Week 16 驗證腳本 | 完成 | scripts/verify-week-sixteen.mjs |
Scaling 不是「一看到慢就拆服務」。先讓單機和 PostgreSQL 正確,再看 concurrency、execution data、binary data、logs、backup、worker pool。Kubernetes 是成熟後的承載方式,不是最小 production 起點。
整合來源:docs/week-16-scaling-single-queue-workers.md
331| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Scaling overview | Scaling overview | n8n 官方說大量 users、workflows、executions 時需要調整配置;queue mode 提供最佳 scalability,execution data/pruning 也影響 database performance。 |
| Queue mode | Queue mode | queue mode 使用 main instance、Redis message broker、workers、PostgreSQL;main 產生 execution,Redis 排隊,worker 從 DB 取 workflow information,完成後寫回 DB 並通知 Redis。 |
| Queue mode env vars | Queue mode env vars | EXECUTIONS_MODE=queue、QUEUE_BULL_REDIS_HOST、QUEUE_BULL_REDIS_PORT、OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS、N8N_MULTI_MAIN_SETUP_ENABLED 等設定決定 queue mode 行為。 |
| Concurrency control | Concurrency control | regular mode 預設不限制 production executions;可用 N8N_CONCURRENCY_PRODUCTION_LIMIT 控制 production concurrency;queue mode 的 worker concurrency 是另一層機制。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Execution data | Execution data | execution data 保存與 pruning 會影響 database size/performance;scale 前應先確認是否保存太多成功 execution data。 |
| Binary data | Binary data | binary data 預設在 memory;queue mode 不支援 filesystem binary data,需改 database 或 S3 external storage。 |
| External storage | External storage | Enterprise 可用 S3 作為 binary data external storage,避免大量 binary data 依賴 local filesystem。 |
| Prometheus metrics | Prometheus metrics | N8N_METRICS=true 可啟用 metrics;queue metrics 可追蹤 active、completed、failed、waiting jobs,main 與 workers 都可暴露 metrics。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Monitoring | Monitoring | production scaling 要看 health、metrics、queue、worker 與 process 指標,而不是只看容器是否 running。 |
| Logging | Logging | 多 process/multi-worker deployment 需要 centralized logs;只有本機 stdout 會讓 worker 問題難以追蹤。 |
| Task runners | Task runners | production task runners 建議 external mode;queue mode 下每個 worker 需要自己的 task runner sidecar。 |
| Execute Command | Execute Command | queue mode 下 production Execute Command 會在執行任務的 worker 上跑;manual execution 除非 offload,否則在 main 上跑。 |
| Kubernetes/OpenShift example | OpenShift example | n8n 的 OpenShift/Kubernetes 範例使用 shared database、message queue、object storage、worker pods、webhook processors、multi-main;這證明 Kubernetes 是多組件成熟後的承載方式,不是最小 production 起點。 |
先 single instance first,再 PostgreSQL first,然後用 metrics 判斷是否加大單機、設定 regular concurrency、清 execution data、移 binary data;只有當 worker separation 和 queue backlog 是真瓶頸,才進 Redis queue mode 與 workers。
| 階段 | 架構 | 進入條件 | 主要設定 | 不要跳過的檢查 |
|---|---|---|---|---|
| 0 | local / learning single container | 學習、demo、低風險 manual workflow | SQLite 或 local volume,沒有 public production webhook | 不放 business-critical credentials,不公開 tunnel 當 production。 |
| 1 | single container + PostgreSQL | workflow 開始承載真資料,需要 durable state | DB_TYPE=postgresdb、固定 N8N_ENCRYPTION_KEY、backup/restore | PostgreSQL backup、volume、env/proxy config 保存。 |
| 2 | larger single instance + PostgreSQL | CPU/memory 偶爾尖峰,但瓶頸仍可由單機處理 | 4 vCPU / 8 GB RAM 起,N8N_CONCURRENCY_PRODUCTION_LIMIT,execution pruning | p95 latency、memory high-water mark、DB growth、binary storage。 |
| 3 | single instance + managed PostgreSQL/Redis-ready observability | workload 穩定成長,需要先把 state/monitoring 做穩 | managed PostgreSQL、centralized logs、Prometheus metrics、alerts | 先證明 DB/backup/logs 可營運,再加 workers。 |
| 階段 | 架構 | 進入條件 | 主要設定 | 不要跳過的檢查 |
|---|---|---|---|---|
| 4 | Redis queue mode + workers | production executions 重疊且單機 event loop 或 webhook response 被重任務拖慢 | EXECUTIONS_MODE=queue、Redis、workers、shared N8N_ENCRYPTION_KEY、worker --concurrency | Redis/DB readiness、worker health、DB connection pool、binary data mode。 |
| 5 | separate webhook processors + worker pools | webhook burst 是入口瓶頸,需要獨立接收 webhook | webhook processors、load balancer route /webhook/* 與 /webhook-waiting/*,N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true | main 不進 webhook LB pool,manual /webhook-test/* route 回 main。 |
| 6 | managed DB/Redis + centralized logs + multi-main evaluation | queue mode 已是核心生產架構,需要 HA 與操作治理 | managed PostgreSQL、managed Redis、centralized logs、metrics、backups、multi-main eligibility | all main/worker same version、sticky sessions、leader/follower 行為、cost。 |
| 7 | Kubernetes / OpenShift / EKS style orchestration | 需要 pod scheduling、replicas、rolling deploy、worker autoscaling、standard platform ops | main pods、worker pods、webhook processor pods、DB/Redis/object storage、Ingress/LB、secrets、logs | 沒有 platform skill、DB/Redis/logs/backup 成熟前,不進 Kubernetes。 |
| 序號 | 驗收路線 |
|---|---|
| 1 | single container + Postgres:n8n + PostgreSQL + persistent volume + fixed N8N_ENCRYPTION_KEY + backup。 |
| 2 | larger single instance + Postgres:先加 CPU/RAM、設定 N8N_CONCURRENCY_PRODUCTION_LIMIT、修 pruning 與 binary data。 |
| 3 | observability first:啟用 logs/metrics,確認 p95 latency、memory、DB connections、execution failures、binary storage。 |
| 4 | Redis queue mode + workers:加 Redis,把 production executions 丟給 workers,main 保持 UI/triggers/webhook coordination。 |
| 5 | separate webhook processors:入口流量高時再把 webhook processors 與 load balancer routing 拆出來。 |
| 6 | managed DB/Redis + centralized logs:把 state、queue、logs、backup 變成可營運服務。 |
| 7 | Kubernetes:只有當你需要 replicas、rolling updates、worker autoscaling、pod scheduling、multi-service platform governance 時才進。 |
合理路線是先把 durable state、recovery、observability 做好,再讓 queue mode 接手 execution 壓力。Kubernetes 不是為了顯得正式,而是為了解決已被證明存在的 orchestration 問題。
| Process | 責任 | 關鍵設定 |
|---|---|---|
| main | UI、API、trigger coordination、execution creation、non-HTTP triggers、pruning;queue mode 時不直接跑 production execution。 | EXECUTIONS_MODE=queue、N8N_ENCRYPTION_KEY、PostgreSQL env vars、Redis env vars。 |
| Redis | message broker,保存 pending executions queue,讓可用 worker 取 job。 | QUEUE_BULL_REDIS_HOST、QUEUE_BULL_REDIS_PORT、username/password/db/timeout。 |
| worker | 從 Redis 取 execution ID,從 PostgreSQL 讀 workflow information,執行後寫結果回 PostgreSQL,通知 Redis。 | EXECUTIONS_MODE=queue、shared N8N_ENCRYPTION_KEY、DB/Redis access、n8n worker --concurrency=5 起測。 |
| webhook processor | optional scaling layer,接大量 webhook request,送 execution 到 Redis;不把 main 放進 webhook pool。 | EXECUTIONS_MODE=queue、WEBHOOK_URL、load balancer route /webhook/*、/webhook-waiting/*。 |
| Process | 責任 | 關鍵設定 |
|---|---|---|
| PostgreSQL | durable state:workflows、credentials、executions、users、settings。 | Postgres 13+、connection pool、backup/restore、execution pruning。 |
| binary storage | queue mode 不使用 filesystem binary data;改 database 或 S3 external storage。 | N8N_DEFAULT_BINARY_DATA_MODE=database 或 s3;S3 lifecycle。 |
| centralized logs/metrics | 對 main、webhook processors、workers、Redis、DB 進行 observability。 | N8N_METRICS=true、N8N_METRICS_INCLUDE_QUEUE_METRICS=true、集中 logs、alerts。 |
| 順序 | 動作 |
|---|---|
| 1 | Main 在 PostgreSQL 建立 execution record。 |
| 2 | Main 把 execution ID enqueue 到 Redis。 |
| 3 | Worker 從 Redis claim next job。 |
| 4 | Worker 從 PostgreSQL 載入 workflow and credentials metadata。 |
| 5 | Worker 執行 workflow。 |
| 6 | Worker 把 result and status 寫回 PostgreSQL。 |
| 7 | Worker 在 Redis publish completion。 |
| 8 | Redis 通知 Main completion。 |
| 9 | Main 與 Worker 都把 logs/metrics 暴露給 centralized observability。 |
| Route | 目標 |
|---|---|
/webhook/* | webhook processor pool |
/webhook-waiting/* | webhook processor pool |
/webhook-test/* | main process,用於 manual/test executions |
| editor static files、internal API、settings | main process |
n8n 官方提醒不建議把 main process 加進 webhook load balancer pool。若 main 同時承接大量 webhook,UI、API、trigger coordination 會被入口流量拖慢。當你已有 webhook processors 時,可以用 N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true 讓 production webhooks 不在 main process 上處理。
| 問題 | 若答案是否定 | 若答案是肯定 |
|---|---|---|
| 是否已經使用 PostgreSQL,而不是仍在 SQLite/local-only state? | 不上 Redis、不上 Kubernetes,先做 PostgreSQL。 | 繼續看 execution volume。 |
| 是否已做 backup/restore drill? | 不上多節點,先完成 Week 14。 | 繼續看 metrics。 |
| 是否知道 p95 execution latency、active executions、failed executions、DB connections? | 不上 Kubernetes,先啟用 logs/metrics。 | 繼續看瓶頸層。 |
| 問題是 CPU/RAM 偶發尖峰,而不是持續 queue/backlog? | 先加大單機、降 concurrency、修 workflow。 | 可評估 workers。 |
| 問題 | 若答案是否定 | 若答案是肯定 |
|---|---|---|
是否已設定 N8N_CONCURRENCY_PRODUCTION_LIMIT? | 先用 regular mode concurrency control。 | 看是否仍有 event loop thrash。 |
| execution data 或 binary data 是否造成 DB/storage 壓力? | 先調 retention、pruning、binary mode。 | 若重任務仍拖慢,再加 workers。 |
| webhook burst 是否拖慢 editor/UI? | 不拆 webhook processors,先觀察。 | 可拆 webhook processors 與 LB route。 |
| 是否有 Redis、PostgreSQL、workers 的 health/readiness 與 centralized logs? | 不上 Kubernetes,先補 observability。 | 可進 queue mode production。 |
| 問題 | 若答案是否定 | 若答案是肯定 |
|---|---|---|
| 是否已有 managed DB/Redis 或能營運自管 DB/Redis? | 不上 Kubernetes,否則 state/queue 會成為事故點。 | 可評估 orchestration。 |
| 是否需要 rolling deploy、worker autoscaling、pod scheduling、multi-service governance? | 不上 Kubernetes,VPS/PaaS/queue workers 足夠。 | Kubernetes 開始有理由。 |
| 團隊是否能 debug Redis queue、DB connection pool、worker logs、LB routing? | 不上 Kubernetes,先練 queue mode runbook。 | 可建立 Kubernetes spike。 |
| 是否能接受 Kubernetes 的成本與維運責任? | 不上 Kubernetes,避免把小系統變成平台工程。 | 用 staging 先驗證。 |
| category | question | evidence_required | decision |
|---|---|---|---|
| state | Are workflows and credentials already on PostgreSQL instead of SQLite? | DB_TYPE=postgresdb and restore drill evidence | PostgreSQL first |
| recovery | Has Week 14 backup and restore drill passed? | Backup ID and restore drill result | Recovery before scale |
| observability | Do you know p95 latency, failed executions, active executions, memory, CPU, DB storage, and DB connections? | Dashboard or metric export | Observe before scale |
| regular_mode | Have you tried N8N_CONCURRENCY_PRODUCTION_LIMIT in regular mode? | Configured limit and execution queue behavior | Tune single instance first |
| single_instance | Is pressure only occasional CPU or memory spike? | CPU and memory trend | Scale up before scale out |
| category | question | evidence_required | decision |
|---|---|---|---|
| execution_data | Is database growth caused by execution data retention? | Execution data settings and DB growth chart | Fix data policy first |
| binary_data | Is binary data mode queue-compatible? | N8N_DEFAULT_BINARY_DATA_MODE value | Binary mode before workers |
| webhook_latency | Are heavy executions slowing webhook response or editor/API responsiveness? | Webhook p95 and editor/API latency | Separate only real bottlenecks |
| redis_readiness | Can Redis be monitored, backed up when relevant, patched, and secured? | Redis health, auth, metrics, alerting | Redis readiness |
| db_connections | Can PostgreSQL handle worker concurrency and connection count? | DB connection pool and max connections | DB capacity gates workers |
| category | question | evidence_required | decision |
|---|---|---|---|
| worker_logs | Will worker logs and metrics be centralized? | Central log sink and worker metrics | Logs before distributed execution |
| webhook_processors | Is webhook ingress volume the bottleneck after queue mode? | Route map and webhook p95 | Ingress split only when needed |
| load_balancer | Can load balancer route /webhook/*, /webhook-waiting/*, and /webhook-test/* correctly? | LB route tests | Route correctness |
| managed_state | Are DB and Redis managed or operated with mature runbooks? | Managed service configs or runbooks | State operations first |
| centralized_logs | Are main, webhook processors, workers, Redis, DB, and LB logs centralized? | Log source list and alert rules | Central logs before Kubernetes |
| category | question | evidence_required | decision |
|---|---|---|---|
| team_skill | Can the team debug Redis queue, worker backlog, DB pool exhaustion, and LB routing? | Runbook exercise results | Skill before platform |
| kubernetes_need | Do you need rolling deploys, pod scheduling, worker autoscaling, and platform governance? | Written platform requirement | Kubernetes last |
| cost | Can the team explain the cost and on-call burden of Kubernetes? | Cost estimate and on-call owner | Cost is part of architecture |
| security | Does scaling preserve Week 15 hardening and patch cadence? | Hardening checklist and patch policy | Security boundary travels with scale |
| acceptance | Can you describe a path from single container + Postgres to Redis workers without starting with Kubernetes? | Documented ladder and runbook | Gradual route accepted |
single instance first 的意思不是永遠單機,而是先把最少 moving parts 做對。大多數 early production n8n 問題不是 Kubernetes 不夠,而是 state、資料保留、binary data、webhook response、backup、logs 或 patch cadence 還沒有做好。
| 問題 | 應先處理 |
|---|---|
| workflow 保存太多 execution data | execution data pruning、成功 execution 不保存、DB storage monitoring。 |
| binary data 讓 memory 爆掉 | filesystem/database/S3 mode,限制檔案大小,避免 default memory mode。 |
| webhook response 慢 | workflow 拆分、早回應、concurrency limit、background processing。 |
| DB 未備份 | PostgreSQL backup、restore drill、RPO/RTO。 |
| logs 看不到 | centralized logs、metrics、alerts。 |
| 公開 instance 太舊 | Week 15 patch cadence。 |
PostgreSQL first 是進 queue mode 的前置條件。官方 queue mode 文件說分散式 queue setup 不支援 SQLite,並建議 Postgres 13+。PostgreSQL 讓 workflows、credentials、executions、users、settings 有 durable state,也讓 workers 可以共享 execution state。若還沒把 database 做穩,就先上 Redis workers,只會把資料層問題放大。
不適合 distributed queue。
workers 能共享 execution state。
建立在穩定 DB 之上。
| 順序 | 單機升級動作 |
|---|---|
| 1 | 固定 N8N_ENCRYPTION_KEY。 |
| 2 | 使用 PostgreSQL。 |
| 3 | 設 WEBHOOK_URL 與 N8N_EDITOR_BASE_URL。 |
| 4 | 設 backup/restore drill。 |
| 5 | 開 logs 與 metrics。 |
| 6 | 調整 execution pruning。 |
| 7 | 設 N8N_CONCURRENCY_PRODUCTION_LIMIT。 |
| 8 | 增加 vCPU/RAM。 |
| 9 | 移除重 workflow 的同步 webhook 路徑。 |
| 10 | 用 metrics 判斷是否真的需要 queue mode。 |
| 訊號 | 解讀 |
|---|---|
| production executions 長時間重疊,regular mode concurrency control 造成等待但仍可觀察到 backlog | 需要 worker pool。 |
| 重 workflow 拖慢 editor/UI 或 webhook response | 需要把 execution 從 main 拆到 workers。 |
| CPU/memory 壓力來自 execution,而不是 UI/API | workers 可以水平擴充。 |
| 已有 PostgreSQL、Redis、centralized logs、backup/restore | queue mode 的 state/queue/logs 基礎已具備。 |
| binary data 已改 database/S3,不依賴 local filesystem mode | 符合 queue mode binary data 限制。 |
| 設定 | baseline |
|---|---|
| Execution mode | EXECUTIONS_MODE=queue 用在 main、workers、webhook processors。 |
| Redis | QUEUE_BULL_REDIS_HOST、QUEUE_BULL_REDIS_PORT、username/password/db/timeout。 |
| Encryption key | main、workers、webhook processors 使用同一個 N8N_ENCRYPTION_KEY。 |
| Worker command | n8n worker --concurrency=5 起測,官方建議 worker concurrency 5 或更高,避免低 concurrency + 大量 workers 耗盡 DB connections。 |
| Worker health | 啟用 worker health/readiness endpoints,確認 DB/Redis ready。 |
| Metrics | N8N_METRICS=true、N8N_METRICS_INCLUDE_QUEUE_METRICS=true。 |
| Binary data | N8N_DEFAULT_BINARY_DATA_MODE=database 或 S3;不使用 filesystem mode。 |
| Task runners | queue mode 下每個 worker 需要自己的 task runner sidecar。 |
| 情境 | 更合理的處理 |
|---|---|
| 只有一兩條慢 workflow | 拆 workflow、優化 API calls、加 timeout/retry、把大檔分批。 |
| DB storage 成長太快 | 先調 execution retention、pruning、binary storage。 |
| webhook response 只是需要立即回覆 | 使用 Respond to Webhook/早回應模式或拆 background workflow。 |
| memory 爆是 binary data default mode | 先改 binary mode。 |
| 沒有 centralized logs | 先補 logs,否則 workers 只會讓故障更分散。 |
workers 可以分散 execution 壓力,但不能替你修掉爛 workflow、過大的 execution history、錯誤 binary mode 或看不到 logs 的維運盲點。
webhook processors 是 queue mode 的下一層 scaling。當入口 webhook burst 很高時,webhook processors 可以把接收 request 的工作從 main 拆出去。load balancer 要把 /webhook/*、/webhook-waiting/* 送到 webhook processor pool,把 editor、internal API、settings、manual /webhook-test/* 留給 main。
webhook processor pool
webhook processor pool
main process
main process
一旦 Redis queue mode 變成 production path,PostgreSQL 與 Redis 不再是附屬元件,而是主系統。managed DB/Redis 的價值不是品牌,而是 backup、restore、metrics、patch、availability、access control、connection limits、alerting。如果團隊選擇自管,也要有同等的 runbook。
多 workers 之後,本機 container logs 已不足以定位問題。至少要集中 main、webhook processors、workers、Redis、PostgreSQL、load balancer 的 logs。
| Log source | 必看內容 |
|---|---|
| main | trigger、API、UI、pruning、queue enqueue、Redis notification。 |
| webhook processors | request volume、route、HTTP status、latency。 |
| workers | execution start/end、node errors、memory、timeouts、Execute Command location。 |
| Redis | connectivity、timeout、queue pressure、restarts。 |
| PostgreSQL | connection count、slow queries、storage、backup。 |
| load balancer | route mapping、5xx、timeout、sticky/session behavior。 |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 scaling ladder | 通過 | 第 16.3 節與 week-16-scaling-ladder.json |
| 完成 queue mode architecture diagram | 通過 | 第 16.4 節與 week-16-queue-mode-architecture.json |
| 完成 anti-overengineering checklist | 通過 | 第 16.5 節與 week-16-anti-overengineering-checklist.csv |
| 覆蓋 single instance first | 通過 | 第 16.3、16.6 節 |
| 覆蓋 PostgreSQL first | 通過 | 第 16.3、16.6 節 |
| 覆蓋 Redis queue mode 與 workers | 通過 | 第 16.4、16.7 節 |
| 覆蓋 separate webhook processors、managed DB/Redis、centralized logs | 通過 | 第 16.4、16.8 節 |
| 提出 single container + Postgres 到 Redis workers 漸進路線 | 通過 | 第 16.3 節「驗收路線」 |
| 避免一開始就上 Kubernetes | 通過 | 第 16.3、16.5、16.8 節 |
Week 17 會進入故障排除演練。Week 16 已經建立 single instance、PostgreSQL、queue mode、workers、webhook processors、DB/Redis/logs 的 scaling ladder,下一週要把這些元件轉成故障情境:DB down、Redis down、worker backlog、webhook 5xx、binary storage missing、memory OOM、version mismatch、load balancer route 錯誤。
Week 16 的成果,是把 scaling 變成有門檻的漸進路線:先 single container + PostgreSQL,接著加大單機與 concurrency control,再補 observability,最後才用 Redis queue mode、workers、webhook processors,Kubernetes 留給真的需要 orchestration 的階段。
17.0 本週定位
執行日期:2026-05-28。本週目標是遇到錯誤時,快速判斷是 container、DB、URL、proxy、OAuth、security 還是 resource 問題。Week 17 把前 16 週累積的部署知識轉成故障排除肌肉記憶。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| 12 張故障排除卡 | 完成 | artifacts/week-17-troubleshooting/week-17-troubleshooting-cards.json;本章 17.4 |
| log/env/DNS/proxy/DB 檢查順序 | 完成 | artifacts/week-17-troubleshooting/week-17-check-order.json;本章 17.5 |
| incident note 範本 | 完成 | artifacts/week-17-troubleshooting/week-17-incident-note-template.md;本章 17.6 |
| troubleshooting table 演練 | 完成 | 本章 17.4、17.7 |
| 常見問題第一檢查點 | 完成 | 本章 17.3、17.4、17.7 |
| 症狀轉排查流程 | 完成 | 本章 17.3、17.5 |
| Week 17 驗證腳本 | 完成 | scripts/verify-week-seventeen.mjs |
不要一開始就改 workflow、重啟所有服務或重建容器。先拿 log、env、DNS、proxy、DB 的客觀證據,避免把單一設定錯誤擴大成資料遺失、憑證失效或公開服務中斷。
整合來源:docs/week-17-troubleshooting-drills.md
361| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Webhook URL behind proxy | Webhook URL | n8n behind reverse proxy 時要手動設定 WEBHOOK_URL,並設定 N8N_PROXY_HOPS=1 與 forwarded headers,否則 editor 顯示與第三方註冊的 webhook URL 可能錯。 |
| Webhook node common issues | Webhook common issues | Test URL 和 Production URL 行為不同;production webhook 需要 workflow active;同一路徑與 HTTP method 只能有一個 webhook。 |
| Telegram trigger issue | Telegram trigger common issues | Telegram 要求 HTTPS webhook;behind proxy 時 wrong webhook URL 或 TLS 終止錯誤會造成 bad webhook。 |
| Database env vars | Database env vars | DB_TYPE=postgresdb、DB_POSTGRESDB_HOST、port、user、password、pool size、SSL 設定是 database connection failed 的第一組檢查點。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Supported databases | Supported databases | self-hosted 預設 SQLite,也可設定 PostgreSQL;production 事故要先確認實際 DB 類型與 state 位置。 |
| Logging | Logging | log level 可用 error、warn、info、debug;排查時先讀 container logs,再必要時提升到 debug。 |
| Logs env vars | Logs env vars | N8N_LOG_LEVEL、N8N_LOG_OUTPUT、N8N_LOG_FORMAT=json、DB_LOGGING_ENABLED 能讓 production incident 更可追。 |
| Monitoring | Monitoring | /healthz 只代表 instance reachable,/healthz/readiness 才能驗證 DB 已連線且 migration ready;metrics 要用 N8N_METRICS=true 啟用。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Security env vars | Security env vars | N8N_SECURE_COOKIE=true 代表 cookie 只透過 HTTPS 傳送;secure cookie error 先查 scheme、proxy headers、TLS。 |
| SSL setup | SSL setup | 官方建議用 reverse proxy 處理 TLS;也可用 N8N_SSL_CERT、N8N_SSL_KEY 讓 n8n 直接提供 HTTPS。 |
| Custom encryption key | Custom encryption key | n8n 首次啟動會生成 encryption key,credentials 依賴該 key;queue workers 也必須使用同一個 N8N_ENCRYPTION_KEY。 |
| Encryption key rotation | Encryption key rotation | rotation 是針對 data encryption key,instance N8N_ENCRYPTION_KEY 不應變更;啟用前要備份 DB,且所有 main/workers 共用同一 instance key。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Deployment env vars | Deployment env vars | N8N_EDITOR_BASE_URL、N8N_PROTOCOL、N8N_HOST、N8N_PORT、N8N_ENCRYPTION_KEY、proxy 相關 env 都會影響 URL、OAuth、cookie 與 credentials。 |
| OAuth credentials | OAuth credentials | OAuth1/OAuth2 credentials 需要把 n8n 顯示的 OAuth Redirect URL 填到外部服務;callback mismatch 先比對 redirect URI。 |
| Memory errors | Memory errors | Problem running workflow、Connection Lost、503 Service Temporarily Unavailable、heap out of memory 都可能是 resource 問題。 |
| Queue mode | Queue mode | queue mode 下 main、workers、webhook processors 要共享 DB、Redis 與 N8N_ENCRYPTION_KEY;worker 故障要分別查 Redis、DB、worker logs。 |
故障排除要先把「看到的錯誤」轉成「可能的層」。這一步會決定你先查 logs、env、DNS、proxy、DB,還是進一步看 credentials、OAuth、security、resource、queue、workflow。
| 層 | 常見症狀 | 第一檢查點 |
|---|---|---|
| container | n8n 無法打開、重啟循環、Connection refused | docker ps、docker logs、volume mount、image tag。 |
| DB | /healthz 200 但 /healthz/readiness 不是 200、startup log 有 connection failed | DB_TYPE、DB_POSTGRESDB_HOST、port、password、SSL、DB container/network。 |
| URL | webhook 或 OAuth callback 指到 localhost、舊 domain、http | WEBHOOK_URL、N8N_EDITOR_BASE_URL、editor 中顯示的 URL。 |
| proxy | IP whitelist 失準、secure cookie、websocket 卡住、502/504 | N8N_PROXY_HOPS、X-Forwarded-* headers、TLS termination、route。 |
| OAuth | provider 回傳 redirect URI mismatch、connect account 失敗 | 外部 provider redirect URI 與 n8n OAuth Redirect URL 是否完全相同。 |
| security | secure cookie error、session 不保留、public API 暴露 | N8N_SECURE_COOKIE、HTTPS、N8N_SAMESITE_COOKIE、security audit。 |
| resource | 503、Connection Lost、heap out of memory、worker backlog | CPU/RAM、binary data、execution size、worker logs、queue metrics。 |
env and DB readiness
URL, proxy, resource, workflow
URL, active workflow, redirect URI
先確認現象與最新變更,再用固定順序排除。每一步要能留下證據,否則 incident 結束後只會留下「好像修好了」的口頭印象。
| 卡片 | 症狀 | 第一檢查點 | 修復方向 |
|---|---|---|---|
| T01 wrong webhook URL | 第三方打到 localhost、舊 domain、http URL 或回傳 bad webhook | 比對 editor 顯示的 webhook URL、WEBHOOK_URL、proxy 公開 URL | 設 WEBHOOK_URL=https://n8n.example.com/,重啟 n8n,重新啟用 workflow 或重新註冊 webhook。 |
| T02 lost credentials | 重建容器或搬 DB 後 credentials 無法解密 | 確認 N8N_ENCRYPTION_KEY 是否與建立 credentials 時一致 | 還原原 instance key;若 key 遺失,從含原 key 的備份還原;不要用新 key 覆蓋 production。 |
| T03 database connection failed | startup log 顯示 DB connect failed 或 readiness 不通過 | 查 DB_TYPE=postgresdb 與 DB_POSTGRESDB_* env、DB container/network、SSL | 修正 host、port、user、password、database、SSL;確認 DB ready 後重啟 n8n。 |
| T04 secure cookie error | 瀏覽器無法登入、session 不保留、HTTP 環境 cookie 失敗 | 查外部 URL 是否 HTTPS、proxy 是否送 X-Forwarded-Proto=https、N8N_SECURE_COOKIE | production 保持 HTTPS;local 測試可明確設 N8N_SECURE_COOKIE=false,不要把此設定帶到 public production。 |
| 卡片 | 症狀 | 第一檢查點 | 修復方向 |
|---|---|---|---|
| T05 OAuth callback mismatch | Connect account 後 provider 拒絕 redirect URI | 比對 n8n 顯示的 OAuth Redirect URL 與 provider 設定 | 修正 WEBHOOK_URL、N8N_EDITOR_BASE_URL 或 provider redirect URI,然後重新授權 credential。 |
| T06 proxy forwarded headers | IP whitelist、websocket、scheme 或 client IP 判斷錯 | 查 N8N_PROXY_HOPS 與 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto | 在最後一層 proxy 補 headers,設定正確 proxy hops,重測 webhook/IP whitelist。 |
| T07 DNS or TLS failure | domain 無法解析、憑證錯誤、HTTPS 不通 | dig/nslookup domain,curl -Iv https://domain/healthz | 修正 DNS A/AAAA/CNAME、TLS certificate、reverse proxy virtual host。 |
| T08 container restart loop | container 一直 restarting 或 n8n UI 開不起來 | docker ps、docker logs、volume mount、env file path | 修正 env、volume、permission、port collision;避免刪除資料 volume。 |
| 卡片 | 症狀 | 第一檢查點 | 修復方向 |
|---|---|---|---|
| T09 resource exhaustion | 503、Connection Lost、heap out of memory、workflow 中斷 | 查 memory/CPU、container OOM、execution size、binary data mode | 增加資源、拆 workflow、降低 concurrency、調整 binary data 與 execution pruning。 |
| T10 queue worker stalled | queue mode 有 backlog,executions 不被 worker 消化 | 查 worker logs、EXECUTIONS_MODE=queue、QUEUE_BULL_REDIS_HOST、DB connectivity、shared N8N_ENCRYPTION_KEY | 修 Redis/DB env,確認 workers 與 main 同版同 key,調整 worker concurrency 與 DB pool。 |
| T11 webhook path or method conflict | webhook 顯示路徑被占用或 production URL 沒反應 | 查 workflow active、Test URL/Production URL、path + method 是否重複 | 停用衝突 workflow,換 path/method,production 前啟用 workflow。 |
| T12 missing logs or evidence | 事故後無法知道錯在哪個 process | 查 N8N_LOG_LEVEL、N8N_LOG_OUTPUT、N8N_LOG_FORMAT、centralized logs | 設 N8N_LOG_FORMAT=json,集中 main/worker/proxy/DB logs,incident note 保留時間線。 |
| 卡片 | likely causes | check commands | evidence required |
|---|---|---|---|
| T01 |
| docker inspect ... WEBHOOK_URL|N8N_PROXY_HOPS|N8N_EDITOR_BASE_URLcurl -Iv https://n8n.example.com/healthzcurl -Iv https://n8n.example.com/webhook/path | Editor Production URL、container env、provider registration、curl result |
| T02 |
| docker inspect ... N8N_ENCRYPTION_KEYdocker logs ... credential|encryption|decryptgrep -R N8N_ENCRYPTION_KEY .env ... | current key source、original key source、credential error text、backup timestamp |
| T03 |
| docker logs ... database|postgres|connectioncurl ... /healthz/readinessdocker compose ps postgres | DB env、DB logs、startup logs、readiness status |
| T04 |
| curl -I https://n8n.example.comdocker inspect ... N8N_SECURE_COOKIE|N8N_PROXY_HOPS|N8N_PROTOCOLdocker logs ... cookie|secure|session | response headers、proxy headers、cookie settings、browser console |
| 卡片 | likely causes | check commands | evidence required |
|---|---|---|---|
| T05 |
| docker inspect ... WEBHOOK_URL|N8N_EDITOR_BASE_URL|N8N_PROTOCOL|N8N_HOSTcurl -Iv https://n8n.example.com/rest/oauth2-credential/callback | n8n redirect URL、provider redirect URI、public base URL、provider error |
| T06 |
| docker inspect ... N8N_PROXY_HOPScurl -Iv https://n8n.example.com/healthz | proxy config、n8n env、access log、failing behavior |
| T07 |
| dig n8n.example.comcurl -Iv https://n8n.example.com/healthzcurl -Iv http://n8n.example.com/healthz | DNS answer、certificate SAN、HTTP status、proxy access log |
| T08 |
| docker ps --filter name=n8ndocker logs --tail 200 n8ndocker inspect n8n --format '{{json .Mounts}}' | restart count、startup error、mount list、image tag |
| 卡片 | likely causes | check commands | evidence required |
|---|---|---|---|
| T09 |
| docker stats --no-streamdocker logs ... heap|memory|503|Connection Lostdocker inspect n8n --format '{{.State.OOMKilled}}' | OOM state、memory usage、execution id、payload size |
| T10 |
| docker logs --since 30m n8n-workerdocker inspect n8n-worker ... EXECUTIONS_MODE|QUEUE_BULL_REDIS|DB_POSTGRESDB|N8N_ENCRYPTION_KEYcurl ... /healthz/readiness | worker logs、Redis env、DB readiness、shared key |
| T11 |
| curl -Iv https://n8n.example.com/webhook/pathdocker logs ... webhook|path|method | workflow active state、path、method、caller URL |
| T12 |
| docker logs --since 2h n8ndocker inspect ... N8N_LOG_LEVEL|N8N_LOG_OUTPUT|N8N_LOG_FORMAT|DB_LOGGING_ENABLEDcurl -s http://localhost:5687/healthz | log configuration、incident timestamp、process list、alert link |
| 必考情境 | 第一步 | 修復方向 |
|---|---|---|
| wrong webhook URL | 先比對 editor 中 webhook URL 與公開 domain,確認 WEBHOOK_URL 是否設定為 HTTPS public base URL。 | 修正 WEBHOOK_URL 與 proxy headers,重啟後重新啟用 workflow 或重新註冊第三方 webhook。 |
| lost credentials | 先確認 N8N_ENCRYPTION_KEY 是否與原 instance key 一致,並停止任何會覆蓋 key 的部署。 | 還原原 key 或從含原 key 的備份恢復;若原 key 不存在,既有 credentials 無法可靠解密,必須重新建立 credentials。 |
| database connection failed | 先打 /healthz/readiness 並讀 startup log,定位是 host、port、password、database、SSL 或 network。 | 修 DB_TYPE=postgresdb 與 DB_POSTGRESDB_*,確認 DB reachable、migration ready,再重啟 n8n。 |
| secure cookie error | 先確認使用者進站 URL 是 HTTPS,且最後一層 proxy 有 X-Forwarded-Proto=https。 | production 修 TLS/proxy;local-only 測試可設 N8N_SECURE_COOKIE=false,並在公開前改回安全設定。 |
固定順序是 log -> env -> DNS -> proxy -> DB。這五步先跑完,再進 container、credentials、OAuth、security、resource、queue、workflow。
| 順序 | Gate | 目的 | 代表性檢查 |
|---|---|---|---|
| 1 | log | 先拿客觀錯誤與時間線 | docker logs --since 30m n8n、centralized logs query、N8N_LOG_LEVEL。 |
| 2 | env | 確認 instance identity 與連線設定 | WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_ENCRYPTION_KEY、DB_POSTGRESDB_*。 |
| 3 | DNS | 確認 public hostname 指到正確入口 | dig n8n.example.com、curl -Iv https://n8n.example.com/healthz。 |
| 4 | proxy | 確認 TLS、forwarded headers、routes | X-Forwarded-Proto、X-Forwarded-Host、N8N_PROXY_HOPS、/webhook/* route。 |
| 5 | DB | 確認 durable state ready | /healthz/readiness、PostgreSQL network、password、SSL、pool。 |
| 6 | container | 確認 process 與 volume | image tag、restart count、volume mount、port mapping。 |
| 順序 | Gate | 目的 | 代表性檢查 |
|---|---|---|---|
| 7 | credentials | 確認 encryption key 與 credential state | 原 N8N_ENCRYPTION_KEY、credential decrypt error、DB backup。 |
| 8 | OAuth | 確認 redirect URI 與 provider 設定 | n8n OAuth Redirect URL、provider redirect URI、public base URL。 |
| 9 | security | 確認 cookie、SSO、API exposure | N8N_SECURE_COOKIE、HTTPS、SameSite、security audit。 |
| 10 | resource | 確認 CPU、memory、binary data、execution size | OOM logs、503、execution payload、binary data mode。 |
| 11 | queue | 確認 Redis 與 workers | Redis host/port/password、worker logs、shared key、queue metrics。 |
| 12 | workflow | 最後才改 workflow | node error、retry、timeout、webhook response mode、external API status。 |
| Gate | commands | pass signal | fail action |
|---|---|---|---|
| log | docker logs --since 30m n8ndocker logs --tail 200 n8ncentralized logs query | 能說出第一個失敗 process 與 timestamp。 | 在受控窗口暫時提高到 N8N_LOG_LEVEL=debug 再抓 log。 |
| env | docker inspect n8n --format '{{range .Config.Env}}{{println .}}{{end}}'compare .env against deployed secretscheck WEBHOOK_URL、N8N_EDITOR_BASE_URL、N8N_ENCRYPTION_KEY、DB_POSTGRESDB_* | public URL、key、DB target、security flags 都已知。 | 從 deployment source of truth 修 env,再依文件順序 restart。 |
| DNS | dig n8n.example.comnslookup n8n.example.comcurl -Iv https://n8n.example.com/healthz | public hostname resolves and reaches expected TLS endpoint。 | 修 DNS、TTL、firewall、certificate 或 ingress target。 |
| Gate | commands | pass signal | fail action |
|---|---|---|---|
| proxy | inspect Caddy/Nginx/Traefik/LB config check X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Protocheck N8N_PROXY_HOPS | proxy forwards HTTPS scheme and host,webhook routes reach correct process。 | 修 forwarded headers、proxy hops、TLS termination、/webhook route。 |
| DB | curl -s -o /dev/null -w '%{http_code}' http://localhost:5687/healthz/readinessdocker compose ps postgresdocker logs --since 30m postgres | /healthz/readiness returns 200,DB 無 authentication/network failure。 | 修 DB_TYPE、host、port、database、user、password、SSL、network 或 readiness。 |
| container | docker ps --filter name=n8n --format '{{.Names}} {{.Status}} {{.Ports}}'docker inspect n8n --format '{{json .Mounts}}'docker inspect n8n --format '{{.Config.Image}}' | container stable,image、mounts、ports 符合預期。 | 修 startup、image tag、port conflict、volume mount 或 permission,不刪 state。 |
| Gate | commands | pass signal | fail action |
|---|---|---|---|
| credentials | compare N8N_ENCRYPTION_KEY across main/workers/deployment secretreview credential decrypt errors verify restore notes include original key | credentials decrypt,所有 process 同 key。 | 還原原 key 或 DB+key;確認 key loss 後才重建 credentials。 |
| OAuth | copy n8n OAuth Redirect URL compare provider redirect URI check WEBHOOK_URL and N8N_EDITOR_BASE_URL | provider redirect URI 完全等於 n8n OAuth Redirect URL。 | 修 public URL 或 provider redirect URI,重新連 credential。 |
| security | curl -I https://n8n.example.comcheck N8N_SECURE_COOKIE and N8N_SAMESITE_COOKIErun n8n audit in maintenance window | cookie、session、security posture 符合 public exposure。 | 修 TLS、secure cookie、public API exposure、audit findings。 |
| Gate | commands | pass signal | fail action |
|---|---|---|---|
| resource | docker stats --no-streamdocker inspect n8n --format '{{.State.OOMKilled}}'review execution payload and binary data mode | resource usage and execution size 在預期範圍。 | 降 concurrency、拆 workflow、移 binary data、prune execution data 或加資源。 |
| queue | docker logs --since 30m n8n-workercheck EXECUTIONS_MODE=queuecheck QUEUE_BULL_REDIS_HOST and QUEUE_BULL_REDIS_PORT | workers 能連 Redis/DB、處理 jobs、shared key。 | 修 Redis、DB、worker env、version mismatch 或 worker concurrency。 |
| workflow | open failed execution identify first failed node check retry、timeout、response mode、external API status | 第一個 workflow-level failure 已由 execution evidence 定位。 | 修 node config、拆 workflow、加 retries 或改 webhook response behavior。 |
incident note 的功能不是寫漂亮報告,而是留下可重演證據。它刻意把「已排除」和「仍需追蹤」分開,避免 incident 結束後只留下口頭印象。
| 區塊 | 必填內容 |
|---|---|
| Incident header | incident id、owner、severity、start time、detect time、affected workflow、affected users。 |
| Symptom | exact error text、HTTP status、browser message、provider response、execution id、container name。 |
| Architecture context | deployment type、public URL、proxy、DB、Redis/workers、n8n version、last deploy。 |
| Check sequence | log、env、DNS、proxy、DB 的結果與時間。 |
| Hypothesis matrix | 每個可能層的 evidence、status、next action。 |
| Fix | 實際變更、指令、env diff、restarts、rollback point。 |
| Verification | health/readiness、webhook test、OAuth reconnect、credential decrypt、execution success。 |
| Root cause | direct cause、contributing cause、missed detection。 |
| Prevention | monitoring、backup、runbook、deployment guard、owner。 |
| Section | Fields |
|---|---|
| Incident Header | Incident ID、Owner、Severity、Start time、Detected time、Resolved time、Affected workflow、Affected users or systems。 |
| Symptom | Exact error text、HTTP status、Execution id、Container or process、First observed by。 |
| Architecture Context | Deployment type、Public URL、Proxy、Database、Redis or workers、n8n version、Last deploy or config change。 |
| Check Sequence | Order 1-12:log、env、DNS、proxy、DB、container、credentials、OAuth、security、resource、queue、workflow;每列填 Result 與 Evidence link or command output。 |
| Section | Fields |
|---|---|
| Hypothesis Matrix | Layer、Hypothesis、Evidence、Status、Next action;layers 至少包含 container、DB、URL、proxy、OAuth、security、resource、workflow。 |
| Fix Applied | Change owner、Change description、Commands or deployment link、Environment diff、Rollback point。 |
| Verification | /healthz、/healthz/readiness、Webhook test、OAuth reconnect、Credential decrypt、Successful execution id、User-facing confirmation。 |
| Root Cause | Direct cause、Contributing cause、Detection gap、Recovery gap。 |
| Prevention / Closure | Action、Owner、Due date、Verification;Final status、Follow-up owner、Follow-up location、Closed time。 |
| 項目 | 操作 |
|---|---|
| 症狀 | 外部服務打 webhook 失敗,或 provider 顯示 webhook URL 必須是 HTTPS。 |
| 第一檢查點 | 看 n8n editor 中 Webhook node 顯示的 Production URL,再比對 WEBHOOK_URL 與 public domain。 |
| 證據 | curl -Iv https://n8n.example.com/webhook/path、provider webhook 設定截圖、container env。 |
| 修復方向 | 設 WEBHOOK_URL=https://n8n.example.com/、N8N_PROXY_HOPS=1,proxy 補 X-Forwarded-* headers,重啟後重新註冊 webhook。 |
| 驗證 | workflow active 後,Production URL 收到 2xx,execution list 有新 execution。 |
| 項目 | 操作 |
|---|---|
| 症狀 | migration 或 container recreation 後,credentials 顯示無法解密,OAuth/token 失效。 |
| 第一檢查點 | 立即查目前 N8N_ENCRYPTION_KEY,與原部署 secret、備份、worker env 比對。 |
| 證據 | deployment secret history、old .n8n settings file、DB backup timestamp、worker env。 |
| 修復方向 | 還原原 N8N_ENCRYPTION_KEY;若原 key 遺失,從含原 key 的備份還原或重新建立 credentials。 |
| 驗證 | Credential test success,既有 workflow 可讀 credentials,queue workers 使用同一 key。 |
| 項目 | 操作 |
|---|---|
| 症狀 | n8n startup log 有 database connection failed,或 /healthz/readiness 回傳非 200。 |
| 第一檢查點 | 查 DB_TYPE=postgresdb 與 DB_POSTGRESDB_HOST、port、database、user、password、SSL 是否與 DB service 一致。 |
| 證據 | docker compose ps、DB logs、n8n startup logs、readiness status、network name。 |
| 修復方向 | 修正 DB env、Docker network、SSL CA、DB password;確認 DB ready 後重啟 n8n。 |
| 驗證 | /healthz/readiness 200,n8n UI 可登入,existing workflows 可讀。 |
| 項目 | 操作 |
|---|---|
| 症狀 | 使用 HTTP public URL、behind proxy、或 browser console 顯示 secure cookie 相關錯誤,登入 session 不保留。 |
| 第一檢查點 | 確認使用者進站為 HTTPS,proxy 給 n8n 的 forwarded proto 是 https,N8N_SECURE_COOKIE 沒被錯誤關閉或錯誤保留。 |
| 證據 | curl -I https://n8n.example.com、proxy access log、response headers、container env。 |
| 修復方向 | production 修 TLS 與 proxy headers;local-only 測試可暫設 N8N_SECURE_COOKIE=false,但 public production 必須回到 HTTPS cookie。 |
| 驗證 | login session 穩定,browser 不再拒收 cookie,security env 與 public URL 一致。 |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 12 張故障排除卡 | 通過 | 第 17.4 節與 week-17-troubleshooting-cards.json |
| 完成 log/env/DNS/proxy/DB 檢查順序 | 通過 | 第 17.5 節與 week-17-check-order.json |
| 完成 incident note 範本 | 通過 | 第 17.6 節與 week-17-incident-note-template.md |
| wrong webhook URL 有第一步與修復方向 | 通過 | 第 17.4、17.7 節 T01/Drill A |
| lost credentials 有第一步與修復方向 | 通過 | 第 17.4、17.7 節 T02/Drill B |
| database connection failed 有第一步與修復方向 | 通過 | 第 17.4、17.7 節 T03/Drill C |
| secure cookie error 有第一步與修復方向 | 通過 | 第 17.4、17.7 節 T04/Drill D |
| 症狀可轉成排查流程 | 通過 | 第 17.3、17.5 節 |
Week 18 會進入平台選型與成本風險評估。Week 17 的 incident notes 可以回餵 Week 18:哪一類事故最常發生、哪一層最難維運、哪個平台能降低 DB/proxy/OAuth/security/resource 的操作風險。選型不只看月費,也要看它能不能減少真實事故的 MTTR。
Week 17 的成果,是把排錯從直覺改成證據流程:先 log、env、DNS、proxy、DB,再看 container、credentials、OAuth、security、resource、queue、workflow。每一次修復都要用 incident note 留下時間線、證據、修復與預防。
18.1 本週交付總覽
執行日期:2026-05-28。本週目標是說清楚不同使用者類型應該選哪條部署路線,並把成本與維運責任攤開。實作結果包含 deployment recommendation matrix、cost-risk worksheet、AWS vs PaaS decision memo,並為 beginner、freelancer、agency、production team 分別提出首選、替代方案、避免事項。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| deployment recommendation matrix | 完成 | artifacts/week-18-platform-selection/week-18-deployment-recommendation-matrix.json;本章 18.3 |
| cost-risk worksheet | 完成 | artifacts/week-18-platform-selection/week-18-cost-risk-worksheet.csv;本章 18.4 |
| AWS vs PaaS decision memo | 完成 | artifacts/week-18-platform-selection/week-18-aws-vs-paas-decision-memo.md;本章 18.5 |
| beginner、freelancer、agency、production team 選型 | 完成 | 本章 18.3、18.6 |
| AWS 與 simpler cloud options 比較 | 完成 | 本章 18.5 |
| usage-priced RAM/CPU/storage/egress 風險整理 | 完成 | 本章 18.4 |
| Week 18 驗證腳本 | 完成 | scripts/verify-week-eighteen.mjs |
整合來源:docs/week-18-platform-selection-cost-risk.md
390Week 18 的判斷基準不是「哪個平台最酷」,而是「誰要承擔維運責任」。同一個 n8n 可以放在 n8n Cloud、單機 VPS、PaaS、Cloud Run、AWS ECS/Fargate 或 Kubernetes;錯誤選型會把 Week 14 的 backup、Week 15 的 security、Week 16 的 scaling、Week 17 的 troubleshooting 變成長期成本。
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n Docker install | Docker install | n8n 官方 Docker 文件明確要求 persistent volume;這是 VPS/Docker Compose 路線的最低基礎,也提醒 beginner 不能把 container 當 state。 |
| n8n scaling overview | Scaling overview | 大量 users、workflows、executions 時才進入 scaling 設定;queue mode 是擴展路線,不是 beginner 起點。 |
| n8n queue mode | Queue mode | queue mode 需要 PostgreSQL、Redis、workers,且 main/worker 要共享資料層與 encryption key;production team 才應把它當主要架構。 |
| n8n execution data | Execution data | execution retention 會影響 database size 與效能;成本 worksheet 必須包含 DB storage、pruning、backup growth。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n binary data | Binary data | binary data 會影響 memory、storage、execution behavior;平台選型不能只看 app compute。 |
| n8n external storage | External storage | 大量 binary data 需要外部物件儲存;這會增加 storage、request、egress、lifecycle policy 風險。 |
| n8n logging | Logging | 多 process/multi-worker deployment 要 centralized logs;log level 與 retention 是成本項,也是 Week 17 排錯證據來源。 |
| n8n monitoring | Monitoring | production 需要 health/readiness/metrics;監控與告警是維運責任,不是可省略項。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Render pricing | Render pricing | Render 以服務、Postgres、disk、bandwidth 等項目組合成本;適合簡化部署,但仍需看 persistent disk 與 DB plan。 |
| Render free usage | Render free | free tier 有使用限制;不能把 free service 當 production webhook 承載,也不能放真客戶 credentials。 |
| Railway pricing | Railway pricing | Railway 採 base subscription fee + resource usage;RAM、CPU、storage、egress 會直接影響月費;適合快速部署但要設 usage alerts。 |
| Railway databases | Railway databases | Railway database templates 是 unmanaged services;production 要自行負責 backup、DR、security、monitoring/maintenance,或改用 Enterprise / external managed database provider。 |
| Fly.io pricing | Fly pricing | Fly 以 machines、volumes、bandwidth 等項目計價;多 region 或 volume 成長會改變成本。 |
| Google Cloud Run pricing | Cloud Run pricing | Cloud Run 依 CPU、memory、requests、networking 等項目計費;scale-to-zero 有價值,但長時間常駐與 egress 要估算。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| AWS Fargate pricing | Fargate pricing | Fargate 以 vCPU、memory、OS/CPU architecture、running time 計費;需搭配 RDS、logs、load balancer、data transfer 看總成本。 |
| Amazon RDS pricing | RDS pricing | RDS 成本包含 instance、storage、I/O、backup、data transfer;production team 才應承擔完整雲端資料層。 |
| AWS data transfer pricing | Data transfer pricing | AWS egress 與跨區流量會變成成本風險;自動化傳大檔或 binary data 時要特別估算。 |
| Amazon Lightsail pricing | Lightsail pricing | Lightsail 提供比較固定的 VPS 套餐;適合作為簡單 VPS 路線對照,但仍需自行維運 Docker、backup、安全更新。 |
| User type | 首選 | 替代方案 | 避免事項 |
|---|---|---|---|
| beginner | n8n Cloud | Local Docker Desktop for learning volume, credentials, and workflow export behavior |
|
| freelancer | Single VPS with Docker Compose, PostgreSQL, Caddy, backup, and patch cadence | Railway, Render, or Fly with managed/external PostgreSQL;Railway template DB needs operator-owned backup、DR、security、monitoring;n8n Cloud when the client pays for low operations |
|
| agency | Standardized client blueprint using isolated Compose or PaaS instances, managed/external PostgreSQL, backup, patch cadence, and incident notes | n8n Cloud Business or Enterprise for low-operations client delivery |
|
| production team | AWS or GCP production architecture with managed PostgreSQL, Redis queue, workers, centralized logs, IaC, budgets, and on-call | n8n Cloud Enterprise or mature PaaS with managed database and Redis during transition |
|
| User type | 為什麼 | 成本風險 | 維運責任 |
|---|---|---|---|
| beginner | The beginner should learn automation semantics before owning hosting, backups, public URLs, secure cookies, and database operations. | Subscription cost is easier to understand than variable infrastructure cost;主要風險是 workflows 還沒證明價值前就 overbuying。 |
|
| freelancer | The freelancer needs a clear client bill, predictable maintenance scope, and a deployment that can be restored without a platform team. | VPS is mostly fixed but labor-heavy;PaaS is faster but RAM, CPU, storage, egress, and database plan can drift. |
|
| agency | The agency optimizes for repeatability, client isolation, handoff, and maintenance margins rather than a single lowest monthly bill. | 最大風險是 many small incidents 的 hidden labor;per-client budgets、support terms、standardized restore drills 比少一點 compute 更重要。 |
|
| production team | The production team has compliance, private networking, IAM, SLO, queue workers, logs, and disaster recovery requirements that justify cloud architecture complexity. | AWS and GCP cost is a stack total:compute, RDS, Redis, logs, load balancer, NAT, egress, backup, storage, support, and operations labor. |
|
選平台不是一次性答案。前 90 天要用 export、backup、restore drill、budget alert、incident note、logs、metrics,把「我選了這個平台」變成「我能維運這條路線」。
| User type | first 90 days |
|---|---|
| beginner |
|
| freelancer |
|
| agency |
|
| production team |
|
沒有 ops owner 時先選 n8n Cloud。
需要清楚報價時優先 VPS Compose。
可選 Railway、Render、Fly 加 managed/external PostgreSQL;Railway template DB 要另管備份與監控。
需求跨過 maturity gate 後才進 AWS/GCP。
Redis workers、centralized logs、RPO/RTO 要有人負責。
把成本、avoid list、90 天行動寫進 handoff。
先問 owner,再問成本模型,最後才問平台名稱。只要沒有 backup、security、scaling、troubleshooting 的 owner,平台越強大,事故面也越大。
| User type | 30 秒建議 |
|---|---|
| beginner | 先用 n8n Cloud;只在本機 Docker 學 state、volume、credentials,不要自己公開 production。 |
| freelancer | 有基本 Linux/Docker 能力就用 VPS Compose;若不想維護 VM,就用 PaaS 但設 monthly budget、backup、DB storage alert。 |
| agency | 建立一份標準交付藍圖,每個客戶獨立 instance、獨立 DB、獨立 credentials、獨立 backup;不要把多客戶塞進同一個省錢 instance。 |
| production team | 用 AWS/GCP 不是因為高級,而是因為你真的需要 VPC/IAM/audit/logging/queue/worker/DR;若沒有這些需求,PaaS 或 n8n Cloud 更理性。 |
| 類型 | 說明 | 常見失控點 |
|---|---|---|
| Fixed baseline | 即使沒有 executions 也會付的費用。 | VPS、RDS instance、Redis instance、persistent disk、support plan。 |
| Usage variable | 用量增加才上升的費用。 | CPU/RAM runtime、egress、request count、storage growth、logs ingestion、object storage operations。 |
| Human operations | 人工維護與事故處理成本。 | patch、backup restore、incident response、security review、client support。 |
服務還沒忙也要付。
RAM、CPU、storage、egress 隨量漂移。
人的維運時間常比雲端帳單更貴。
成本 worksheet 的功能不是做精準報價,而是防止漏算:app 看起來便宜,但 DB、backup、logs、egress、Redis、load balancer、support、maintenance hours 才是長期責任。
| 成本項 | 風險 | 控制方式 |
|---|---|---|
| App RAM | workflow 讀大 payload、binary data in memory、並行 executions。 | 限制 concurrency、拆 workflow、設定 binary data mode、監控 memory high-water mark。 |
| App CPU | 大量 transformation、code node、PDF/image processing、crypto/API batching。 | 將重工作排程化、queue workers、限制 execution timeout、觀察 CPU throttling。 |
| DB compute | execution history、credentials、workflow metadata、queue workers 共用 DB。 | PostgreSQL first、connection pool、execution pruning、slow query 與 readiness monitoring。 |
| DB storage | 保存太多 success executions、大量 binary metadata、backup snapshots。 | retention policy、pruning、storage alert、定期 restore drill。 |
| Object storage | binary data、attachments、workflow generated files。 | lifecycle policy、檔案大小限制、避免無限保存 debug artifacts。 |
| Egress | webhook 回傳大檔、跨區傳輸、第三方 API 同步大量資料。 | 設 response size policy、避免跨區 DB/app、評估 CDN 或直接讓 client 拉檔。 |
| 成本項 | 風險 | 控制方式 |
|---|---|---|
| Logs | debug level 長期開啟、多 workers、多 requests。 | incident 才短期 debug、JSON logs、retention days、sampling。 |
| Autoscaling | scale-to-zero 或 horizontal scale 沒有上限。 | 設 max instances、monthly budget alerts、queue backlog 門檻。 |
| Redis/queue | worker 增加造成 DB connections 與 Redis plan 升級。 | worker concurrency、DB pool、queue metrics、Redis memory alert。 |
| Public IPv4/LB | cloud load balancer、公網 IP、TLS endpoint。 | 小案用 Caddy/VPS/PaaS managed endpoint;production 才上雲端 LB。 |
| Backup | DB backup、volume snapshot、object storage versioning。 | 決定 RPO/RTO、保留週期、restore drill,不只看備份大小。 |
| Support and SLO | 商業支援、on-call、incident SLA。 | 把支援成本寫進報價,不把 response time 當免費承諾。 |
monthly_total =
app_compute_baseline
+ db_compute_baseline
+ persistent_storage
+ backup_storage
+ object_storage
+ egress
+ logs_and_metrics
+ redis_or_queue
+ public_endpoint_or_load_balancer
+ support_plan
+ maintenance_hours
PaaS 的表面月費常常沒有包含全部 variable;AWS 的服務單價也不是總價。RDS、CloudWatch、NAT/LB、data transfer、backup、Redis、on-call 都要一起看。
| category | cost_driver | applies_to | risk | how_it_surprises | control | evidence |
|---|---|---|---|---|---|---|
| app_ram | RAM allocated or consumed by the n8n process | PaaS, Cloud Run, AWS Fargate, VPS | high | Large payloads, binary data, and concurrent executions can force a bigger instance or higher memory allocation | Set concurrency limits, move binary data out of memory, split workflows, monitor memory high-water mark | memory chart, execution size, binary data mode |
| app_cpu | vCPU allocation, CPU seconds, or burst CPU | PaaS, Cloud Run, AWS Fargate, VPS | medium | Code nodes, transformations, PDF/image work, and high concurrency can increase runtime cost or require larger compute | Schedule heavy jobs, use queue workers only after Week 16 gates, cap autoscaling | CPU chart, slow workflow list, queue backlog |
| db_compute | Managed PostgreSQL instance size or database service tier | PaaS, AWS RDS, Cloud SQL, self-managed Postgres | high | The app may be cheap while the database tier becomes the real baseline cost | Right-size DB, monitor connections, use connection pool, review slow queries | DB instance tier, connection count, readiness history |
| db_storage | Execution data, workflow metadata, credential metadata, indexes | All production deployments | high | Saved success executions and binary metadata grow quietly until storage or performance degrades | execution pruning, retention policy, storage alerts, restore drill | DB storage graph, pruning settings, backup size |
| category | cost_driver | applies_to | risk | how_it_surprises | control | evidence |
|---|---|---|---|---|---|---|
| backup_storage | Database backups, volume snapshots, object versioning | VPS, PaaS, AWS, GCP | medium | Backups are often omitted in cheap estimates but required for production RPO/RTO | Define retention windows, test restore, separate hot and archive backups | backup schedule, restore proof, retention policy |
| object_storage | External storage for binary data and generated files | AWS S3, GCS, PaaS add-ons, n8n external storage | medium | Attachments and workflow-generated files can grow independently of DB size | Lifecycle rules, file size policy, storage alerts | bucket size, lifecycle policy, object count |
| egress | Outbound bandwidth to users, third-party APIs, or cross-region services | Cloud Run, AWS, Fly, Render, Railway, VPS | high | Large webhook responses, binary downloads, or cross-region traffic can make a small app expensive | Avoid cross-region app/DB, cap response size, budget alerts, direct-to-object-storage links | egress graph, region map, large response audit |
| logs | Log ingestion, retention, and search | AWS CloudWatch, GCP Logging, PaaS logs, centralized logging | medium | Debug logs left on in production create log cost and noise | Use info level by default, short debug windows, retention rules, structured JSON logs | log volume, retention days, log level |
| category | cost_driver | applies_to | risk | how_it_surprises | control | evidence |
|---|---|---|---|---|---|---|
| metrics_alerts | Monitoring service and alerting volume | Production PaaS, AWS, GCP, self-hosted Prometheus | medium | More workers and services create more metrics and alert paths | Monitor only actionable signals, define owner and severity | alert list, dashboard, owner map |
| redis_queue | Redis service, memory, persistence, worker connectivity | Queue mode deployments | high | Adding workers creates a Redis baseline cost and can force DB connection upgrades | Use queue mode only after Week 16 gates, monitor Redis memory and queue metrics | Redis plan, queue metrics, worker count |
| queue_workers | Additional worker processes and their CPU/RAM | Queue mode, AWS Fargate, Cloud Run jobs, PaaS workers | high | Horizontal workers increase compute and DB pressure together | Set worker concurrency, DB pool, max replicas, autoscaling limits | worker logs, DB connections, queue backlog |
| autoscaling | Scale-to-zero, max instances, or horizontal replicas | Cloud Run, AWS, Fly, Render, Railway | high | Autoscaling can protect availability but multiply compute, DB, logs, and egress cost | Set max instances, budget alerts, load test before raising limits | max instance setting, budget alert, load-test result |
| category | cost_driver | applies_to | risk | how_it_surprises | control | evidence |
|---|---|---|---|---|---|---|
| persistent_disk | Volume or disk attached to app or database | VPS, Render, Fly, self-managed DB | medium | A cheap app plan may not include durable disk or disk expansion can be manual | Use managed DB where possible, monitor disk, document volume restore | disk size, mount path, snapshot proof |
| public_endpoint_lb | Load balancer, public IPv4, TLS endpoint, static IP | AWS, GCP, VPS, PaaS | medium | Small apps can pay nontrivial baseline for LB or public network resources | Use simpler managed endpoint for small cases, share only where isolation remains safe | LB config, certificate, DNS record |
| support_plan | Vendor support, paid SLA, enterprise features | n8n Cloud, AWS, GCP, PaaS | medium | Support expectations may be promised to clients without being priced | Match client SLA to paid support and maintenance contract | support plan, SLA, client contract |
| maintenance_labor | Patch, backup, incident response, security review | All self-hosted and semi-managed routes | high | Human time can exceed infrastructure bill, especially for agencies and freelancers | Retainer, update windows, incident note discipline, standard blueprint | hours log, patch calendar, incident notes |
| category | cost_driver | applies_to | risk | how_it_surprises | control | evidence |
|---|---|---|---|---|---|---|
| security_compliance | SSO, audit logs, private networking, secrets management | Agency and production deployments | high | Compliance requirements can force enterprise plans or hyperscaler architecture | Decide compliance boundary before platform choice | security requirements, audit needs, secret inventory |
| vendor_lock_in | Platform-specific deploy model, databases, secrets, networking | PaaS, AWS, GCP, n8n Cloud | medium | Migration later can require DNS, env, DB, storage, credentials, and OAuth changes | Keep workflow exports, DB backups, env inventory, migration runbook | export date, backup date, env inventory |
| client_isolation | Per-client instance, DB, credentials, domains, logs | Agency deployments | high | Saving money by sharing instances creates privacy and blast-radius risk | One client per instance or strict tenant boundary, separate backups and keys | client map, instance id, DB id, encryption key owner |
| free_tier_limits | Free service sleep, low resources, usage caps, deleted inactive resources | Render, Railway, Fly, Cloud free tiers | high | Free tiers are learning tools; production webhooks may sleep, throttle, or hit caps | Use paid plans for production, define uptime and support expectations | plan name, sleep behavior, uptime proof |
Use simpler cloud options by default. Choose AWS or GCP only when the workload, team, compliance, networking, and operations maturity justify the extra moving parts.
| Situation | Default |
|---|---|
| Learning and early automation | n8n Cloud or Local Docker Desktop |
| First paid client | VPS Docker Compose + PostgreSQL, or PaaS + managed/external PostgreSQL |
| Repeatable agency delivery | Standardized isolated client blueprint |
| Production platform team | AWS/GCP with managed PostgreSQL, Redis queue, centralized logs, IaC, budgets, and on-call |
| Advantage | Why it matters |
|---|---|
| Faster deployment | Reduces setup time for freelancer and agency delivery. |
| Managed public endpoint | Simplifies TLS, domain, and routing compared with raw VM networking. |
| Managed database options | Reduces the chance that SQLite or unmanaged Postgres becomes the hidden production risk. |
| Lower cognitive load | Fewer services to debug during Week 17-style incidents. |
| Easier client explanation | Costs can be explained as app, database, storage, and usage rather than a large AWS bill of materials. |
| Risk | Control |
|---|---|
| Usage-priced RAM/CPU/storage/egress drift | Set monthly budgets, usage alerts, storage alerts, and max instance limits. |
| Free tier behavior | Do not use free tier for production webhooks or client credentials. |
| Platform-specific migration | Keep workflow exports, env inventory, PostgreSQL backups, and OAuth redirect documentation. |
| Limited low-level control | Move to AWS/GCP only when private networking, IAM, queue workers, or compliance require it. |
| Advantage | Why it matters |
|---|---|
| VPC and private networking | Required for internal APIs, private DBs, and enterprise network boundaries. |
| IAM and audit controls | Required for production teams with compliance and access governance. |
| Managed PostgreSQL and Redis | Supports queue mode, HA, backup, and operational dashboards. |
| Centralized logs and metrics | Supports SLO, incident response, and capacity planning. |
| Infrastructure as code | Makes production changes reviewable and repeatable. |
| Risk | Control |
|---|---|
| Cost stack complexity | Estimate app compute, RDS, Redis, logs, LB, NAT, egress, backup, storage, support, and labor together. |
| More troubleshooting layers | Require Week 17 incident process, centralized logs, and runbooks before production cutover. |
| Overengineering small workloads | Keep small freelancer/client projects on VPS/PaaS unless compliance or networking proves otherwise. |
| Autoscaling bill shock | Set max instances, queue thresholds, budget alerts, and anomaly detection before launch. |
| Gate | Choose PaaS or VPS if | Choose AWS/GCP if |
|---|---|---|
| Operations owner | No dedicated cloud ops exists | A production team owns IaC, on-call, and FinOps |
| Networking | Public HTTPS webhook is enough | Private VPC, internal APIs, peering, or IAM boundaries are required |
| Data layer | Managed Postgres plan is enough | RDS/Cloud SQL with explicit RPO/RTO and backup governance is required |
| Scaling | Single instance or simple worker process is enough | Redis queue, worker pools, central logs, and separate webhook processors are required |
| Cost model | Client needs predictable simple billing | Team can manage multi-service budgets and anomaly alerts |
| Compliance | Basic credential hygiene and backups are enough | Audit, SSO, private networking, data residency, or formal review is required |
| 不要因為這個理由選 AWS | 更好的選擇 |
|---|---|
| 想看起來 enterprise | n8n Cloud Business/Enterprise 或標準化 PaaS 交付更可靠。 |
| 以為 AWS 一定便宜 | 先把 RDS、egress、logs、LB、NAT、backup、maintenance hours 算進去。 |
| 只有一兩個客戶 workflow | VPS Compose 或 PaaS 比多服務 AWS 更好維護。 |
| 還沒有 backup/restore drill | Week 14 完成前,不要擴大平台複雜度。 |
| 還沒有 troubleshooting runbook | Week 17 完成前,AWS 只會增加排查層數。 |
AWS/GCP 的價值是 VPC/IAM/compliance/observability/managed state/queue/region/networking 的完整控制。沒有這些需求時,PaaS 的速度、少維運與較少基礎設施決策更符合課程主線。
| Maturity | Platform |
|---|---|
| Learning | n8n Cloud 或 Local Docker Desktop。 |
| First paid automation | VPS Compose + PostgreSQL 或 PaaS + managed/external PostgreSQL。 |
| Repeatable client delivery | Standardized PaaS/VPS blueprint + backup + incident note + budget alerts。 |
| Production operations | AWS/GCP + managed PostgreSQL + Redis queue + logs + IaC + budget + on-call。 |
Beginner should use n8n Cloud. Freelancer should use VPS Compose or a small PaaS with managed/external PostgreSQL;Railway template databases need explicit backup, DR, security, and monitoring ownership. Agency should standardize isolated client blueprints or use n8n Cloud Business/Enterprise. Production team should choose AWS/GCP only when they have the operational maturity to own managed state, queue mode, logs, budgets, and incident response.
| User type | 首選 | 替代方案 | 避免事項 |
|---|---|---|---|
| beginner | n8n Cloud,因為先避開 hosting、backup、public URL、secure cookie、database 維運。 | Local Docker Desktop 學習 volume、credentials、workflow 匯出。 | public tunnel 當 production、自架 VPS 放真客戶 credentials、跳 AWS/Kubernetes。 |
| freelancer | VPS Docker Compose + PostgreSQL + Caddy,成本固定、可控、容易向客戶說明。 | Railway/Render/Fly + managed/external PostgreSQL;Railway template DB 需自己處理 backup、DR、security、monitoring;或客戶願付時用 n8n Cloud。 | 沒 backup 的單容器、free tier production、未設 budget 的 usage-priced 平台、AWS multi-service 起手。 |
| agency | 標準化 blueprint:每客戶獨立 instance、獨立 DB、backup、patch cadence、incident note。 | n8n Cloud Business/Enterprise,或 PaaS + managed DB 作為低維運交付。 | 多客戶共用未隔離 instance、同一組 credentials、手工散裝部署、沒有維護合約。 |
| production team | AWS/GCP production stack:managed PostgreSQL、Redis queue、workers、centralized logs、IaC、budget alerts。 | n8n Cloud Enterprise;或成熟 PaaS + managed DB/Redis 作為過渡。 | 單台 VPS 承擔高 SLO、沒有 RPO/RTO、未控 autoscaling、無 logs/alerts 的 queue mode。 |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成 deployment recommendation matrix | 通過 | 第 18.3 節與 week-18-deployment-recommendation-matrix.json |
| 完成 cost-risk worksheet | 通過 | 第 18.4 節與 week-18-cost-risk-worksheet.csv |
| 完成 AWS vs PaaS decision memo | 通過 | 第 18.5 節與 week-18-aws-vs-paas-decision-memo.md |
| beginner 有首選、替代、避免事項 | 通過 | 第 18.3、18.6 節 |
| freelancer 有首選、替代、避免事項 | 通過 | 第 18.3、18.6 節 |
| agency 有首選、替代、避免事項 | 通過 | 第 18.3、18.6 節 |
| production team 有首選、替代、避免事項 | 通過 | 第 18.3、18.6 節 |
| usage-priced 平台 RAM/CPU/storage/egress 風險已整理 | 通過 | 第 18.4 節 |
| AWS 與 simpler cloud options 已比較 | 通過 | 第 18.5 節 |
Week 19 會進入 Capstone:建立可複製部署作品。Week 18 的結論會變成作品包的入口選單:先選 user type,再套用對應 blueprint、成本 worksheet、incident note、backup checklist、security cadence。
Week 18 的成果,是把平台選型從「平台喜好」改成「維運責任、成本風險與成熟度門檻」。Capstone 不只要能部署,還要能交接給下一個維護者。
19.1 本週交付總覽
執行日期:2026-05-28。本週目標是把前 18 週學到的內容變成另一位同仁可以接手的部署作品包。主路線選擇 VPS Docker Compose + PostgreSQL + Caddy,實作結果包含 deployment package、README-style handoff、final demo checklist,以及 architecture、env template、DNS/TLS notes、backup/update/troubleshooting。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| 部署作品包 | 完成 | artifacts/week-19-capstone/deployment-package/ |
| README-style handoff | 完成 | artifacts/week-19-capstone/deployment-package/README.md;本章 19.4 |
| final demo checklist | 完成 | artifacts/week-19-capstone/deployment-package/final-demo-checklist.csv;本章 19.7 |
| deployment package manifest | 完成 | artifacts/week-19-capstone/week-19-deployment-package-manifest.json;本章 19.3、19.4 |
| env template | 完成 | artifacts/week-19-capstone/deployment-package/.env.template;本章 19.5 |
| architecture、DNS/TLS notes、backup/update/troubleshooting | 完成 | 本章 19.3、19.5、19.6 與作品包 runbooks |
| Week 19 驗證腳本 | 完成 | scripts/verify-week-nineteen.mjs |
整合來源:docs/week-19-capstone-replicable-deployment-package.md
421Week 19 選 VPS Docker Compose + PostgreSQL + Caddy,不是因為它永遠最好,而是因為它最適合做成可複製作品:成本相對固定、架構容易理解、可以完整演示 DNS/TLS、persistent state、PostgreSQL、backup/restore、update、troubleshooting,也能自然接到 Week 20 的最終建議。
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Docker self-hosting | Docker install | n8n 官方建議 Docker 適合多數 self-hosting;persistent volume 必須保存 /home/node/.n8n。 |
| Docker Compose setup | Docker Compose setup | Compose 範例把 n8n data volume 視為 state;作品包用 Compose 固化 n8n、postgres、caddy。 |
| DigitalOcean Caddy route | DigitalOcean Caddy route | 官方 Caddy 範例使用 reverse_proxy n8n:5678;作品包沿用 Caddy 作為 TLS reverse proxy。 |
| Webhook URL behind proxy | Webhook URL | reverse proxy 後要設定 WEBHOOK_URL、N8N_PROXY_HOPS=1 與 X-Forwarded-* headers;作品包把它放入 env template 與 DNS/TLS notes。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| SSL setup | SSL setup | production 要使用 HTTPS;Caddy 自動處理 TLS,n8n 內部仍以 n8n:5678 服務。 |
| Database settings | Database settings | self-hosted 可使用 PostgreSQL;作品包使用 DB_TYPE=postgresdb 與 DB_POSTGRESDB_*。 |
| Custom encryption key | Custom encryption key | N8N_ENCRYPTION_KEY 是 credentials 可解密的關鍵;handoff 明確要求保存與交接。 |
| Update self-hosted n8n | Update self-hosted n8n | 更新前要檢查 release notes、測試環境、備份;作品包提供 update runbook。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Logging | Logging | 作品包預設 N8N_LOG_FORMAT=json,incident 時可短期提高 log level。 |
| Monitoring | Monitoring | 作品包用 /healthz 與 /healthz/readiness 做啟動與交接驗收。 |
| Execution data | Execution data | handoff 要說明 execution data retention 與 DB storage 風險。 |
| Binary data | Binary data | 作品包預設 N8N_DEFAULT_BINARY_DATA_MODE=database,避免把 binary data 放在 ephemeral memory。 |
| 決策 | 選擇 |
|---|---|
| User type | freelancer / agency baseline,可被 production team 擴展。 |
| Primary route | VPS Docker Compose + PostgreSQL + Caddy。 |
| Runtime | Docker Compose 管理 n8n、postgres、caddy。 |
| Public endpoint | Caddy 對外 80/443,自動 TLS,反代到 n8n:5678。 |
| State | postgres_data 保存 PostgreSQL;n8n_data 保存 n8n local state 與設定檔。 |
| Secrets | .env 由 .env.template 建立,必須安全保存 N8N_ENCRYPTION_KEY 與 DB password。 |
| Backup | pg_dump + volume snapshot/export + env secret archive。 |
| Update | backup -> pull image -> compose up -> readiness -> rollback path。 |
| Troubleshooting | Week 17 的 log -> env -> DNS -> proxy -> DB 順序。 |
A/AAAA to VPS public IP
TLS and forwarded headers
internal service only
postgres_data volume stores workflows, credentials metadata, executions, users, settings
settings and local files; must be included in restore evidence
certificate state and Caddy configuration
| Manifest 欄位 | 內容 |
|---|---|
| primaryRoute | VPS Docker Compose + PostgreSQL + Caddy |
| acceptanceTarget | A teammate can understand architecture, startup, backup, risks, and next steps by reading only the deployment package. |
| publicEntry | DNS points n8n.example.com to the VPS public IP. Caddy owns ports 80 and 443. |
| reverseProxy | Caddy terminates TLS and forwards traffic to n8n:5678 inside the Docker network. |
| application | n8n runs as a Docker Compose service with PostgreSQL database configuration. |
| database | PostgreSQL stores workflows, credentials metadata, executions, users, and settings. |
| state | postgres_data volume stores PostgreSQL data;n8n_data volume stores n8n local state and settings;caddy_data and caddy_config store TLS state and Caddy config。 |
| operations | backup-restore-runbook.md、update-runbook.md、troubleshooting-playbook.md、final-demo-checklist.csv。 |
| 檔案 | 用途 | 接手者要知道什麼 |
|---|---|---|
README.md | README-style handoff | 先讀這份,理解架構、啟動、備份、風險與下一步。 |
compose.yaml | Docker Compose runtime | 啟動 postgres、n8n、caddy,使用 named volumes 保存 state。 |
.env.template | env template | 建立 .env 的來源;不得提交真實 secrets。 |
Caddyfile | DNS/TLS reverse proxy | 對外 domain 綁 Caddy,內部反代 n8n:5678。 |
backup-restore-runbook.md | 備份與還原 | 說明 backup scope、pg_dump、volume、env secret、restore verification。 |
update-runbook.md | 更新流程 | 說明 update 前後檢查、rollback point、readiness 驗收。 |
troubleshooting-playbook.md | 故障排除 | 直接接 Week 17 的檢查順序與四個高風險情境。 |
final-demo-checklist.csv | 期末展示清單 | 逐項驗證架構、啟動方式、備份方式、風險與下一步。 |
| 順序 | README Startup 步驟 |
|---|---|
| 1 | Provision a VPS with Docker Engine and Docker Compose installed. |
| 2 | Point DNS A or AAAA record for N8N_DOMAIN to the VPS public IP. |
| 3 | Open firewall ports 80 and 443; do not expose 5678 publicly. |
| 4 | Create .env from .env.template. |
| 5 | Replace every CHANGE_ME value in .env, especially POSTGRES_PASSWORD and N8N_ENCRYPTION_KEY. |
| 6 | Run docker compose --env-file .env -f compose.yaml up -d. |
| 7 | Verify docker compose ps. |
| 8 | Verify https://N8N_DOMAIN/healthz and https://N8N_DOMAIN/healthz/readiness. |
| 9 | Create the owner account in the n8n UI. |
| 10 | Create a test workflow and verify a webhook Production URL uses https://N8N_DOMAIN/. |
| 順序 | 最低閱讀動作 |
|---|---|
| 1 | 讀 README.md 的 architecture summary。 |
| 2 | 檢查 .env.template 的 secrets 與 public URL。 |
| 3 | 對照 compose.yaml 確認 state volumes。 |
| 4 | 對照 Caddyfile 確認 DNS/TLS route。 |
| 5 | 跑 final demo checklist 的 dry run。 |
| 6 | 看 backup/update/troubleshooting runbooks,確認能交接給下一位維護者。 |
README 的功能不是替代 runbook,而是讓接手者知道先讀什麼、哪些資料不能遺失、哪個 URL 是公開入口、哪個 volume 是 state、哪個 secret 會影響 credentials。
| State | Owner | Backup requirement |
|---|---|---|
| PostgreSQL data | postgres_data volume | Required before update and at scheduled backup interval. |
| n8n local state | n8n_data volume | Required because settings and local files can affect restore. |
| Caddy state | caddy_data and caddy_config volumes | Required for stable TLS operations and proxy recovery. |
| Secrets | .env and secret store | Required because credentials depend on N8N_ENCRYPTION_KEY. |
| Rule | Reason |
|---|---|
Keep N8N_ENCRYPTION_KEY stable forever for this instance. | Changing it breaks existing credential decryption. |
Keep WEBHOOK_URL=https://N8N_DOMAIN/. | Reverse proxy deployments need the public URL to generate correct webhook URLs. |
Keep N8N_PROXY_HOPS=1. | Caddy is the trusted proxy hop in this blueprint. |
Keep N8N_SECURE_COOKIE=true in production. | Public production access must use HTTPS cookies. |
Keep N8N_DEFAULT_BINARY_DATA_MODE=database for this baseline. | This makes binary behavior explicit and easier to back up with PostgreSQL. |
name: n8n-capstone
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 10
n8n:
image: ${N8N_IMAGE:-docker.n8n.io/n8nio/n8n:stable}
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
DB_POSTGRESDB_USER: ${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_HOST: ${N8N_DOMAIN}
N8N_PROTOCOL: https
N8N_PORT: 5678WEBHOOK_URL: https://${N8N_DOMAIN}/
N8N_EDITOR_BASE_URL: https://${N8N_DOMAIN}/
N8N_PROXY_HOPS: 1
N8N_SECURE_COOKIE: "true"
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
N8N_RUNNERS_ENABLED: "true"
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
N8N_DEFAULT_BINARY_DATA_MODE: database
N8N_LOG_LEVEL: ${N8N_LOG_LEVEL:-info}
N8N_LOG_OUTPUT: console
N8N_LOG_FORMAT: json
GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
TZ: ${TZ}
volumes:
- n8n_data:/home/node/.n8n
expose:
- "5678"
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:5678/healthz >/dev/null 2>&1"]
interval: 30s
timeout: 5s
retries: 10caddy:
image: caddy:2-alpine
restart: unless-stopped
depends_on:
n8n:
condition: service_healthy
environment:
N8N_DOMAIN: ${N8N_DOMAIN}
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
volumes:
postgres_data:
n8n_data:
caddy_data:
caddy_config:| 類別 | 代表設定 | 風險 |
|---|---|---|
| Public URL | N8N_DOMAIN、WEBHOOK_URL、N8N_EDITOR_BASE_URL | wrong webhook URL、OAuth callback mismatch、secure cookie error。 |
| Database | POSTGRES_USER、POSTGRES_PASSWORD、DB_POSTGRESDB_* | database connection failed、DB restore mismatch。 |
| Encryption | N8N_ENCRYPTION_KEY | lost credentials;此值遺失會導致既有 credentials 無法可靠解密。 |
| Runtime | GENERIC_TIMEZONE、TZ、N8N_RUNNERS_ENABLED | schedule nodes、task execution、runtime consistency。 |
| Logs/security | N8N_LOG_FORMAT=json、N8N_SECURE_COOKIE=true | troubleshooting evidence、HTTPS session behavior。 |
N8N_DOMAIN=n8n.example.com
GENERIC_TIMEZONE=Asia/Taipei
TZ=Asia/Taipei
POSTGRES_USER=n8n
POSTGRES_PASSWORD=CHANGE_ME_LONG_RANDOM_POSTGRES_PASSWORD
POSTGRES_DB=n8n
N8N_ENCRYPTION_KEY=CHANGE_ME_64_CHARACTER_RANDOM_INSTANCE_KEY
N8N_IMAGE=docker.n8n.io/n8nio/n8n:stable
N8N_LOG_LEVEL=info
WEBHOOK_URL=https://n8n.example.com/
N8N_EDITOR_BASE_URL=https://n8n.example.com/
N8N_PROXY_HOPS=1
N8N_SECURE_COOKIE=true
N8N_DEFAULT_BINARY_DATA_MODE=database
| 項目 | 規則 |
|---|---|
| DNS | N8N_DOMAIN 必須解析到 VPS public IP。 |
| Firewall | VPS 必須開 80/443 給 Caddy;5678 不對外開。 |
| TLS | Caddy 取得與更新 certificate;n8n 內部只接受 Caddy 反代。 |
| Proxy headers | Caddy 要帶 X-Forwarded-Proto、X-Forwarded-Host、X-Forwarded-For。 |
| Webhook URL | WEBHOOK_URL=https://N8N_DOMAIN/ 必須與實際 HTTPS domain 一致。 |
{$N8N_DOMAIN} {
encode gzip zstd
reverse_proxy n8n:5678 {
flush_interval -1
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto {scheme}
header_up X-Forwarded-For {remote_host}
}
}| Scope | Required artifact |
|---|---|
| PostgreSQL | Compressed pg_dump output. |
| n8n local state | n8n_data Docker volume archive or host snapshot. |
| Caddy state | caddy_data and caddy_config volume archive or host snapshot. |
| Secrets | .env plus secret-store record for N8N_ENCRYPTION_KEY and POSTGRES_PASSWORD. |
| Documentation | Current README.md, compose.yaml, Caddyfile, and runbooks. |
mkdir -p backups
docker compose --env-file .env -f compose.yaml exec -T postgres \
pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" \
| gzip > "backups/n8n-postgres-$(date +%Y%m%d-%H%M%S).sql.gz"
docker compose --env-file .env -f compose.yaml ps > "backups/compose-status-$(date +%Y%m%d-%H%M%S).txt"
docker volume ls > "backups/docker-volumes-$(date +%Y%m%d-%H%M%S).txt"| Secret | Rule |
|---|---|
N8N_ENCRYPTION_KEY | Store in a managed secret store and include in restore drills. |
POSTGRES_PASSWORD | Store in a managed secret store and rotate only with a planned DB credential change. |
.env | Do not commit to source control; store encrypted with deployment records. |
| 順序 | Restore Order |
|---|---|
| 1 | Provision a clean host with Docker and Docker Compose. |
| 2 | Restore compose.yaml, Caddyfile, .env, and runbooks. |
| 3 | Create Docker volumes or restore host volume snapshots. |
| 4 | Start only PostgreSQL with docker compose --env-file .env -f compose.yaml up -d postgres. |
| 5 | Restore the PostgreSQL dump into the postgres service. |
| 6 | Start n8n and Caddy with docker compose --env-file .env -f compose.yaml up -d. |
| 7 | Verify https://N8N_DOMAIN/healthz. |
| 8 | Verify https://N8N_DOMAIN/healthz/readiness. |
| 9 | Verify credentials can decrypt by running a known workflow that uses a saved credential. |
| 10 | Verify a Production URL webhook reaches the expected workflow. |
| Check | Pass condition |
|---|---|
| Container state | postgres, n8n, and caddy are running. |
| Health | /healthz returns 200. |
| Readiness | /healthz/readiness returns 200. |
| Credentials | Existing credential-backed workflow succeeds. |
| Webhook | Production URL uses https://N8N_DOMAIN/ and creates an execution. |
| Logs | No database connection, encryption, cookie, or proxy errors in recent logs. |
| Risk | Prevention |
|---|---|
| Lost credentials | Preserve the original N8N_ENCRYPTION_KEY. |
| Empty database | Verify PostgreSQL dump size and restore output. |
| Wrong domain | Verify DNS and WEBHOOK_URL before enabling production workflows. |
| Broken TLS | Restore Caddy config and confirm ports 80/443 are reachable. |
| Check | Required evidence |
|---|---|
| Release notes reviewed | Version being installed and breaking changes recorded. |
| Backup completed | PostgreSQL dump, volume evidence, and .env secret archive exist. |
| Current version recorded | docker compose --env-file .env -f compose.yaml exec n8n n8n --version. |
| Rollback image known | Previous N8N_IMAGE tag recorded in the update note. |
| Maintenance window approved | Owner and expected impact recorded. |
| Step | 動作 |
|---|---|
| 1 | Set N8N_IMAGE in .env to the target stable image tag. |
| 2 | Run docker compose --env-file .env -f compose.yaml pull n8n. |
| 3 | Run docker compose --env-file .env -f compose.yaml up -d n8n. |
| 4 | Wait for docker compose --env-file .env -f compose.yaml ps to show n8n healthy. |
| 5 | Check https://N8N_DOMAIN/healthz. |
| 6 | Check https://N8N_DOMAIN/healthz/readiness. |
| 7 | Run one manual workflow. |
| 8 | Run one production webhook test. |
| 9 | Review logs for database, migration, encryption, cookie, proxy, and credential errors. |
| 10 | Record final version and update result. |
| Step | Rollback Steps |
|---|---|
| 1 | Set N8N_IMAGE back to the previous image tag. |
| 2 | Run docker compose --env-file .env -f compose.yaml pull n8n. |
| 3 | Run docker compose --env-file .env -f compose.yaml up -d n8n. |
| 4 | If migrations or data changes broke compatibility, stop n8n and restore the PostgreSQL dump. |
| 5 | Verify /healthz, /healthz/readiness, credentials, and webhook execution. |
| 6 | Record root cause in an incident note. |
| Check | Pass condition |
|---|---|
| n8n version | Expected target version is running. |
| UI login | Owner can log in through HTTPS. |
| Readiness | /healthz/readiness returns 200. |
| Credentials | Credential-backed workflow succeeds. |
| Webhook URL | Production URL uses public HTTPS domain. |
| Logs | No new startup or migration errors. |
| Risk | Control |
|---|---|
| Breaking changes | Read release notes and test first. |
| Migration failure | Back up PostgreSQL before update. |
| Credential decrypt error | Preserve N8N_ENCRYPTION_KEY. |
| Public URL regression | Recheck WEBHOOK_URL and Caddy route after update. |
| Order | Gate | First action |
|---|---|---|
| 1 | log | Read docker compose --env-file .env -f compose.yaml logs --since 30m. |
| 2 | env | Compare .env with .env.template and secret-store records. |
| 3 | DNS | Confirm N8N_DOMAIN resolves to the VPS public IP. |
| 4 | proxy | Confirm Caddy owns 80/443 and reverse proxies to n8n:5678. |
| 5 | DB | Check /healthz/readiness and PostgreSQL logs. |
| 6 | container | Check docker compose --env-file .env -f compose.yaml ps. |
| 7 | credentials | Confirm N8N_ENCRYPTION_KEY matches the original instance key. |
| 8 | OAuth | Confirm OAuth Redirect URL uses the public HTTPS domain. |
| 9 | security | Confirm N8N_SECURE_COOKIE=true with HTTPS. |
| 10 | resource | Check memory, CPU, disk, DB storage, and binary data growth. |
| 11 | queue | Not enabled in this baseline; if added later, check Redis and workers. |
| 12 | workflow | Inspect failed execution and first failed node. |
| Incident | First check | Repair direction |
|---|---|---|
| wrong webhook URL | Compare editor Production URL, WEBHOOK_URL, N8N_DOMAIN, and Caddy route. | Set WEBHOOK_URL=https://N8N_DOMAIN/, keep N8N_PROXY_HOPS=1, restart n8n, reactivate or re-register webhook. |
| lost credentials | Confirm current N8N_ENCRYPTION_KEY matches original deployment secret. | Restore the original key or restore DB and key from backup; recreate credentials only after confirming key loss. |
| database connection failed | Check /healthz/readiness, PostgreSQL logs, and DB_POSTGRESDB_*. | Fix DB host, database, user, password, Docker network, or SSL settings; restart n8n after DB is healthy. |
| secure cookie error | Confirm user enters through HTTPS and Caddy passes the correct forwarded scheme. | Keep production HTTPS, keep N8N_SECURE_COOKIE=true, fix Caddy/DNS/TLS rather than weakening cookie security. |
docker compose --env-file .env -f compose.yaml ps
docker compose --env-file .env -f compose.yaml logs --since 30m n8n
docker compose --env-file .env -f compose.yaml logs --since 30m postgres
docker compose --env-file .env -f compose.yaml logs --since 30m caddy
curl -I "https://${N8N_DOMAIN}/healthz"
curl -I "https://${N8N_DOMAIN}/healthz/readiness"| Symptom | Escalate to |
|---|---|
| DB cannot restore | Backup owner and database maintainer. |
| Credentials cannot decrypt | Secret owner and deployment owner. |
| TLS cannot renew | DNS owner and VPS owner. |
| Memory or storage repeatedly exceeds limits | Platform owner for Week 16 scaling review. |
| Client-facing outage exceeds SLA | Incident owner and business owner. |
| Risk | Preventive action |
|---|---|
| wrong webhook URL | Verify public URL after every DNS/proxy change. |
| lost credentials | Store N8N_ENCRYPTION_KEY in the secret store and include it in restore drills. |
| database connection failed | Keep DB env in one source of truth and monitor readiness. |
| secure cookie error | Keep HTTPS enabled and test browser login after proxy changes. |
| noisy incidents | Keep logs structured with N8N_LOG_FORMAT=json. |
| order | demo_item | expected_evidence | pass_condition |
|---|---|---|---|
| 1 | Show deployment package directory | README.md, compose.yaml, .env.template, Caddyfile, runbooks, final-demo-checklist.csv | Reviewer can see every package file |
| 2 | Explain chosen route | VPS Docker Compose + PostgreSQL + Caddy | Reviewer understands why this route was selected |
| 3 | Explain architecture | DNS -> Caddy -> n8n -> PostgreSQL -> volumes | Reviewer can identify public entry, app, database, and state |
| 4 | Explain env template | N8N_DOMAIN, WEBHOOK_URL, N8N_ENCRYPTION_KEY, DB_POSTGRESDB_* | Reviewer knows which values are secrets and which values are public URL settings |
| 5 | Explain DNS/TLS | Caddy owns ports 80/443 and reverse proxies to n8n:5678 | Reviewer knows 5678 is not public |
| 6 | Explain startup | docker compose --env-file .env -f compose.yaml up -d | Reviewer can repeat the startup path |
| order | demo_item | expected_evidence | pass_condition |
|---|---|---|---|
| 7 | Explain health checks | /healthz and /healthz/readiness | Reviewer can distinguish reachable from DB-ready |
| 8 | Explain backup | pg_dump, named volumes, Caddy state, .env, N8N_ENCRYPTION_KEY | Reviewer knows what must be backed up |
| 9 | Explain restore | restore DB, restore secrets, start services, verify health and credentials | Reviewer can describe restore order |
| 10 | Explain update | release notes, backup, pull image, up, readiness, rollback | Reviewer can describe update and rollback |
| 11 | Explain troubleshooting | log -> env -> DNS -> proxy -> DB | Reviewer can start incident response in the correct order |
| order | demo_item | expected_evidence | pass_condition |
|---|---|---|---|
| 12 | Answer wrong webhook URL | Check WEBHOOK_URL, N8N_DOMAIN, Caddy route, editor Production URL | Reviewer hears first step and repair direction |
| 13 | Answer lost credentials | Check original N8N_ENCRYPTION_KEY | Reviewer hears why the key must be preserved |
| 14 | Answer database connection failed | Check /healthz/readiness and DB_POSTGRESDB_* | Reviewer hears first step and repair direction |
| 15 | Answer secure cookie error | Check HTTPS, Caddy forwarded scheme, N8N_SECURE_COOKIE | Reviewer hears first step and repair direction |
| 16 | Explain risks | encryption key, webhook URL, DB, cookie, storage growth, update failure | Reviewer can name top operational risks |
| 17 | Explain next steps | n8n Cloud, PaaS, queue mode, AWS/GCP based on user type and maturity | Reviewer can map future platform moves |
| Trigger | Next platform move |
|---|---|
| Beginner needs low operations | Use n8n Cloud. |
| Freelancer needs faster deploy and less VM maintenance | Use Railway, Render, or Fly with managed/external PostgreSQL and budgets; Railway template databases require explicit backup, DR, security, and monitoring ownership. |
| Agency needs repeatability | Turn this package into a client blueprint with separate instance, DB, key, backup, and incident notes per client. |
| Production team needs VPC, IAM, audit, queue workers, and RPO/RTO | Move toward AWS/GCP or n8n Cloud Enterprise with managed state and centralized logs. |
| handoffReadiness | 說明 |
|---|---|
| Architecture is visible in README.md and this manifest. | 接手者能從 README 與 manifest 看到 public entry、reverse proxy、application、database、state、operations。 |
| Startup path is documented with Docker Compose commands. | 接手者能照 docker compose --env-file .env -f compose.yaml up -d 啟動。 |
| Backup path covers PostgreSQL, volumes, Caddy state, and secrets. | 備份範圍涵蓋 DB、named volumes、TLS state、.env、N8N_ENCRYPTION_KEY。 |
| Risk section covers encryption key, wrong webhook URL, database connection, secure cookie, storage growth, and updates. | Week 17 的 incident 類型已經被放回作品包風險清單。 |
| Next steps explain when to move toward PaaS, n8n Cloud, queue mode, or AWS/GCP. | Week 18 的平台矩陣成為 Week 20 導入排序的入口。 |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成部署作品包 | 通過 | artifacts/week-19-capstone/deployment-package/ |
| 完成 README-style handoff | 通過 | deployment-package/README.md |
| 完成 final demo checklist | 通過 | deployment-package/final-demo-checklist.csv |
| 選定一條主部署路線 | 通過 | VPS Docker Compose + PostgreSQL + Caddy |
| 整理 architecture | 通過 | 第 19.3 節與 package README |
| 整理 env template | 通過 | 第 19.5 節與 .env.template |
| 整理 DNS/TLS notes | 通過 | Caddyfile、README、第 19.5 節 |
| 整理 backup/update/troubleshooting | 通過 | 第 19.6 節與三份 runbook |
| 另一位同仁只看作品包即可接手 | 通過 | README + manifest + checklist 覆蓋架構、啟動、備份、風險、下一步 |
Week 20 會做期末驗收與下一階段導入排序。Week 19 的作品包會成為 Week 20 的展示核心:先證明可交接,再提出 90 天維運節奏、平台升級路線與最後建議。
Week 19 的成果不是一堆設定檔,而是一個可以被另一位同仁接手的部署作品包。它把前 18 週的 state、URL、PostgreSQL、Caddy、backup、update、troubleshooting、platform choice 都收束成一條可展示、可複製、可交接的路線。
20.1 本週交付總覽
執行日期:2026-05-28。本週目標是把 20 週部署能力轉成下一階段導入判斷。實作結果包含最終建議報告、90 天維運節奏、導入候選清單與 owner,並把期末驗收從「n8n 有跑」提升到能回答「為什麼選這條路、風險在哪、如何備份、如何更新、何時擴展」。
| 交付物 | 狀態 | 檔案或章節 |
|---|---|---|
| 最終建議報告 | 完成 | artifacts/week-20-final/final-recommendation-report.md;本章 20.3 |
| 90 天維運節奏 | 完成 | artifacts/week-20-final/week-20-90-day-maintenance-cadence.csv;本章 20.4 |
| 導入候選清單與 owner | 完成 | artifacts/week-20-final/week-20-adoption-candidates-and-owners.csv;本章 20.5 |
| 3 小時成果交流 agenda | 完成 | artifacts/week-20-final/week-20-three-hour-showcase-agenda.json;本章 20.2 |
| Gate 05 final scorecard | 完成 | artifacts/week-20-final/week-20-final-scorecard.json;本章 20.6 |
| Week 20 驗證腳本 | 完成 | scripts/verify-week-twenty.mjs |
整合來源:docs/week-20-final-acceptance-next-stage.md
464Week 20 的重點不是再多做一個部署,而是把前 19 週的所有證據整理成決策能力。最後要能向決策者說清楚:第一條路線是什麼、誰負責、哪些風險要先控、90 天內要驗收什麼、什麼條件才值得擴展。
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| n8n Cloud pricing and plan shape | n8n pricing | n8n Cloud 以 workflow executions 估用量,並提供 Cloud/Self-hosted/Enterprise 等不同操作責任;beginner 與低維運團隊可優先評估。 |
| Docker self-hosting | Docker installation | self-hosting 需要技術能力,Docker 需要 persistent volume;不是只啟動容器就算 production。 |
| Docker Compose setup | Docker Compose setup | Compose route 可作為 VPS 作品包基礎,但 state、env、backup 要交接清楚。 |
| Webhook URL behind proxy | Webhook URL behind proxy | reverse proxy 後要設定 WEBHOOK_URL、N8N_PROXY_HOPS 與 forwarded headers;這是 wrong webhook URL 的第一風險。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Updating self-hosted n8n | Updating self-hosted n8n | 更新要查 release notes、測試與備份;90 天維運節奏必須包含每月更新窗口。 |
| Security audit | Security audit | production 前要能跑 security audit,檢查 credentials、database、file system、nodes、instance 風險。 |
| Logging | Logging | incident response 需要 logs,不能只靠 UI 現象;維運節奏要包含 log review。 |
| Monitoring | Monitoring | /healthz 與 /healthz/readiness 是基本營運驗收,metrics 則支撐 scale decision。 |
| 主題 | 官方來源 | 本週採用的判斷 |
|---|---|---|
| Scaling overview | Scaling overview | 大量 users、workflows、executions 會推動 scaling;queue mode 是 scale path,不是初始答案。 |
| Queue mode | Queue mode | queue mode 需要 PostgreSQL、Redis、workers 與 shared encryption key;列為 90 天後依負載評估的候選。 |
| Concurrency control | Concurrency control | 擴展前先控制 production concurrency,觀察 active executions 與 queue 行為。 |
| Execution data | Execution data | execution retention 會影響 DB size/performance;維運節奏要包含 pruning 與 storage review。 |
| Binary data | Binary data | binary data 會影響 memory/storage;導入候選需標記 binary-heavy workflow 風險。 |
| 時間 | 主題 | 期望產出 |
|---|---|---|
| 00:00-00:20 | Executive summary | 決策者知道首選路線、替代方案、避免事項。 |
| 00:20-01:00 | 部署作品展示 | 看到 Week 19 作品包、architecture、env template、DNS/TLS。 |
| 01:00-01:35 | Runbook drill | 能說明 backup、restore、update、rollback、troubleshooting。 |
| 01:35-02:10 | 風險與成本 | 看懂 Week 18 cost-risk worksheet 與主要失控點。 |
| 02:10-02:40 | Scaling gate | 說清楚何時留在 VPS/PaaS,何時上 queue mode,何時評估 AWS/GCP。 |
| 02:40-03:00 | 下一步排序 | 確認 90 天節奏、導入候選、owner、驗收指標。 |
| section | evidence | requiredAnswer |
|---|---|---|
| Executive summary | final-recommendation-report.md、week-18-deployment-recommendation-matrix.json | Why the recommended route is VPS Docker Compose + PostgreSQL + Caddy for self-hosted baseline, and when n8n Cloud is better. |
| Deployment package demo | deployment-package/README.md、compose.yaml、.env.template、Caddyfile | How DNS, TLS, n8n, PostgreSQL, and volumes fit together. |
| Runbook drill | backup-restore-runbook.md、update-runbook.md、troubleshooting-playbook.md | How to back up, restore, update, roll back, and investigate incidents. |
| Risk and cost review | week-18-cost-risk-worksheet.csv、week-20-adoption-candidates-and-owners.csv | Where cost and operational risk can grow: RAM, CPU, storage, egress, logs, DB, backups, maintenance labor. |
| Scaling gate | week-16-scaling-ladder.json、week-20-final-scorecard.json | When to stay single instance, when to add concurrency control, when to evaluate queue mode, and when AWS/GCP is justified. |
| Next-stage owner review | week-20-90-day-maintenance-cadence.csv、week-20-adoption-candidates-and-owners.csv | Which owner is accountable for each next action and what evidence proves completion. |
Adopt the Week 19 VPS Docker Compose + PostgreSQL + Caddy deployment package as the first self-hosted baseline for teams that can own basic operations. Use n8n Cloud when the team does not have an operations owner. Use PaaS when speed and lower VM maintenance matter more than fixed baseline cost. Consider AWS/GCP only after VPC, IAM, audit, RPO/RTO, queue workers, centralized logs, and FinOps are real requirements.
| Decision | Recommendation |
|---|---|
| Primary self-hosted baseline | VPS Docker Compose + PostgreSQL + Caddy |
| Beginner or no ops owner | n8n Cloud |
| Freelancer | VPS baseline or small PaaS with managed/external PostgreSQL |
| Agency | Standardized isolated client blueprint |
| Production team | AWS/GCP or n8n Enterprise after operational gates are met |
| Reason | Evidence |
|---|---|
| It is handoff-ready | Week 19 package includes README, compose, env template, Caddyfile, backup, update, troubleshooting, and demo checklist. |
| It preserves durable state | PostgreSQL and named volumes are explicit. |
| It controls public URL risk | Caddy, WEBHOOK_URL, N8N_PROXY_HOPS, and HTTPS are documented. |
| It protects credentials | N8N_ENCRYPTION_KEY is treated as a critical secret. |
| It can scale gradually | Week 16 defines the path from single instance to Redis queue workers. |
| It avoids premature complexity | Kubernetes and AWS/GCP are reserved for proven requirements. |
| Risk | First control |
|---|---|
| wrong webhook URL | Verify WEBHOOK_URL, N8N_DOMAIN, Caddy route, and editor Production URL. |
| lost credentials | Preserve and restore the original N8N_ENCRYPTION_KEY. |
| database connection failed | Check /healthz/readiness, PostgreSQL logs, and DB_POSTGRESDB_*. |
| secure cookie error | Keep HTTPS and N8N_SECURE_COOKIE=true; fix proxy headers. |
| DB storage growth | Set execution retention and review database size monthly. |
| binary data growth | Keep binary mode explicit and monitor storage. |
| unsafe update | Backup first, review release notes, keep rollback image tag. |
| cost drift | Track RAM, CPU, storage, egress, logs, Redis, and maintenance labor. |
| 期末必答 | 答案 |
|---|---|
| Backup Answer | Back up PostgreSQL, n8n_data, Caddy volumes, .env, N8N_ENCRYPTION_KEY, and current deployment package files. A backup is not accepted until a restore drill proves /healthz, /healthz/readiness, credential decryption, and a Production URL webhook. |
| Update Answer | Update in a maintenance window. Review release notes, create backup, record current image tag, pull target image, start n8n, verify health/readiness, test credential-backed workflow, test production webhook, then record the result. Roll back by restoring the previous image tag and database backup if needed. |
| Scaling Answer | Do not start with Kubernetes. First measure p95 execution latency, active executions, DB connections, memory, storage, and webhook response time. Then apply pruning, concurrency control, and workflow tuning. Move to Redis queue mode and workers only when production executions or webhook latency repeatedly exceed the single-instance capacity. Evaluate AWS/GCP only when queue operations, managed state, centralized logs, security, and FinOps are mature. |
| Scenario | Decision |
|---|---|
| Individual learning | n8n Cloud or Local Docker Desktop |
| First paid automation | VPS package or PaaS with managed/external PostgreSQL |
| Repeatable agency delivery | Standardize Week 19 package per client |
| Low-ops client | n8n Cloud Business or Enterprise |
| Heavy production workload | PostgreSQL + Redis queue mode + workers after scaling gate |
| Enterprise governance | AWS/GCP or n8n Enterprise after security and FinOps review |
| 問題 | 答案 |
|---|---|
| 為什麼選這條路? | 因為它能在固定成本、可交接性、可維運性之間取得平衡,並覆蓋 DNS/TLS、PostgreSQL、backup、update、troubleshooting。 |
| 風險在哪? | N8N_ENCRYPTION_KEY 遺失、wrong webhook URL、DB connection failed、secure cookie error、execution data growth、binary data storage、更新失敗。 |
| 如何備份? | 備份 PostgreSQL dump、n8n_data、Caddy state、.env、N8N_ENCRYPTION_KEY,並用 staging restore 驗證。 |
| 如何更新? | 先看 release notes,備份,維護窗口 pull image,啟動後檢查 /healthz、/healthz/readiness、credentials、webhook,失敗則 rollback。 |
| 何時擴展? | 當 p95 latency、active executions、DB connections、worker backlog、memory/storage growth 連續超過門檻時,先調 concurrency,再導入 queue mode 與 workers。 |
| 階段 | 天數 | 主題 | 主要產出 |
|---|---|---|---|
| Phase 1 | Day 1-14 | Stabilize baseline | owner、secrets、backup、health checks、first restore drill。 |
| Phase 2 | Day 15-30 | Operate safely | patch cadence、security audit、incident note、cost baseline。 |
| Phase 3 | Day 31-60 | Measure and tune | execution pruning、DB/storage review、workflow risk register、monitoring。 |
| Phase 4 | Day 61-90 | Decide next stage | queue mode gate、PaaS/n8n Cloud/AWS comparison、owner sign-off。 |
owners, secrets, backup, restore
patch, audit, incidents, cost
DB, executions, storage, workflows
queue, Cloud/PaaS/AWS, sign-off
| phase | days | cadence | owner | activity | evidence | acceptance_gate |
|---|---|---|---|---|---|---|
| stabilize | 1-3 | once | deployment_owner | Confirm deployment package owner and secret owner | owner map with deployment_owner, operations_owner, security_owner, finance_owner | Every critical area has one accountable owner |
| stabilize | 1-7 | once | deployment_owner | Deploy Week 19 package to staging or selected baseline host | compose ps output, HTTPS URL, /healthz status | n8n reachable through HTTPS |
| stabilize | 1-7 | once | operations_owner | Verify /healthz and /healthz/readiness checks | timestamped health and readiness output | /healthz and /healthz/readiness return 200 |
| stabilize | 4-10 | once | security_owner | Store N8N_ENCRYPTION_KEY and POSTGRES_PASSWORD in secret store | secret inventory and access owner | Secrets are recoverable and not stored in plaintext repo |
| stabilize | 8-14 | once | operations_owner | Run first backup and restore drill | pg_dump file, restore notes, credential-backed workflow test | Restore proves DB, credentials, and webhook work |
| phase | days | cadence | owner | activity | evidence | acceptance_gate |
|---|---|---|---|---|---|---|
| operate | 15-21 | weekly | operations_owner | Review logs and incident notes | log review notes and open incidents | No unresolved P0/P1 incidents |
| operate | 15-30 | monthly | security_owner | Run n8n security audit | audit output and remediation list | Risky findings have owners and dates |
| operate | 15-30 | monthly | deployment_owner | Run update window with backup first | release notes, previous image tag, target image tag, readiness evidence | Update or deferred update has explicit reason |
| operate | 22-30 | monthly | finance_owner | Set baseline cost and budget alerts | cost baseline, storage alert, egress alert | Budget alert exists for chosen platform |
| phase | days | cadence | owner | activity | evidence | acceptance_gate |
|---|---|---|---|---|---|---|
| measure | 31-45 | biweekly | data_owner | Review execution data retention and DB growth | DB size trend and pruning settings | Retention policy is documented and applied |
| measure | 31-60 | biweekly | operations_owner | Review memory, CPU, active executions, and webhook latency | metrics snapshot or log-derived trend | No sustained capacity breach without owner |
| measure | 45-60 | monthly | workflow_owner | Review top workflows by risk and business value | workflow risk register | High-value workflows have owner and failure path |
| measure | 45-60 | monthly | security_owner | Review credentials and unused credentials | credential inventory and cleanup note | Unused or risky credentials are removed or justified |
| phase | days | cadence | owner | activity | evidence | acceptance_gate |
|---|---|---|---|---|---|---|
| decide | 61-75 | once | platform_owner | Evaluate concurrency control before queue mode | active executions trend and N8N_CONCURRENCY_PRODUCTION_LIMIT decision | Concurrency decision is recorded |
| decide | 61-90 | once | platform_owner | Evaluate queue mode gate | Redis/worker spike plan, DB connection review, rollback plan | Queue mode is approved, deferred, or rejected with evidence |
| decide | 75-90 | once | product_owner | Evaluate n8n Cloud or PaaS for low-ops cases | execution estimate and plan fit | Low-ops route has owner and migration note |
| decide | 75-90 | once | platform_owner | Evaluate AWS/GCP only if enterprise gates are true | VPC/IAM/audit/RPO/RTO/FinOps checklist | AWS/GCP decision is evidence-based |
| decide | 85-90 | once | business_owner | Hold 90-day review and next-stage sign-off | scorecard, owner list, next 90-day backlog | Next-stage decision has owner, budget, and deadline |
| priority | candidate | owner | why_now | entry_condition | first_action | success_metric | avoid_until |
|---|---|---|---|---|---|---|---|
| P0 | Adopt Week 19 VPS package as self-hosted baseline | deployment_owner | It is the completed handoff-ready package | A team can own Docker, DNS, backup, updates, and incidents | Deploy to staging using compose.yaml and .env.template | Teammate can explain architecture, startup, backup, risks, and next steps | Do not put business-critical workflows on it before restore drill |
| P0 | Monthly backup restore drill | operations_owner | Credentials and workflow state must be recoverable | Any production workflow stores real credentials or business data | Run pg_dump and restore to staging | Restore proves /healthz/readiness, credential decrypt, and webhook execution | Do not rely on backups that were never restored |
| P0 | Security audit cadence | security_owner | Public automation instance increases risk | Instance is reachable from the internet or uses sensitive credentials | Run n8n audit and record findings | Findings have severity, owner, and due date | Do not expand public workflows before high-risk items are owned |
| priority | candidate | owner | why_now | entry_condition | first_action | success_metric | avoid_until |
|---|---|---|---|---|---|---|---|
| P1 | Execution data retention and DB pruning | data_owner | Database growth is the most likely silent cost and performance risk | DB size trend or execution count grows each week | Set retention and review saved success executions | DB growth trend is stable and documented | Do not increase workflow volume with unlimited retention |
| P1 | Centralized logs and incident notes | operations_owner | Week 17 showed logs are required for fast diagnosis | Incidents cannot be diagnosed from local logs alone | Route n8n, Caddy, and PostgreSQL logs to a searchable place | Incident note includes exact timestamp and process evidence | Do not add workers before logs are searchable |
| P1 | Cost-risk budget alerts | finance_owner | Usage-priced platforms and storage can drift | PaaS, Cloud Run, AWS, object storage, or multi-client delivery is used | Create budget and storage alerts | Monthly cost has owner and alert threshold | Do not accept open-ended autoscaling without budget |
| priority | candidate | owner | why_now | entry_condition | first_action | success_metric | avoid_until |
|---|---|---|---|---|---|---|---|
| P1 | n8n Cloud fit check | product_owner | Some teams should not own infrastructure | No dedicated operations owner exists | Estimate executions and compare Cloud plan fit | Decision records execution estimate and owner | Do not self-host only to avoid subscription cost |
| P2 | Queue mode evaluation | platform_owner | Scale path should be evidence-based | p95 latency, active executions, or webhook backlog breaches threshold twice | Run Redis/worker staging spike | Queue mode decision includes DB connection and rollback plan | Do not add Redis/workers before PostgreSQL, logs, and backup are stable |
| P3 | AWS/GCP production architecture evaluation | platform_owner | Enterprise requirements may justify complexity | VPC, IAM, audit, SSO, RPO/RTO, and on-call are real requirements | Create architecture and FinOps estimate | Security and finance approve or defer | Do not move to AWS/GCP for appearance or premature scale |
| Gate 05 問題 | 結論 | 證據 |
|---|---|---|
| 是否能提出合理部署建議? | 通過 | Week 18 選型矩陣 + Week 20 最終建議報告。 |
| 是否能展示部署作品包? | 通過 | Week 19 deployment package。 |
| 是否能回答架構? | 通過 | README architecture + compose + Caddyfile。 |
| 是否能回答啟動方式? | 通過 | README Startup + final demo checklist。 |
| 是否能回答備份方式? | 通過 | backup-restore-runbook + 90 天 restore drill。 |
| 是否能回答風險? | 通過 | Week 17 cards + Week 18 cost-risk + Week 20 risk register。 |
| 是否能回答如何更新? | 通過 | update-runbook + monthly patch cadence。 |
| 是否能回答何時擴展? | 通過 | Week 16 scaling ladder + Week 20 scaling gate。 |
| 是否能排出 90 天導入優先順序? | 通過 | 90 天維運節奏 + adoption candidates and owners。 |
| question | answer | evidence | status |
|---|---|---|---|
| Why choose this route? | It balances handoff readiness, fixed baseline cost, PostgreSQL durability, DNS/TLS clarity, backup discipline, and a gradual scaling path. | README.md;docs/week-18-platform-selection-cost-risk.md | pass |
| Where are the risks? | Risks are wrong webhook URL, lost credentials, database connection failure, secure cookie behavior, execution data growth, binary data storage, update failure, logs, and cost drift. | week-17-troubleshooting-cards.json;week-18-cost-risk-worksheet.csv;final-recommendation-report.md | pass |
| How do we back up? | Back up PostgreSQL, n8n_data, Caddy state, .env, N8N_ENCRYPTION_KEY, and deployment files, then prove restore through readiness, credential decryption, and webhook execution. | backup-restore-runbook.md;week-20-90-day-maintenance-cadence.csv | pass |
| question | answer | evidence | status |
|---|---|---|---|
| How do we update? | Review release notes, back up, record previous image tag, update in a maintenance window, verify health/readiness and workflow execution, then roll back if needed. | update-runbook.md;week-20-90-day-maintenance-cadence.csv | pass |
| When do we scale? | Scale after metrics show sustained pressure. Apply pruning and concurrency control first; evaluate queue mode after PostgreSQL, logs, backup, RPO/RTO, and owner readiness are stable. | week-16-scaling-ladder.json;week-20-adoption-candidates-and-owners.csv | pass |
| finalArtifacts | 用途 |
|---|---|
artifacts/week-20-final/final-recommendation-report.md | 最終建議報告,回答 route、risk、backup、update、scale。 |
artifacts/week-20-final/week-20-90-day-maintenance-cadence.csv | 90-day maintenance 節奏,安排 owner、活動、證據、acceptance gate。 |
artifacts/week-20-final/week-20-adoption-candidates-and-owners.csv | 導入候選清單與 owner,將下一步拆成 P0-P3。 |
artifacts/week-20-final/week-20-three-hour-showcase-agenda.json | 三小時成果交流 agenda,定義每段 evidence 與 required answer。 |
| 階段 | nextStageDecision |
|---|---|
| days1to14 | Stabilize baseline, owners, secrets, backup, restore. |
| days15to30 | Operate safely with update window, security audit, logs, cost baseline. |
| days31to60 | Measure execution data, DB growth, workflow risk, memory, CPU, storage. |
| days61to90 | Decide whether to stay baseline, move to n8n Cloud/PaaS, evaluate queue mode, or prepare AWS/GCP with explicit RPO/RTO and FinOps. |
| 驗收條件 | 結果 | 證據 |
|---|---|---|
| 完成最終建議報告 | 通過 | final-recommendation-report.md |
| 完成 90 天維運節奏 | 通過 | week-20-90-day-maintenance-cadence.csv |
| 完成導入候選清單與 owner | 通過 | week-20-adoption-candidates-and-owners.csv |
| 完成 3 小時成果交流 | 通過 | week-20-three-hour-showcase-agenda.json |
| 能回答為什麼選這條路 | 通過 | 第 20.3、20.6 節 |
| 能回答風險在哪 | 通過 | 第 20.3、20.5、20.6 節 |
| 能回答如何備份 | 通過 | 第 20.3、20.4、20.6 節 |
| 能回答如何更新 | 通過 | 第 20.3、20.4、20.6 節 |
| 能回答何時擴展 | 通過 | 第 20.3、20.5、20.6 節 |
20 週的最終成果不是一個跑起來的 n8n instance,而是一套可交接的部署判斷能力:能從 user type 選平台,能從 state 判斷資料風險,能用 DNS/TLS 正確公開 webhook,能用 PostgreSQL 保存 production state,能備份與還原,能用 runbook 排查事故,能在成本和維運責任之間做選擇,最後能把下一階段導入拆成 owner、節奏與驗收指標。
這份報告最後要服務的不是單次部署,而是後續每一次導入決策。只要能回答「為什麼、風險、備份、更新、擴展」,n8n 才真正從工具變成可維運的自動化平台。
After Week 20
每週先讀導讀,再照製作任務完成本週交付物,最後展開完整原文核對所有細節與來源。
用 Week 19 的 deployment package 當基準,把 README、compose、env、Caddyfile、runbook 與 checklist 交給下一位 owner。
用 Week 18 與 Week 20 的 scorecard 排出 Cloud、VPS、PaaS、hyperscaler 與 Enterprise 的採用順序。
把 Week 14 的 backup/update runbook、Week 15 的 patch cadence、Week 16 的 scaling signals 放進 90 天維運節奏。
這套 n8n 部署課程的成果,不是只有把服務跑起來,而是能回答:為什麼選這條部署路線、資料在哪裡、public URL 是否正確、如何備份還原、如何更新修補、出事如何排查、成本風險如何說明、下一階段誰負責。