N8N Docker Docker Compose 環境變數 Nginx 自架 部署

Docker Compose 檔案詳解:N8N 環境變數、資料卷、反向代理完整說明

逐行拆解 N8N 的 Docker Compose 設定檔:每個環境變數的意義、資料卷的設計邏輯、Nginx 反向代理的關鍵設定,讓你知道自己在設定什麼。

N8NMarket 2026年4月22日

Docker Compose 檔案詳解:N8N 環境變數、資料卷、反向代理完整說明

「照著教學做完了,但不知道每個設定在做什麼。」這篇是「N8N Docker 自架完全攻略」的深入補充,如果你還沒跑過自架流程,建議先讀那篇。

這是很多人自架 N8N 之後的狀態。能跑,但下次出問題不知道怎麼改。

這篇文章的目的很簡單:把 N8N Docker Compose 設定檔裡每一個關鍵設定逐一解釋清楚,讓你從「會照著做」升級到「知道在做什麼」。


完整的 docker-compose.yml 範本

先把完整的設定檔放在這裡,後面逐段說明:

version: "3.8"

services:
  postgres:
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d n8n"]
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      - N8N_HOST=${N8N_HOST}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${N8N_HOST}/
      - GENERIC_TIMEZONE=Asia/Taipei
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=${POSTGRES_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=168
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  n8n_data:
  postgres_data:

環境變數逐一說明

基本設定類

N8N_HOST:你的 N8N 網域名稱,例如 n8n.example.com。N8N 用這個值來判斷哪些請求是給它的,也用在某些節點生成回呼 URL 時。

N8N_PORT:N8N 監聽的 Port,預設 5678。因為我們用 Nginx 做反向代理,外部 user 不會直接連這個 port,但 N8N 內部需要知道自己跑在哪個 port。

N8N_PROTOCOL:設定 https,告訴 N8N 它對外是透過 HTTPS 提供服務。這影響到 N8N 生成的 Webhook URL 是 http:// 還是 https://。

NODE_ENV=production:啟用生產環境模式,關閉開發模式的 debug 輸出,效能更好。

WEBHOOK_URL:Webhook 的基礎 URL。當你在 N8N 建立一個 Webhook 節點,它生成的 URL 會是 WEBHOOK_URL + /webhook/xxxxx。一定要設定正確,否則外部服務呼叫 Webhook 會失敗。格式:https://你的網域/(結尾一定要有斜線)。

GENERIC_TIMEZONE:N8N 的時區設定。影響 Schedule Trigger 的執行時間、流程裡的時間格式。台灣用 Asia/Taipei

安全設定類

N8N_ENCRYPTION_KEY:用來加密儲存在資料庫裡的憑證(OAuth Token、API Key 等)。這是最重要的安全設定。一旦設定了就不要改,改了之後所有已存的憑證都會無法解密。

生成一個強的隨機字串的方法:

openssl rand -hex 32

把這個值填進 .env 裡的 N8N_ENCRYPTION_KEY

資料庫設定類

DB_TYPE=postgresdb:告訴 N8N 使用 PostgreSQL 而不是預設的 SQLite。

DB_POSTGRESDB_HOST=postgres:資料庫的主機名稱。在 Docker Compose 裡,服務之間用 service 名稱互相連接(不是 IP),所以這裡填的是 postgres 這個 service 的名字。

DB_POSTGRESDB_PORT=5432:PostgreSQL 的預設 Port。

DB_POSTGRESDB_DATABASE=n8n:N8N 使用的資料庫名稱。

DB_POSTGRESDB_USERDB_POSTGRESDB_PASSWORD:資料庫的使用者名稱和密碼,要和 postgres service 裡設定的一致。

執行資料管理類

EXECUTIONS_DATA_PRUNE=true:自動清理舊的執行記錄。如果不開啟,執行記錄會一直累積,資料庫會越來越大。

EXECUTIONS_DATA_MAX_AGE=168:保留最近幾小時的執行記錄,168 小時等於 7 天。超過這個時間的記錄會被自動刪除。


資料卷(Volumes)說明

Docker Volume 是讓容器的資料在容器重啟或更新後繼續保留的機制。如果不用 Volume,容器關掉資料就消失了。

n8n_data

掛載到容器裡的 /home/node/.n8n 路徑。

這個目錄存放 N8N 的 SQLite 資料庫(如果你用 SQLite 模式)、N8N 的 config 檔案、以及某些節點的臨時檔案。

如果你用 PostgreSQL 模式,資料庫本身存在 postgres_data volume 裡,n8n_data 就只存 config 檔案。

postgres_data

掛載到 postgres 容器的 /var/lib/postgresql/data

這裡存放 PostgreSQL 的所有資料,包括所有的工作流程、執行記錄、憑證(加密後的)。這個 volume 是你最重要的備份對象。

ports 設定的細節

在範本裡,ports 設定是 127.0.0.1:5678:5678 而不是 5678:5678

5678:5678:把容器的 5678 port 綁定到「所有網路介面」,代表任何 IP(包括外部網路)都可以直接連到這個 port。

127.0.0.1:5678:5678:只把 port 綁定到 localhost,代表只有同一台機器上的程式(比如 Nginx)可以連到這個 port,外部網路連不到。

因為我們用 Nginx 做反向代理,外部流量應該只走 Nginx 的 80/443 port,N8N 的 5678 port 不應該暴露給外部網路。使用 127.0.0.1:5678:5678 是更安全的做法。

depends_on 與 healthcheck

depends_on:
  postgres:
    condition: service_healthy

這個設定讓 N8N 等 postgres 服務「健康」之後才啟動,而不是只等 postgres 容器「啟動」。

差別:容器啟動和服務準備好是不同的。PostgreSQL 容器啟動後可能還需要幾秒鐘才真正可以接受連線。如果 N8N 太早嘗試連資料庫,會連線失敗然後崩潰。

service_healthy 搭配 healthcheck 設定,確保 postgres 真正準備好接受連線後,N8N 才啟動。


Nginx 反向代理設定詳解

server {
    server_name n8n.example.com;

    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;

        # WebSocket 支援(N8N 的即時介面需要)
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';

        # 傳遞原始請求資訊
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # 關閉 Nginx 的緩衝(N8N 的 SSE 事件流需要)
        proxy_cache_bypass $http_upgrade;
        chunked_transfer_encoding off;
        proxy_buffering off;
        proxy_request_buffering off;

        # 增加 timeout(長時間執行的流程需要)
        proxy_read_timeout 3600s;
        proxy_connect_timeout 3600s;
        proxy_send_timeout 3600s;
    }

    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
}

server {
    listen 80;
    server_name n8n.example.com;
    return 301 https://$host$request_uri;
}

逐行說明幾個關鍵設定:

proxy_http_version 1.1 加 WebSocket headers:N8N 的介面用 WebSocket 做即時更新(你在跑測試時看到節點即時顯示結果就是 WebSocket 在做的)。這兩行設定讓 Nginx 支援 WebSocket 的 Upgrade 請求,沒有這個設定,N8N 介面會有功能問題。

proxy_buffering offchunked_transfer_encoding off:N8N 用 Server-Sent Events(SSE)串流傳送執行狀態。如果 Nginx 把回應緩衝起來,你的介面會看不到即時更新。關閉緩衝讓資料直接傳到瀏覽器。

proxy_read_timeout 3600s:N8N 的某些流程執行時間可能很長(比如等待一個 Webhook 回應、或 AI 推理時間長)。預設的 Nginx timeout 是 60 秒,超過就切斷連線。設成 3600 秒(1 小時)避免長時間流程被中斷。

X-Forwarded-ForX-Forwarded-Proto:告訴 N8N 真實的請求來源 IP 和協議。這影響到 N8N 的安全日誌記錄和某些需要知道客戶端 IP 的場景。


多 Worker 設定(進階)

如果你的 N8N 流程很多、執行頻率高,單一個 N8N 進程可能成為瓶頸。可以設定多個 Worker 並行處理任務。

這需要加入 Redis 作為任務 Queue:

services:
  redis:
    image: redis:7-alpine
    restart: always
    volumes:
      - redis_data:/data

  n8n:
    # ... 原本的設定 ...
    environment:
      # ... 原本的環境變數 ...
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
    command: n8n start

  n8n-worker:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    environment:
      # 和 n8n service 一樣的環境變數
      - DB_TYPE=postgresdb
      - EXECUTIONS_MODE=queue
      - QUEUE_BULL_REDIS_HOST=redis
      - QUEUE_BULL_REDIS_PORT=6379
    command: n8n worker
    depends_on:
      - n8n
      - redis

volumes:
  redis_data:

EXECUTIONS_MODE=queue:把執行模式從「直接執行」改成「放進 Queue 等 Worker 處理」。

n8n start vs n8n worker:主服務跑 UI 和接收觸發,Worker 負責實際執行流程。可以啟動多個 Worker container 分攤工作:docker compose up -d --scale n8n-worker=2


.env 檔案完整範本

# N8N 基本設定
N8N_HOST=n8n.yourdomain.com

# 安全(用 openssl rand -hex 32 生成)
N8N_ENCRYPTION_KEY=your_random_32_char_key_here

# 資料庫
POSTGRES_USER=n8n
POSTGRES_PASSWORD=your_strong_db_password

.env 檔案放在和 docker-compose.yml 同一個目錄下,Docker Compose 啟動時會自動讀取。

不要把 .env 加進 git commit,在 .gitignore 加入:

.env
*.env

設定完之後的驗證清單

N8N 介面可以用 HTTPS 正常存取:瀏覽器地址欄應該有鎖頭圖示。

Webhook URL 正確:在 N8N 新建一個 Webhook 節點,看它生成的 URL 是不是 https://你的網域/webhook/xxxxx

流程可以正常儲存和執行:新建一個簡單的流程(Manual Trigger → Set → 看輸出),確認執行沒有錯誤。

執行記錄有保存:跑完流程後去 Executions 看,應該有一筆記錄。

備份腳本有在跑:手動執行備份腳本,確認 /tmp 下有生成 tar.gz 備份檔案。

這五個確認點都過了,你的自架 N8N 就算正式上線了。

有設定上的問題或看不懂哪個環境變數的意思?留言告訴我,我來解釋。

自架完成後前往 N8Nstart 模板庫 匯入第一批流程。Docker 官方文件N8N 官方文件 — Self-hosting 是最完整的技術參考。


延伸閱讀