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.
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.
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.
| Kwestia | Self-hosted n8n | n8n Cloud |
|---|---|---|
| Gdzie żyją dane wykonań | Twoje serwery, Twój region, Twoja retencja | Infrastruktura i domyślne ustawienia n8n |
| Docieranie do systemów wewnętrznych | Ta sama sieć co CRM i bazy danych | Tylko to, co udostępniasz publicznie |
| Publiczny URL webhooka i TLS | Ty prowadzisz proxy i certyfikaty | Zapewnione |
| Aktualizacje, kopie zapasowe, łatanie | Twoja praca, co miesiąc | Obsługiwane |
| Koszt przy dużym wolumenie zdarzeń | Stały koszt serwera | Skaluje 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
- Self-hosting Elido na k3s: playbook - kiedy linki też muszą żyć wewnątrz firmy.
- Webhooki dla zdarzeń linków - każdy typ zdarzenia i kształt ładunku.
- Webhooki kontra odpytywanie dla śledzenia kliknięć - dlaczego nocna rekoncyliacja ma znaczenie.
- Automatyzacja krótkich linków z Make i IFTTT - zarządzana droga low-code.
- Skracacz URL w n8n - konfiguracja węzła HTTP Request i trzy przepływy w szczegółach.
- Weryfikacja sygnatur webhooków - surowe ciało, okno zapobiegające odtworzeniom i rotacja sekretu w czterech środowiskach uruchomieniowych.
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