n8n 從 Zeabur 搬到 VPS:encryption key 沒抄到,credentials 就全毀(實測)

n8n 搬家最容易出事的是 N8N_ENCRYPTION_KEY。實測發現用錯的 key 匯入時,n8n 一樣會顯示成功。這篇整理怎麼找到 key、怎麼匯出匯入,以及可以直接用的 Docker Compose 加 Caddy 設定。

重點

  • n8n 的 credentials 用 encryption key 加密,換了 key 就全部解不開。
  • key 在環境變數 N8N_ENCRYPTION_KEY,或 n8n 資料夾裡的 config 檔。
  • 實測:用錯 key 匯入時 n8n 仍顯示成功,要用 export:credentials --decrypted 驗證。
  • 本文附可直接使用的 Docker Compose + Caddy 設定(自動 HTTPS)。
這篇怎麼驗證的?(4 項實測、3 項依官方文件)
實際跑過
  • n8n 2.43.7 官方映像:export:workflow、export:credentials 匯出,再匯入到新的 n8n
  • 同一把 encryption key:credentials 解密成功;換一把 key:匯入時顯示成功,但之後解不開
  • 沒設定環境變數時,n8n 會自動產生 key,寫進 /home/node/.n8n/config
  • 本文的 docker-compose.yml 與 Caddyfile:本機以 n8n.localhost 啟動,經 Caddy 的 HTTPS 連到 n8n,healthz 回 200
依官方文件撰寫、未實際操作
  • 在 Zeabur 控制台執行指令、下載檔案的介面:依 Zeabur 官方文件撰寫,我們沒有在 Zeabur 上操作
  • Zeabur 的 n8n 模板把資料放在哪個路徑、用 SQLite 還是 PostgreSQL:請以你服務的實際設定為準
  • 正式網域自動申請 Let's Encrypt 憑證:本機測試用的是 Caddy 的自簽憑證;正式環境的行為依 Caddy 官方文件
目錄(6 節)
  1. 最重要的一件事:找到你的 encryption key
  2. 第 1 步:在 Zeabur 上匯出
  3. 第 2 步:在 VPS 上架好新的 n8n
  4. 第 3 步:匯入
  5. 第 4 步:驗證 credentials 真的解得開
  6. 第 5 步:收尾

最重要的一件事:找到你的 encryption key

n8n 存的每一組 credentials(API key、OAuth token、資料庫密碼)都用一把 encryption key 加密。換了一台機器,key 不同,所有 credentials 都解不開,只能一個一個重新設定。

key 會出現在兩個地方之一:

  1. 環境變數 N8N_ENCRYPTION_KEY:到 Zeabur 服務的「環境變數」頁面找
  2. n8n 資料夾裡的 config 檔:沒設定環境變數時,n8n 第一次啟動會自動產生 key 並寫進這個檔。官方映像的路徑是 /home/node/.n8n/config,內容長這樣:
{
	"encryptionKey": "一串隨機字元"
}

把 key 抄下來,存在密碼管理器裡。

實測發現的陷阱:用錯 key 匯入,n8n 不會報錯。

我們用 KEY_A 匯出 credentials,再匯入到一台設定成 KEY_B 的 n8n,畫面顯示 Successfully imported 1 credential.,看起來一切正常。等到要使用時才出現:

Credentials could not be decrypted. The likely reason is that a different "encryptionKey" was used to encrypt the data.

所以搬完一定要做下面「第 4 步」的驗證,不要相信匯入成功的訊息。

第 1 步:在 Zeabur 上匯出

依 Zeabur 文件,服務的「服務狀態」分頁裡有「指令」區塊,可以在容器裡執行指令。把 workflow 和 credentials 匯出到 n8n 資料夾:

n8n export:workflow --all --output=/home/node/.n8n/workflows.json
n8n export:credentials --all --output=/home/node/.n8n/credentials.json

同一個分頁裡的「檔案」區塊可以瀏覽和下載容器裡的檔案,把這兩個檔案和 config 下載回來。

匯出的 credentials.json 是加密過的,打開看不到明文密碼。實測時,我們設定的 SECRET123 在檔案裡完全搜尋不到。所以它一定要搭配原本那把 key 才有用。

另一個做法:整包備份 Volume。 如果你的 n8n 用內建的 SQLite(資料夾裡會有 database.sqlite),可以用 Zeabur「備份」分頁的離線備份,把整個資料夾打包下載。依 Zeabur 文件,離線備份要先暫停服務,這是對的:SQLite 執行中會有 -wal 暫存檔,不暫停就複製,資料可能不完整。

第 2 步:在 VPS 上架好新的 n8n

開一台 Ubuntu VPS 並安裝 Docker,把網域(例如 n8n.example.com)的 A 記錄指到 VPS 的 IP,然後建立這兩個檔案:

# docker-compose.yml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    environment:
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}   # 沿用 Zeabur 上那把
      - N8N_HOST=n8n.example.com
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://n8n.example.com/
    volumes:
      - n8n_data:/home/node/.n8n
  caddy:
    image: caddy:2
    restart: unless-stopped
    ports: ["80:80", "443:443"]
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
volumes:
  n8n_data:
  caddy_data:
# Caddyfile
n8n.example.com {
  reverse_proxy n8n:5678
}
echo "N8N_ENCRYPTION_KEY=從 Zeabur 抄來的 key" > .env
docker compose up -d

Caddy 會自動申請 HTTPS 憑證,前提是 DNS 已經指到這台 VPS,而且 80 和 443 port 對外開放。n8n 跑在反向代理後面時,n8n 文件要求設定 WEBHOOK_URL,讓它產生的 Webhook 網址是對外的正確網址。

第 3 步:匯入

docker compose cp workflows.json n8n:/tmp/
docker compose cp credentials.json n8n:/tmp/
docker compose exec n8n n8n import:workflow --input=/tmp/workflows.json
docker compose exec n8n n8n import:credentials --input=/tmp/credentials.json

第 4 步:驗證 credentials 真的解得開

docker compose exec n8n n8n export:credentials --all --decrypted --output=/tmp/check.json
docker compose exec n8n cat /tmp/check.json
  • 看得到明文內容:key 正確
  • 出現 Credentials could not be decrypted:key 不對,回頭確認第一節

看完立刻刪掉這個檔案,裡面是明文密碼:

docker compose exec n8n rm /tmp/check.json /tmp/credentials.json

第 5 步:收尾

  • 打開每個 workflow,確認觸發器正常;有用 Webhook 觸發的,到對方服務(LINE、Stripe、表單工具)把網址改成新的
  • Zeabur 發生過資安事件,credentials 裡的第三方 API key 建議全部換新(見資安篇)
  • 設定每日備份:至少每天把 n8n_data 這個 volume 打包,傳到別的地方存放

Dify、LobeChat 這類由多個服務組成的工具,用它們官方 repo 提供的 docker-compose.yml,再照同樣方式加上 Caddy 即可。資料庫的搬法見資料庫篇。

常見問題

n8n 的 encryption key 在哪裡?

設定了環境變數 N8N_ENCRYPTION_KEY 的話就在那裡;沒有設定時,n8n 會自動產生並寫進 n8n 資料夾的 config 檔(官方映像為 /home/node/.n8n/config)。

n8n 匯入 credentials 顯示成功,為什麼還是不能用?

因為 encryption key 不同。n8n 匯入時不會檢查 key 是否正確,要等使用時才出現 Credentials could not be decrypted。請沿用原本的 key 重新匯入。