今日目標:用 Docker Compose 在本機 run Postgres + Redis Cluster(3主3從) + n8n Main + n8n Worker,驗證 Queue Mode。
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: n8n
POSTGRES_DB: n8n
volumes:
- pgdata:/var/lib/postgresql/data
# --- Redis Cluster (3 masters + 3 replicas) ---
# 密碼:bitnami;所有節點互相認得彼此的主機名(service name)
redis-node-0:
image: docker.io/bitnami/redis-cluster:7.4
environment:
- REDIS_PASSWORD=bitnami
- REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
# 若要用 redis-cli 測,開放一個節點的 6379 方便連
ports:
- "6379:6379"
redis-node-1:
image: docker.io/bitnami/redis-cluster:7.4
environment:
- REDIS_PASSWORD=bitnami
- REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
redis-node-2:
image: docker.io/bitnami/redis-cluster:7.4
environment:
- REDIS_PASSWORD=bitnami
- REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
redis-node-3:
image: docker.io/bitnami/redis-cluster:7.4
environment:
- REDIS_PASSWORD=bitnami
- REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
redis-node-4:
image: docker.io/bitnami/redis-cluster:7.4
environment:
- REDIS_PASSWORD=bitnami
- REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
# 叢集建立者(等前 5 個起來,再建立 3 主 3 從)
redis-node-5:
image: docker.io/bitnami/redis-cluster:7.4
depends_on:
- redis-node-0
- redis-node-1
- redis-node-2
- redis-node-3
- redis-node-4
environment:
- REDIS_PASSWORD=bitnami
- REDISCLI_AUTH=bitnami
- REDIS_CLUSTER_REPLICAS=1
- REDIS_NODES=redis-node-0 redis-node-1 redis-node-2 redis-node-3 redis-node-4 redis-node-5
- REDIS_CLUSTER_CREATOR=yes
# (可選)RedisInsight:用網頁看 cluster
redis-insight:
image: redis/redisinsight:latest
restart: always
ports:
- "5540:5540"
n8n-main:
image: n8nio/n8n:latest
depends_on:
- postgres
- redis-node-5
ports:
- "5678:5678"
environment:
N8N_ENCRYPTION_KEY: changeme-super-secret
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: n8n
EXECUTIONS_MODE: queue
# --- Redis Cluster 連線(逗號分隔 host:port)---
QUEUE_BULL_REDIS_CLUSTER_NODES: "redis-node-0:6379,redis-node-1:6379,redis-node-2:6379"
QUEUE_BULL_REDIS_PASSWORD: "bitnami"
QUEUE_BULL_REDIS_USERNAME: "default"
# 僅 main 啟用 triggers/webhooks
N8N_RUNNERS_ENABLED: "false"
n8n-worker:
image: n8nio/n8n:latest
depends_on:
- postgres
- redis-node-5
- n8n-main
environment:
N8N_ENCRYPTION_KEY: changeme-super-secret
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_PORT: 5432
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: n8n
EXECUTIONS_MODE: queue
# --- 同樣使用 Cluster 連線 ---
QUEUE_BULL_REDIS_CLUSTER_NODES: "redis-node-0:6379,redis-node-1:6379,redis-node-2:6379"
QUEUE_BULL_REDIS_PASSWORD: "bitnami"
QUEUE_BULL_REDIS_USERNAME: "default"
N8N_DISABLE_PRODUCTION_MAIN_PROCESS: "true"
command: ["worker"]
volumes:
pgdata:
docker compose pull
docker compose up -d
docker compose ps
# 觀察叢集建立(看 redis-node-5)
docker compose logs -f redis-node-5 # 出現 "Cluster correctly created" 類訊息即可 Ctrl+C
http://localhost:5678
建立帳號const tz = 'Asia/Taipei';
const now = new Date();
const formatted = new Intl.DateTimeFormat('zh-TW', { timeZone: tz, dateStyle: 'medium', timeStyle: 'medium', hourCycle: 'h23' }).format(now);
console.log(`[Time][${tz}]`, formatted);
return [{ message: '報時', tz, nowIso: now.toISOString(), nowLocal: formatted }];
docker compose logs -f n8n-worker
console.log
→ 完成。docker compose stop n8n-worker
# 在 UI 點一次 Execute once
docker compose exec redis-node-0 redis-cli -a bitnami -c --scan --pattern "bull:*:wait" \
| xargs -I{} sh -c 'echo -n "{} => "; docker compose exec -T redis-node-0 redis-cli -a bitnami -c LLEN {}'
# 看到 wait > 0 就代表任務在 Queue 中等 Worker 接手
docker compose start n8n-worker
docker compose logs -f n8n-worker # 會把剛剛的 workflow 任務慢慢消耗掉
docker compose up -d --scale n8n-worker=3
docker compose ps
觀察日誌會看到 3 個 Worker 輪流去跟 n8n main 拿取任務。
lsof -i :5678/:6379
殺掉舊程式或修改 port mapping。bitnami/redis-cluster image
如果拉不到:改 :latest
;或改官方 redis:7
+ 自建 cluster。N8N_DISABLE_PRODUCTION_MAIN_PROCESS=true
是否只在 worker;Main 有 N8N_RUNNERS_ENABLED=false
。WEBHOOK_URL
(含協定/網域/子路徑)。docker compose down
docker compose down -v # 連 volumes 一起清(會刪 DB)