9 хв читанняІнтеграції

Самостійно розгорнута автоматизація посилань на n8n: від Docker до вебхуків

Запустіть самостійно розгорнуту автоматизацію посилань n8n з вебхуками Elido, Docker Compose і режимом черги, тримаючи дані робочих процесів на інфраструктурі, яку контролюєте ви, в ЄС.

Marius Voß
DevRel · edge infra
Самостійно розгорнута автоматизація n8n для посилань: вебхуки Elido проходять через зворотний проксі в інстанс n8n з чергою і воркерами, все всередині інфраструктури, яку контролюєте ви

Самостійно розгорнута автоматизація посилань на n8n означає три речі, що працюють на серверах, які контролюєте ви: інстанс n8n у Docker, публічна кінцева точка HTTPS, що отримує події webhook від Elido, і вихідні виклики назад до API Elido з токеном обмеженого доступу. Події посилань і доменів надходять підписаними, а події для кожного кліку - в дорожній карті. Ваші робочі процеси вирішують, що робити далі, а журнали виконань ніколи не покидають вашу інфраструктуру.

Це вся архітектура. Решта цього матеріалу - те, що пропускають швидкі старти: як провести вебхуки через зворотний проксі, як перевірити підпис, щоб сторонній не міг запустити ваші робочі процеси, що змінює режим черги, і коли n8n Cloud - чесно кажучи, кращий вибір. Я запускаю це налаштування на одній невеликій VM, і всі рухомі частини вміщуються на одному екрані.

Якщо ви хочете тримати самі посилання на власному залізі теж, це окреме і набагато більше завдання. Playbook самостійного розгортання Elido на k3s розглядає саме це. Тут Elido лишається керованим, і лише рівень автоматизації переїжджає всередину компанії.

Чому самостійно розгортати n8n для автоматизації посилань

Звична причина - дані. Робочий процес n8n self hosted url shortener бачить кожен payload, що обробляє: цільову URL-адресу, теги, іноді назву кампанії, що каже більше, ніж хотілося б, і країну, пристрій і реферер, якщо ви підтягуєте туди аналітику кліків. На n8n Cloud ці виконання зберігаються на чужих серверах за чужими стандартними термінами зберігання. Самостійно розгорнуті, вони лежать у вашому Postgres, у регіоні, який обрали ви.

Згідно з статтею 28 GDPR кожен оброблювач, що торкається персональних даних, потребує договору і місця у ваших записах. Менше оброблювачів - менше документообігу. Якщо ваші маркетингові дані вже мають лишатися в ЄС, гайд з резидентності даних в ЄС пояснює, чому рівень автоматизації важить так само, як і скорочувач.

Друга причина - структура витрат. n8n Cloud тарифікує за виконаннями, а активний тригер webhook чи часте опитування аналітики швидко витрачає виконання. Самостійно розгорнуто, виконання - це рядок у таблиці і кілька мілісекунд CPU.

Третя - досяжність. Самостійно розгорнутий інстанс перебуває в тій самій мережі, що й ваша база даних CRM чи внутрішній інструмент тікетів, тож подія посилання може потрапити в систему, яка ніколи не мала виходити в інтернет.

Стек Docker Compose

Мінімальний стек n8n docker link automation потребує чотирьох сервісів. Власний гайд з Docker Compose n8n - довідковий; це версія, з якої я почав би для роботи з посиланнями, з уже увімкненим режимом черги, щоб не мігрувати пізніше.

services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${PG_PASSWORD}
      POSTGRES_DB: n8n
    volumes: [pgdata:/var/lib/postgresql/data]

  redis:
    image: redis:7

  n8n:
    image: docker.n8n.io/n8nio/n8n
    env_file: .env.n8n
    ports: ["127.0.0.1:5678:5678"]
    depends_on: [postgres, redis]

  n8n-worker:
    image: docker.n8n.io/n8nio/n8n
    command: worker
    env_file: .env.n8n
    depends_on: [n8n]

volumes:
  pgdata:

І спільний файл середовища:

DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=change-me
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis
N8N_ENCRYPTION_KEY=generate-a-long-random-string
N8N_WEBHOOK_URL=https://n8n.example.com/
N8N_PROXY_HOPS=1

Два рядки важливіші, ніж здається. Ключ шифрування має бути ідентичним на головному процесі і кожному воркері, інакше воркери не зможуть розшифрувати облікові дані Elido, і кожне виконання провалиться із заплутаною помилкою авторизації. А порт 5678 прив'язаний лише до localhost, бо саме зворотний проксі має виходити в інтернет.

Архітектура самостійно розгорнутого n8n для автоматизації посилань: Elido надсилає підписані вебхуки через HTTPS на зворотний проксі, який пересилає їх головному процесу n8n, що ставить виконання в чергу в Redis для воркерів на базі Postgres, а воркери викликають API Elido назовні з токеном обмеженого доступу

Виклик API Elido з самостійно розгорнутого n8n

Вихідні виклики не потребують нічого понад те, що постачається разом з n8n. Створіть облікові дані Header Auth з назвою Authorization і значенням Bearer , за яким слідує API-ключ з дашборду Elido, а потім використовуйте їх з вбудованого вузла HTTP Request. n8n шифрує їх при зберіганні ключем з файла середовища, що є ще однією причиною, чому цей ключ має збігатися всюди.

Кожен маршрут посилань прив'язаний до робочого простору. Щоб скоротити URL-адресу, надішліть POST на https://api.elido.app/v1/workspaces/{workspace_id}/links з JSON-тілом:

{
  "domain_id": 12,
  "destination_url": "{{ $json.url }}",
  "title": "Spring launch",
  "tags": ["n8n", "spring"]
}

Не вказуйте slug, і Elido згенерує його сам. domain_id - це короткий домен, на якому живе посилання; GET на /v1/workspaces/{workspace_id}/domains перелічує ваші, і я б захардкодив ID у робочому процесі, а не шукав його на кожному запуску. GET на тому самому маршруті посилань перелічує посилання, а PATCH /v1/workspaces/{workspace_id}/links/{link_id} згодом змінює ціль чи теги.

Встановіть заголовок Idempotency-Key на POST, побудований з чогось стабільного в елементі, що запускає процес, наприклад ID рядка. Якщо n8n повторює вузол після таймауту, API відтворює першу відповідь замість створення другого посилання. Швидкий старт з API та SDK розглядає решту поверхні, а сторінка API та SDK знадобиться, якщо пізніше захочете перенести крок у код.

Є також пакетний community-вузол n8n-nodes-elido, покликаний обгорнути ці виклики в дружнішу форму. Він опублікований у npm (версія 0.2.0), але все ще опційний, і оскільки це неперевірений вузол, його можна встановити лише на самостійно розгорнутому n8n, а саме це налаштування й передбачає цей допис. Тримайте версію на HTTP Request як базову. Якщо ви таки встановлюєте community-пакети в режимі черги, пам'ятайте, що GUI встановлює лише в головний контейнер; воркери його ніколи не побачать. Починаючи з n8n 2.21, шлях встановлення через змінну середовища виправляє це, узгоджуючи кожен контейнер при запуску, хоча при першому запуску він видаляє все, чого немає в його списку.

Проведення вебхуків Elido через ваш зворотний проксі

Події йдуть у зворотний бік. Elido надсилає link.created, link.updated і domain.verified (серед інших) на кінцеву точку, яку ви реєструєте в Settings, Webhooks, а на самостійно розгорнутому n8n ця кінцева точка - продакшн-URL-адреса вузла Webhook. Подія click.created для кожного кліку - в дорожній карті, але ще не реалізована, тож наразі дані кліків надходять через заплановане опитування API аналітики. Повний список подій і структури payload - у довіднику вебхуки для подій посилань.

За проксі n8n будує свою URL-адресу webhook з власного протоколу, хоста і порту, а це означає, що він з радістю повідомить http://localhost:5678/webhook/... будь-кому, хто запитає. Сторінка конфігурації зворотного проксі коротка і варта повного прочитання: встановіть N8N_WEBHOOK_URL на вашу публічну адресу, встановіть N8N_PROXY_HOPS=1, і нехай останній проксі пересилає X-Forwarded-For, X-Forwarded-Host і X-Forwarded-Proto. Старіші гайди кажуть WEBHOOK_URL; поточні релізи досі його читають, але логують попередження про застарілість.

Nginx, Traefik, що завгодно, що ви вже використовуєте, підійде. Важливо, щоб на публічному боці був TLS і щоб шлях /webhook/* доходив до n8n без змін.

Одна деталь з таймінгом мене підвела. Elido чекає десять секунд на відповідь, перш ніж вважати доставку невдалою. Робочий процес, що пише в повільний API таблиць, а потім відповідає, може вийти за цю межу, отримати повтор і записати той самий рядок двічі. Налаштуйте вузол Webhook відповідати одразу і виконувати роботу вже потім.

Якщо ви налаштовуєте це для клієнта і хочете, щоб бік webhook хтось узяв на себе, сторінка функції вебхуків показує, на що можна підписатися, перш ніж щось будувати.

Перевірка підпису, перш ніж щось запуститься

Публічна URL-адреса webhook - це публічна URL-адреса. Будь-хто, хто її знайде, може надіслати POST з фальшивою подією і запустити ваш робочий процес, тож першим вузлом після тригера має бути перевірка підпису.

Кожна доставка Elido несе X-Webhook-Signature (значення v1= плюс hex-дайджест), X-Webhook-Timestamp в секундах Unix, X-Webhook-Event і X-Webhook-Delivery. Дайджест - це HMAC-SHA256 над міткою часу, крапкою і сирим тілом запиту, з ключем - секретом whsec_, показаним один раз при створенні кінцевої точки.

Спершу увімкніть Raw Body у вузлі Webhook. Це той крок, який люди пропускають. Якщо ви хешуєте JSON.stringify($json.body) замість точних байтів, які надіслав Elido, порядок ключів чи пробіли відрізняються, і кожен підпис провалюється, а ви витратите вечір, будучи впевненими, що секрет неправильний. Потім вузол Code:

const crypto = require("crypto");
const item = $input.first();
const h = item.json.headers;
const raw = (await this.helpers.getBinaryDataBuffer(0, "data")).toString(
  "utf8",
);

const ts = Number(h["x-webhook-timestamp"]);
if (Math.abs(Date.now() / 1000 - ts) > 300) throw new Error("stale delivery");

const expected =
  "v1=" +
  crypto
    .createHmac("sha256", $env.ELIDO_WEBHOOK_SECRET)
    .update(`${ts}.${raw}`)
    .digest("hex");
const got = h["x-webhook-signature"] || "";
if (
  got.length !== expected.length ||
  !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))
) {
  throw new Error("bad signature");
}
return [{ json: JSON.parse(raw) }];

Модуль crypto доступний у вузлі Code за замовчуванням, тож додаткова конфігурація там не потрібна. П'ятихвилинне вікно блокує повтори перехопленого запиту. Коли ви ротуєте секрет, Elido також надсилає X-Elido-Signature-Previous протягом пільгового періоду, тож ви можете приймати будь-який з двох ключів, поки оновлюєте змінну. У посібнику із перевірки підписів вебхуків є версія цього вузла, що перевіряє обидва заголовки, а також така сама перевірка в Node, Python і Go.

Перевірка підпису webhook у самостійно розгорнутому n8n: читання мітки часу і сирого тіла, відхилення доставок, старіших за 300 секунд, переобчислення HMAC-SHA256 над мітка часу крапка сире тіло з секретом кінцевої точки, порівняння за постійний час, потім або запуск робочого процесу, або зупинка виконання

Режим черги і повторні спроби

Із перевіркою підпису на місці, решта питання - що відбувається під навантаженням чи коли щось не працює. Тут задіяні дві системи повторних спроб, і вони покривають різні збої.

У режимі черги n8n головний процес отримує webhook, створює виконання і передає його ID в Redis; воркери забирають його звідти. Сплеск подій накопичується в черзі замість того, щоб затримувати HTTP-відповідь. Для більшого вхідного обсягу можна додати виділені обробники webhook за балансувальником навантаження, хоча для більшості навантажень з посиланнями одного головного процесу і двох воркерів цілком достатньо.

Бік Elido обробляє недоступність n8n. Будь-яка відповідь, відмінна від 2xx, чи таймаут повторюється через 1, 5 і 15 хвилин; після трьох спроб доставка позначається невдалою, і ви можете перезапустити її з дашборду. Це покриває перезапуск контейнера чи швидкий деплой. Це не покриває простій на вихідні, тому я б поєднав вебхуки з нічною звіркою, що перелічує посилання через API, як стверджує матеріал вебхуки проти опитування.

Використовуйте X-Webhook-Delivery як ключ ідемпотентності. Повтори перевикористовують його.

Самостійно розгорнутий n8n проти n8n Cloud: чесні компроміси

Я віддаю перевагу самостійному розгортанню для цього, але бачив, як команди про це шкодували. Ось порівняння без рекламної промови з жодного боку.

ПитанняСамостійно розгорнутий n8nn8n Cloud
Де живуть дані виконаньВаші сервери, ваш регіон, ваше зберіганняІнфраструктура і стандарти n8n
Доступ до внутрішніх системТа сама мережа, що й ваші CRM і бази данихЛише те, що ви публічно відкриваєте
Публічна URL-адреса webhook і TLSВи керуєте проксі і сертифікатамиНадається
Оновлення, резервні копії, патчіВаша робота, щомісяцяКерується постачальником
Вартість при високому обсязі подійФіксована вартість сервераМасштабується з кількістю виконань

Останній рядок б'є в обидва боки. Маленька VM дешева, але година інженера на зламаному оновленні - ні, а n8n випускає релізи часто. Якщо ніхто в команді не відповідає за сервер, Cloud з вузлом HTTP Request і REST API Elido - розумніший вибір, а рецепти Make і IFTTT чи гайд Zapier показують, як виглядає цей керований шлях на інших платформах.

Чого я не можу вам сказати - чи прийме ваш відповідальний за захист даних самостійно розгорнутий сервер як щось простіше за DPA вендора. За моїм досвідом зазвичай приймають, але це залежить від того, наскільки добре керується цей сервер. Про те, як працює сторона договору щодо скорочувача, почніть з гайду GDPR для URL-скорочувачів. А якщо ви готові налаштувати перший робочий процес, отримайте API-токен для робочого простору і спрямуйте на нього вузол Webhook.

Пов'язане в блозі

Поширені запитання

Чи можна використовувати URL-скорочувач із самостійно розгорнутим n8n?

Так. Самостійно розгорнутий n8n може викликати будь-який скорочувач з REST API через вбудований вузол HTTP Request. Для Elido це означає облікові дані Header Auth з вашим API-ключем і POST на маршрут посилань, прив'язаний до робочого простору. Вхідні події на кшталт link.created надходять через вбудований вузол Webhook n8n, якому потрібна публічна HTTPS-адреса. Подія click.created для кожного кліку запланована, але поки недоступна.

Як встановити community-вузли на самостійно розгорнутому n8n?

На одному інстансі використовуйте Settings, потім Community Nodes, і вставте назву пакета npm. У режимі черги встановлення через GUI не доходить до ваших воркерів, тож встановлюйте пакет у кожному контейнері окремо, або, починаючи з n8n 2.21, перелічіть його в N8N_COMMUNITY_PACKAGES зі значенням N8N_COMMUNITY_PACKAGES_MANAGED_BY_ENV, встановленим у true. Для Elido він взагалі не потрібен: вузол HTTP Request покриває API.

Що таке WEBHOOK_URL в n8n?

Він повідомляє n8n, яку публічну адресу показувати в редакторі і реєструвати у зовнішніх сервісах, бо за зворотним проксі n8n не може визначити це сам з власного хоста і порту. Поточні версії n8n читають N8N_WEBHOOK_URL і логують попередження про застарілість для старішого WEBHOOK_URL. Поєднуйте це з N8N_PROXY_HOPS=1 і переданими заголовками на проксі.

Як перевірити підпис webhook у n8n?

Увімкніть опцію Raw Body у вузлі Webhook, потім додайте вузол Code, що переобчислює HMAC-SHA256 над заголовком мітки часу, крапкою і сирим тілом, використовуючи секрет вашої кінцевої точки. Порівняйте його з заголовком підпису за постійний час і відхиляйте все старіше за п'ять хвилин. Перевіряйте за сирими байтами, ніколи за повторно серіалізованим JSON.

Чи потрібен Redis для режиму черги n8n?

Так. У режимі черги головний інстанс і будь-які обробники webhook перетворюють вхідні тригери на ID виконань і додають їх у чергу на основі Redis, а воркери забирають їх звідти. n8n також радить не використовувати режим черги з SQLite, тож плануйте Postgres. Кожен процес має спільно використовувати той самий ключ шифрування, інакше воркери не зможуть прочитати збережені облікові дані.

Чи кращий самостійно розгорнутий n8n для GDPR, ніж n8n Cloud?

Може бути, бо ви обираєте, де фізично живуть дані робочих процесів, журнали виконань і облікові дані, і хто ними адмініструє. Це не робить систему автоматично відповідною вимогам: ви берете на себе відповідальність за патчі, контроль доступу, резервні копії і зберігання. Для автоматизації посилань, що обробляє дані кліків, самостійне розгортання в регіоні ЄС прибирає одного оброблювача з ваших записів, що спрощує документообіг.

Спробуйте Elido

Вставте URL - отримайте коротке посилання

Без реєстрації. Посилання живе 30 днів. Зареєструйтесь, щоб зберегти назавжди.

Безкоштовно, без реєстрації · 2 на день

Спробуйте Elido

URL-скорочувач із хостингом у ЄС: власні домени, глибока аналітика, відкритий API. Безкоштовний тариф - без кредитної картки.

Теги
self-hosted n8n automation links
n8n self hosted url shortener
n8n docker link automation
n8n webhook signature verification
n8n queue mode
n8n http request node api

Читати далі