diff --git a/blueprints/n8n-queue/docker-compose.yml b/blueprints/n8n-queue/docker-compose.yml new file mode 100644 index 00000000..f0b601d1 --- /dev/null +++ b/blueprints/n8n-queue/docker-compose.yml @@ -0,0 +1,124 @@ +services: + postgres: + image: postgres:17-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}"] + start_period: 30s + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + restart: unless-stopped + command: redis-server --requirepass ${REDIS_PASSWORD} + environment: + - REDIS_PASSWORD=${REDIS_PASSWORD} + volumes: + - redis_data:/data + healthcheck: + test: ["CMD-SHELL", "redis-cli -a \"$$REDIS_PASSWORD\" ping | grep PONG"] + start_period: 20s + interval: 10s + timeout: 5s + retries: 5 + + # Main instance: serves the editor UI and webhooks, publishes executions + # to the Redis (Bull) queue instead of running them itself. + n8n: + image: n8nio/n8n:2.30.4 + restart: unless-stopped + environment: + # PostgreSQL + - 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} + + # Queue mode (Redis / Bull) + - EXECUTIONS_MODE=queue + - QUEUE_BULL_REDIS_HOST=redis + - QUEUE_BULL_REDIS_PORT=6379 + - QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD} + - QUEUE_HEALTH_CHECK_ACTIVE=true + - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true + + # Encryption key shared between the main instance and the workers + - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} + + # Networking + - N8N_HOST=${N8N_HOST} + - N8N_PORT=5678 + - N8N_PROTOCOL=http + - N8N_PROXY_HOPS=1 + - NODE_ENV=production + - N8N_WEBHOOK_URL=https://${N8N_HOST}/ + - N8N_EDITOR_BASE_URL=https://${N8N_HOST}/ + - GENERIC_TIMEZONE=${GENERIC_TIMEZONE} + - N8N_SECURE_COOKIE=false + volumes: + - n8n_data:/home/node/.n8n + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1:5678/healthz"] + start_period: 60s + interval: 10s + timeout: 5s + retries: 10 + + # Queue workers: pull executions from Redis and run them. Scale them by + # changing the N8N_WORKER_REPLICAS environment variable and redeploying. + n8n-worker: + image: n8nio/n8n:2.30.4 + restart: unless-stopped + command: worker + deploy: + replicas: ${N8N_WORKER_REPLICAS:-2} + environment: + # PostgreSQL + - 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} + + # Queue mode (Redis / Bull) + - EXECUTIONS_MODE=queue + - QUEUE_BULL_REDIS_HOST=redis + - QUEUE_BULL_REDIS_PORT=6379 + - QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD} + - QUEUE_HEALTH_CHECK_ACTIVE=true + + # Must be the same key as the main instance + - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY} + + - NODE_ENV=production + - GENERIC_TIMEZONE=${GENERIC_TIMEZONE} + depends_on: + n8n: + condition: service_healthy + healthcheck: + test: ["CMD-SHELL", "wget --spider -q http://127.0.0.1:5678/healthz"] + start_period: 60s + interval: 10s + timeout: 5s + retries: 10 + +volumes: + postgres_data: + redis_data: + n8n_data: diff --git a/blueprints/n8n-queue/instructions.md b/blueprints/n8n-queue/instructions.md new file mode 100644 index 00000000..782571b8 --- /dev/null +++ b/blueprints/n8n-queue/instructions.md @@ -0,0 +1,24 @@ +# n8n Queue Mode + +This template runs n8n in [queue mode](https://docs.n8n.io/hosting/scaling/queue-mode/): + +- **n8n** (main): serves the editor UI and receives webhooks/triggers, then publishes executions to the queue. +- **n8n-worker** (x2 by default): pulls executions from the Redis (Bull) queue and runs them. +- **redis**: the message broker for the queue (password protected). +- **postgres**: stores workflows, credentials and execution data. + +All n8n containers share the same `N8N_ENCRYPTION_KEY` (generated automatically), which is required for workers to decrypt credentials. + +## Scaling workers + +Worker replicas are controlled by the `N8N_WORKER_REPLICAS` environment variable (default `2`): + +1. Open the compose service in Dokploy and go to the **Environment** tab. +2. Change `N8N_WORKER_REPLICAS` to the number of workers you want. +3. Redeploy. Docker Compose will scale the `n8n-worker` service to the requested number of replicas. + +Each worker runs up to 10 concurrent executions by default. You can tune this by adding `N8N_CONCURRENCY_PRODUCTION_LIMIT` to the worker environment. + +## Optional: dedicated webhook processors + +For very high webhook volumes, n8n supports dedicated webhook processor instances (`command: webhook`). To use them, add another service to the compose file with the same environment as `n8n-worker` but with `command: webhook`, and route the `/webhook/` path of your domain to it. See the [n8n queue mode docs](https://docs.n8n.io/hosting/scaling/queue-mode/#webhook-processors) for details. diff --git a/blueprints/n8n-queue/meta.json b/blueprints/n8n-queue/meta.json new file mode 100644 index 00000000..e0ada259 --- /dev/null +++ b/blueprints/n8n-queue/meta.json @@ -0,0 +1,18 @@ +{ + "id": "n8n-queue", + "name": "n8n Queue Mode", + "version": "2.30.4", + "description": "n8n running in queue mode for high-throughput production workloads: the main instance handles the editor and webhooks while a scalable pool of workers executes workflows from a Redis (Bull) queue, backed by PostgreSQL.", + "logo": "n8n.png", + "links": { + "github": "https://github.com/n8n-io/n8n", + "website": "https://n8n.io/", + "docs": "https://docs.n8n.io/hosting/scaling/queue-mode/" + }, + "tags": [ + "automation", + "workflow", + "low-code", + "queue" + ] +} diff --git a/blueprints/n8n-queue/n8n.png b/blueprints/n8n-queue/n8n.png new file mode 100644 index 00000000..0e9a607e Binary files /dev/null and b/blueprints/n8n-queue/n8n.png differ diff --git a/blueprints/n8n-queue/template.toml b/blueprints/n8n-queue/template.toml new file mode 100644 index 00000000..46ce3fbe --- /dev/null +++ b/blueprints/n8n-queue/template.toml @@ -0,0 +1,33 @@ +[variables] +main_domain = "${domain}" +postgres_user = "${username}" +postgres_password = "${password:24}" +postgres_db = "n8n" +redis_password = "${password:24}" +n8n_encryption_key = "${base64:32}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "n8n" +port = 5_678 +host = "${main_domain}" + +[config.env] +N8N_HOST = "${main_domain}" +GENERIC_TIMEZONE = "Europe/Berlin" + +# Number of queue workers. Change it and redeploy to scale. +N8N_WORKER_REPLICAS = "2" + +# PostgreSQL +POSTGRES_USER = "${postgres_user}" +POSTGRES_PASSWORD = "${postgres_password}" +POSTGRES_DB = "${postgres_db}" + +# Redis (Bull queue) +REDIS_PASSWORD = "${redis_password}" + +# Encryption key shared by the main instance and the workers (IMPORTANT) +N8N_ENCRYPTION_KEY = "${n8n_encryption_key}"