9 min czytaniaIntegracje

Automatyzacja linków z self-hosted n8n: od Dockera do webhooków

Uruchom automatyzację linków w self-hosted n8n z webhookami Elido, Docker Compose i trybem kolejki, zachowując dane przepływów na infrastrukturze, którą kontrolujesz w UE.

Marius Voß
DevRel · edge infra
Automatyzacja linków w self-hosted n8n: webhooki Elido przechodzą przez reverse proxy do instancji n8n z kolejką i workerami, wszystko na infrastrukturze, którą kontrolujesz

Automatyzacja linków w self-hosted n8n oznacza trzy rzeczy działające na serwerach, które kontrolujesz: instancję n8n w Dockerze, publiczny punkt końcowy HTTPS, który odbiera zdarzenia webhooków Elido, oraz wywołania wychodzące z powrotem do API Elido z tokenem o ograniczonym zakresie. Zdarzenia linków i domen przychodzą podpisane, a zdarzenia per kliknięcie są na mapie drogowej. Twoje przepływy decydują, co dzieje się dalej, a dzienniki wykonań nigdy nie opuszczają Twojej infrastruktury.

To cała architektura. Reszta tego wpisu to część, którą pomijają szybkie startery: jak przeprowadzić webhooki przez reverse proxy, jak sprawdzić sygnaturę, żeby obcy nie mógł wyzwolić Twoich przepływów, co zmienia tryb kolejki i kiedy n8n Cloud jest szczerze mówiąc lepszym wyborem. Uruchamiam tę konfigurację na jednej małej maszynie wirtualnej, a wszystkie ruchome części mieszczą się na jednym ekranie.

Jeśli chcesz mieć na własnym sprzęcie również same linki, to osobne i dużo większe zadanie. Playbook self-hostingu Elido na k3s opisuje to. Tutaj Elido pozostaje zarządzane, a tylko warstwa automatyzacji przenosi się do wewnątrz firmy.

Dlaczego self-hostować n8n do automatyzacji linków

Zwykłym powodem są dane. Przepływ n8n self hosted url shortener widzi każdy ładunek, który przetwarza: adres docelowy, tagi, czasem nazwę kampanii mówiącą więcej, niż byś chciał, oraz kraj, urządzenie i referrer, jeśli wciągasz analitykę kliknięć. W n8n Cloud te wykonania są przechowywane na cudzych serwerach, według cudzych domyślnych zasad retencji. Self-hosted, siedzą w Twoim Postgresie, w wybranym przez Ciebie regionie.

Zgodnie z artykułem 28 RODO każdy procesor, który dotyka danych osobowych, potrzebuje umowy i miejsca w Twoich rejestrach. Mniej procesorów, mniej papierologii. Jeśli Twoje dane marketingowe i tak muszą zostać w UE, przewodnik po rezydencji danych w UE wyjaśnia, dlaczego warstwa automatyzacji liczy się tak samo jak sam skracacz.

Drugim powodem jest kształt kosztów. n8n Cloud rozlicza się według wykonań, a ruchliwy wyzwalacz webhooka albo częste odpytywanie analityki szybko zużywa wykonania. Self-hosted wykonanie to wiersz w tabeli i kilka milisekund CPU.

Trzeci to zasięg. Instancja self-hosted siedzi w tej samej sieci co baza danych Twojego CRM czy wewnętrzne narzędzie zgłoszeniowe, więc zdarzenie linku może trafić do systemu, który nigdy nie miał stawać twarzą do internetu.

Stos Docker Compose

Minimalny stos n8n docker link automation potrzebuje czterech usług. Własny przewodnik Docker Compose n8n jest materiałem referencyjnym; to wersja, od której zacząłbym do pracy z linkami, z trybem kolejki już włączonym, żeby nie trzeba było się później migrować.

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:

I wspólny plik środowiskowy:

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

Dwie linie mają większe znaczenie, niż wygląda. Klucz szyfrowania musi być identyczny w procesie głównym i każdym workerze, inaczej workerzy nie odszyfrują poświadczenia Elido i każde wykonanie zakończy się myloną awarią uwierzytelniania. A port 5678 jest związany tylko z localhost, bo to reverse proxy powinien być jedyną rzeczą wystawioną na internet.

Architektura self-hosted n8n do automatyzacji linków: Elido wysyła podpisane webhooki przez HTTPS do reverse proxy, który przekazuje do procesu głównego n8n, ten kolejkuje wykonania w Redis dla workerów opartych na Postgres, podczas gdy workerzy wywołują API Elido wychodząco z tokenem o ograniczonym zakresie

Wywoływanie API Elido z self-hosted n8n

Wywołania wychodzące nie potrzebują niczego poza tym, co jest w standardzie n8n. Utwórz poświadczenie Header Auth z nazwą Authorization i wartością Bearer plus klucz API z panelu Elido, a następnie użyj go z wbudowanego węzła HTTP Request. n8n szyfruje je w spoczynku kluczem z pliku środowiskowego, co jest kolejnym powodem, dla którego ten klucz musi być wszędzie taki sam.

Każda trasa linków jest w zakresie workspace. Żeby skrócić adres URL, wyślij POST do https://api.elido.app/v1/workspaces/{workspace_id}/links z ciałem JSON:

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

Pomiń slug, a Elido wygeneruje je samo. domain_id to krótka domena, na której żyje link; GET na /v1/workspaces/{workspace_id}/domains wylicza Twoje, a ja zakodowałbym ID na stałe w przepływie zamiast szukać go przy każdym uruchomieniu. GET na tej samej trasie links wylicza linki, a PATCH /v1/workspaces/{workspace_id}/links/{link_id} zmienia cel albo tagi po fakcie.

Ustaw nagłówek Idempotency-Key na POST, zbudowany z czegoś stabilnego w wyzwalającym elemencie, na przykład ID wiersza. Jeśli n8n ponowi węzeł po przekroczeniu czasu, API odtworzy pierwszą odpowiedź zamiast utworzyć drugi link. Szybki start API i SDK opisuje resztę powierzchni, a strona API i SDK czeka, jeśli wolałbyś przenieść krok do kodu później.

Istnieje też spakowany węzeł społeczności, n8n-nodes-elido, mający opakować te wywołania w bardziej przyjazną formę. Jest opublikowany na npm (wersja 0.2.0), ale nadal opcjonalny, a ponieważ nie jest zweryfikowanym węzłem, instaluje się go tylko w self-hosted n8n, czyli w konfiguracji, którą i tak zakłada ten post. Trzymaj wersję HTTP Request jako punkt odniesienia. Jeśli instalujesz pakiety społeczności w trybie kolejki, pamiętaj, że GUI instaluje tylko do kontenera głównego; workerzy nigdy go nie widzą. Od n8n 2.21 ścieżka instalacji przez zmienną środowiskową naprawia to, uzgadniając każdy kontener przy starcie, choć za pierwszym razem odinstalowuje wszystko, czego nie ma na swojej liście.

Przeprowadzanie webhooków Elido przez reverse proxy

Zdarzenia płyną w drugą stronę. Elido emituje link.created, link.updated i domain.verified (między innymi) do punktu końcowego, który rejestrujesz pod Settings, Webhooks, a w self-hosted n8n tym punktem końcowym jest produkcyjny URL węzła Webhook. Zdarzenie click.created per kliknięcie jest na mapie drogowej, ale jeszcze niewdrożone, więc na razie dane kliknięć pochodzą z zaplanowanego pobierania z API analitycznego. Pełna lista zdarzeń i kształty ładunków znajdują się w referencji webhooki dla zdarzeń linków.

Za proxy n8n buduje swój URL webhooka na podstawie własnego protokołu, hosta i portu, co oznacza, że chętnie ogłosi http://localhost:5678/webhook/... każdemu, kto zapyta. Strona konfiguracji reverse proxy jest krótka i warta przeczytania w całości: ustaw N8N_WEBHOOK_URL na swój publiczny adres, ustaw N8N_PROXY_HOPS=1 i spraw, żeby ostatnie proxy przekazywało X-Forwarded-For, X-Forwarded-Host i X-Forwarded-Proto. Starsze przewodniki mówią o WEBHOOK_URL; bieżące wydania wciąż go czytają, ale logują ostrzeżenie o wycofaniu.

Nginx, Traefik, cokolwiek już masz uruchomione, jest w porządku. Liczy się TLS po stronie publicznej i to, żeby ścieżka /webhook/* docierała do n8n bez zmian.

Ugryzł mnie kiedyś jeden szczegół związany z czasem. Elido czeka dziesięć sekund na odpowiedź, zanim uzna dostarczenie za nieudane. Przepływ, który zapisuje do wolnego API arkuszy, a potem odpowiada, może przekroczyć ten czas, zostać ponowiony i zapisać ten sam wiersz dwa razy. Ustaw węzeł Webhook tak, żeby odpowiadał natychmiast, a pracę wykonywał potem.

Jeśli konfigurujesz to dla klienta i chcesz, żeby strona webhooków została za Ciebie ogarnięta, strona funkcji webhooków pokazuje, na co możesz się zasubskrybować, zanim zaczniesz cokolwiek budować.

Weryfikacja sygnatury, zanim cokolwiek się uruchomi

Publiczny URL webhooka to publiczny URL. Każdy, kto go znajdzie, może wysłać sfałszowane zdarzenie i wyzwolić Twój przepływ, więc pierwszym węzłem po wyzwalaczu powinno być sprawdzenie sygnatury.

Każde dostarczenie Elido niesie X-Webhook-Signature (wartość v1= plus skrót hex), X-Webhook-Timestamp w sekundach Unix, X-Webhook-Event i X-Webhook-Delivery. Skrót to HMAC-SHA256 po znaczniku czasu, kropce i surowym ciele żądania, kluczowany sekretem whsec_ pokazanym raz przy tworzeniu punktu końcowego.

Włącz najpierw Raw Body w węźle Webhook. To krok, który ludzie pomijają. Jeśli haszujesz JSON.stringify($json.body) zamiast dokładnych bajtów wysłanych przez Elido, kolejność kluczy albo białe znaki się różnią i każda sygnatura zawodzi, a Ty spędzisz wieczór przekonany, że sekret jest zły. Potem węzeł 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) }];

Moduł crypto jest domyślnie dostępny w węźle Code, więc nie trzeba tam dodatkowej konfiguracji. Pięciominutowe okno blokuje odtworzenie przechwyconego żądania. Podczas rotacji sekretu Elido wysyła też X-Elido-Signature-Previous przez okres przejściowy, więc możesz akceptować oba klucze, aktualizując zmienną. W przewodniku weryfikacji sygnatur webhooków znajdziesz wersję tego węzła, która sprawdza oba nagłówki, a także taką samą weryfikację w Node, Pythonie i Go.

Weryfikacja sygnatury webhooka w self-hosted n8n: odczytaj znacznik czasu i surowe ciało, odrzuć dostarczenia starsze niż 300 sekund, przelicz HMAC-SHA256 po timestamp kropka raw body z sekretem punktu końcowego, porównaj w czasie stałym, potem albo uruchom przepływ, albo zatrzymaj wykonanie

Tryb kolejki i ponowienia

Z zabezpieczeniem sygnatury na miejscu, pozostałym pytaniem jest, co dzieje się pod obciążeniem albo gdy coś jest niedostępne. W grę wchodzą tu dwa systemy ponowień, obejmujące różne rodzaje awarii.

W trybie kolejki n8n proces główny odbiera webhooka, tworzy wykonanie i przekazuje jego ID do Redis; workerzy je pobierają. Wysyp zdarzeń gromadzi się w kolejce zamiast blokować odpowiedź HTTP. Przy większym wolumenie przychodzącym możesz dodać dedykowane procesory webhooków za load balancerem, choć dla większości obciążeń związanych z linkami wystarcza jeden proces główny i dwóch workerów.

Strona Elido obsługuje sytuację, w której n8n jest niedostępne. Każda odpowiedź inna niż 2xx albo przekroczenie czasu jest ponawiana po 1, 5 i 15 minutach; po trzech próbach dostarczenie zostaje oznaczone jako nieudane i możesz je uzbroić ponownie z panelu. To obejmuje restart kontenera albo szybki deploy. Nie obejmuje weekendowej awarii, dlatego łączyłbym webhooki z nocną rekoncyliacją, która wylicza linki przez API, jak argumentuje wpis webhooki kontra odpytywanie.

Użyj X-Webhook-Delivery jako klucza idempotencji. Ponowienia go powtarzają.

Self-hosted n8n kontra n8n Cloud: uczciwe kompromisy

Wolę self-hosting do tego celu, ale widziałem zespoły, które tego żałowały. Oto porównanie bez marketingu z żadnej ze stron.

KwestiaSelf-hosted n8nn8n Cloud
Gdzie żyją dane wykonańTwoje serwery, Twój region, Twoja retencjaInfrastruktura i domyślne ustawienia n8n
Docieranie do systemów wewnętrznychTa sama sieć co CRM i bazy danychTylko to, co udostępniasz publicznie
Publiczny URL webhooka i TLSTy prowadzisz proxy i certyfikatyZapewnione
Aktualizacje, kopie zapasowe, łatanieTwoja praca, co miesiącObsługiwane
Koszt przy dużym wolumenie zdarzeńStały koszt serweraSkaluje się z wykonaniami

Ostatni wiersz działa w obie strony. Mała maszyna wirtualna jest tania, ale godzina inżyniera przy zepsutej aktualizacji już nie, a n8n wydaje aktualizacje często. Jeśli nikt w zespole nie zajmuje się tą maszyną na co dzień, Cloud z węzłem HTTP Request i REST API Elido to rozsądniejsza opcja, a przepisy Make i IFTTT albo przewodnik Zapier pokazują, jak wygląda ta zarządzana droga na innych platformach.

Czego nie mogę Ci powiedzieć, to czy Twój inspektor ochrony danych zaakceptuje self-hosted maszynę jako prostszą niż umowa powierzenia z dostawcą. W moim doświadczeniu zwykle tak, ale to zależy od tego, jak dobrze ta maszyna jest prowadzona. W kwestii tego, jak działa strona kontraktowa samego skracacza, przewodnik RODO dla skracaczy URL to miejsce, od którego warto zacząć. A jeśli jesteś gotowy podłączyć pierwszy przepływ, weź token API na workspace i skieruj na niego węzeł Webhook.

Powiązane na blogu

Najczęściej zadawane pytania

Czy mogę używać skracacza URL z self-hosted n8n?

Tak. Self-hosted n8n może wywołać dowolny skracacz z API REST przez wbudowany węzeł HTTP Request. Dla Elido oznacza to poświadczenie Header Auth niosące Twój klucz API i POST do trasy links w zakresie workspace. Zdarzenia przychodzące, takie jak link.created, docierają przez wbudowany węzeł Webhook n8n, który potrzebuje publicznego adresu HTTPS. Zdarzenie click.created per kliknięcie jest planowane, ale jeszcze niedostępne.

Jak zainstalować węzły społeczności w self-hosted n8n?

Na pojedynczej instancji użyj Settings, potem Community Nodes, i wklej nazwę pakietu npm. W trybie kolejki instalacja przez GUI nie dociera do Twoich workerów, więc zainstaluj pakiet wewnątrz każdego kontenera albo, od n8n 2.21, wymień go w N8N_COMMUNITY_PACKAGES z ustawionym N8N_COMMUNITY_PACKAGES_MANAGED_BY_ENV na true. Dla Elido nie potrzebujesz żadnego: węzeł HTTP Request obejmuje całe API.

Czym jest WEBHOOK_URL w n8n?

Mówi n8n, jaki publiczny adres pokazać w edytorze i zarejestrować w zewnętrznych usługach, bo za reverse proxy n8n nie potrafi tego wyznaczyć na podstawie własnego hosta i portu. Obecne wersje n8n czytają N8N_WEBHOOK_URL i logują ostrzeżenie o wycofaniu dla starszego WEBHOOK_URL. Połącz to z N8N_PROXY_HOPS=1 i przekazywanymi nagłówkami na proxy.

Jak zweryfikować sygnaturę webhooka w n8n?

Włącz opcję Raw Body w węźle Webhook, a potem dodaj węzeł Code, który przelicza HMAC-SHA256 po nagłówku znacznika czasu, kropce i surowym ciele, używając sekretu Twojego punktu końcowego. Porównaj go z nagłówkiem sygnatury w czasie stałym i odrzuć wszystko starsze niż pięć minut. Weryfikuj na surowych bajtach, nigdy na ponownie zserializowanym JSON-ie.

Czy tryb kolejki n8n potrzebuje Redis?

Tak. W trybie kolejki instancja główna i wszelkie procesory webhooków zamieniają przychodzące wyzwalacze na ID wykonań i wypychają je do kolejki opartej na Redis, a workerzy je pobierają. n8n odradza też tryb kolejki z SQLite, więc zaplanuj Postgres. Każdy proces musi dzielić ten sam klucz szyfrowania, inaczej workerzy nie odczytają zapisanych poświadczeń.

Czy self-hosted n8n jest lepszy pod kątem RODO niż n8n Cloud?

Może być, bo wybierasz, gdzie fizycznie żyją dane przepływów, dzienniki wykonań i poświadczenia oraz kto nimi administruje. Nie jest to automatyczna zgodność: bierzesz na siebie odpowiedzialność za łatanie, kontrolę dostępu, kopie zapasowe i retencję. Dla automatyzacji linków obsługującej dane kliknięć, self-hosting w regionie UE usuwa jednego procesora z Twoich rejestrów, co upraszcza papierologię.

Wypróbuj Elido

Wklej URL, otrzymaj krótki link

Bez rejestracji. Link działa 30 dni. Zarejestruj się, aby zachować go na zawsze.

Za darmo, bez rejestracji · 2 dziennie

Wypróbuj Elido

Skracarka URL hostowana w UE: własne domeny, głęboka analityka i otwarte API. Darmowy plan - bez karty kredytowej.

Tagi
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

Czytaj dalej