Automatizarea n8n self-hosted pentru linkuri înseamnă trei lucruri care rulează pe servere pe care le controlezi: o instanță n8n în Docker, un endpoint HTTPS public care primește evenimentele webhook Elido și apeluri de ieșire către API-ul Elido cu un token cu domeniu limitat. Evenimentele de link și de domeniu sosesc semnate, iar evenimentele per clic sunt pe foaia de parcurs. Fluxurile tale decid ce se întâmplă mai departe, iar jurnalele de execuție nu părăsesc niciodată infrastructura ta.
Asta e toată arhitectura. Restul articolului este partea pe care ghidurile rapide o sar: cum treci webhookurile printr-un reverse proxy, cum verifici semnătura ca un străin să nu-ți poată declanșa fluxurile, ce schimbă queue mode și când n8n Cloud este, sincer, alegerea mai bună. Rulez această configurație pe o singură VM mică, iar părțile mobile încap pe un ecran.
Dacă vrei și linkurile în sine pe hardware propriu, e o treabă separată și mult mai mare. O acoperă playbook-ul de self-hosting Elido pe k3s. Aici, Elido rămâne gestionat, iar doar stratul de automatizare se mută în interior.
De ce să rulezi n8n self-hosted pentru automatizarea linkurilor
Motivul obișnuit sunt datele. Un flux n8n self-hosted cu scurtător de URL vede fiecare payload pe care îl procesează: URL-ul de destinație, etichetele, uneori un nume de campanie care spune mai mult decât ți-ai dori, plus țara, dispozitivul și sursa dacă aduci în el analitice de clicuri. Pe n8n Cloud, acele execuții sunt stocate pe serverele altcuiva, cu retenția implicită a altcuiva. Self-hosted, stau în Postgres-ul tău, în regiunea pe care ai ales-o.
Conform articolului 28 din GDPR, fiecare procesator care atinge date personale are nevoie de un contract și de un loc în evidențele tale. Mai puțini procesatori, mai puține hârtii. Dacă datele tale de marketing trebuie deja să rămână în UE, ghidul de rezidență a datelor în UE explică de ce stratul de automatizare contează la fel de mult ca scurtătorul.
Al doilea motiv este forma costului. n8n Cloud taxează pe execuții, iar un declanșator webhook aglomerat sau un polling frecvent de analitice consumă execuții repede. Self-hosted, o execuție este un rând într-un tabel și câteva milisecunde de CPU.
Al treilea este accesul. O instanță self-hosted se află în aceeași rețea cu baza ta de date CRM sau cu instrumentul intern de tichete, deci un eveniment de link poate ajunge într-un sistem care nu a fost niciodată făcut să dea spre internet.
Stack-ul Docker Compose
Un stack minim de automatizare a linkurilor cu n8n în Docker are nevoie de patru servicii. Ghidul Docker Compose al n8n este referința; aceasta este versiunea de la care aș porni pentru linkuri, cu queue mode deja pornit ca să nu fii nevoit să migrezi mai târziu.
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 fișierul de mediu partajat:
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
Două linii contează mai mult decât par. Cheia de criptare trebuie să fie identică pe procesul principal și pe fiecare worker, altfel workerii nu pot decripta credențiala Elido, iar fiecare execuție eșuează cu o eroare de autentificare derutantă. Iar portul 5678 este legat doar la localhost, pentru că reverse proxy-ul este singurul lucru care trebuie să dea spre internet.
Apelarea API-ului Elido din n8n self-hosted
Apelurile de ieșire nu au nevoie de nimic în afară de ce vine cu n8n. Creează o credențială Header Auth cu numele Authorization și valoarea Bearer urmată de o cheie API din dashboard-ul Elido, apoi folosește-o din nodul HTTP Request încorporat. n8n o criptează în repaus cu cheia din fișierul de mediu, încă un motiv pentru care acea cheie trebuie să se potrivească peste tot.
Fiecare rută de link este limitată la un workspace. Ca să scurtezi un URL, fă POST la https://api.elido.app/v1/workspaces/{workspace_id}/links cu un corp JSON:
{
"domain_id": 12,
"destination_url": "{{ $json.url }}",
"title": "Spring launch",
"tags": ["n8n", "spring"]
}
Omite slug și Elido generează unul. domain_id este domeniul scurt pe care trăiește linkul; un GET la /v1/workspaces/{workspace_id}/domains le listează pe ale tale, iar eu aș pune ID-ul direct în flux, în loc să-l caut la fiecare rulare. Un GET pe aceeași rută de linkuri listează linkurile, iar PATCH /v1/workspaces/{workspace_id}/links/{link_id} schimbă ulterior o destinație sau etichetele.
Setează un header Idempotency-Key pe POST, construit din ceva stabil din elementul declanșator, precum un ID de rând. Dacă n8n reîncearcă nodul după un timeout, API-ul redă primul răspuns în loc să creeze un al doilea link. Ghidul rapid pentru API și SDK-uri acoperă restul suprafeței, iar pagina API și SDK-uri e acolo dacă preferi să muți mai târziu un pas în cod.
Există și un community node ambalat, n8n-nodes-elido, menit să învelească aceste apeluri într-o formă mai prietenoasă. Este publicat pe npm (versiunea 0.2.0), dar rămâne opțional, iar fiindcă nu este un nod verificat, se instalează doar pe n8n self-hosted, adică exact configurația pe care o presupune articolul. Păstrează varianta cu HTTP Request ca bază. Dacă instalezi totuși pachete comunitare în queue mode, ține minte că interfața instalează doar în containerul principal; workerii nu-l văd niciodată. Începând cu n8n 2.21, ruta de instalare prin variabile de mediu rezolvă asta, reconciliind fiecare container la pornire, deși dezinstalează tot ce nu e pe lista ei prima dată.
Cum treci webhookurile Elido prin reverse proxy
Evenimentele curg în sens invers. Elido emite link.created, link.updated și domain.verified (printre altele) către un endpoint pe care îl înregistrezi la Settings, Webhooks, iar pe n8n self-hosted acel endpoint este URL-ul de producție al unui nod Webhook. Un eveniment click.created per clic este pe foaia de parcurs, dar nelivrat încă, deci deocamdată datele de clic vin dintr-o interogare programată a API-ului de analitice. Lista completă de evenimente și formele payloadului sunt în referința webhookuri pentru evenimente de link.
În spatele unui proxy, n8n își construiește URL-ul webhook din propriul protocol, propria gazdă și propriul port, ceea ce înseamnă că va anunța bucuros http://localhost:5678/webhook/... oricui întreabă. Pagina despre configurarea reverse proxy este scurtă și merită citită integral: setează N8N_WEBHOOK_URL la adresa ta publică, setează N8N_PROXY_HOPS=1 și pune ultimul proxy să transmită X-Forwarded-For, X-Forwarded-Host și X-Forwarded-Proto. Ghidurile mai vechi spun WEBHOOK_URL; versiunile curente îl citesc în continuare, dar loghează un avertisment de depreciere.
Nginx, Traefik, orice rulezi deja e în regulă. Contează TLS pe partea publică și ca ruta /webhook/* să ajungă la n8n neatinsă.
Un detaliu de timing m-a pus pe jar. Elido așteaptă zece secunde un răspuns înainte să considere o livrare eșuată. Un flux care scrie într-un API lent de foaie de calcul și apoi răspunde poate depăși acest prag, e reîncercat și scrie același rând de două ori. Setează nodul Webhook să răspundă imediat și fă munca după.
Dacă configurezi asta pentru un client și vrei partea de webhook rezolvată pentru tine, pagina de funcții webhook arată la ce te poți abona înainte să construiești ceva.
Verifică semnătura înainte să ruleze orice
Un URL webhook public este un URL public. Oricine îl găsește poate trimite un POST cu un eveniment fals și îți poate declanșa fluxul, deci primul nod după declanșator trebuie să fie o verificare de semnătură.
Fiecare livrare Elido poartă X-Webhook-Signature (valoarea v1= plus un digest hex), X-Webhook-Timestamp în secunde Unix, X-Webhook-Event și X-Webhook-Delivery. Digestul este HMAC-SHA256 peste timestamp, un punct și corpul brut al cererii, cu cheia secretului whsec_ afișat o singură dată când ai creat endpointul.
Activează mai întâi Raw Body pe nodul Webhook. Acesta e pasul pe care îl sar oamenii. Dacă faci hash pe JSON.stringify($json.body) în loc de octeții exacți trimiși de Elido, ordinea cheilor sau spațiile diferă, fiecare semnătură eșuează, iar tu îți petreci o seară convins că secretul e greșit. Apoi un nod 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) }];
Modulul crypto este disponibil implicit în nodul Code, deci nu e nevoie de configurare suplimentară acolo. Fereastra de cinci minute blochează reluarea unei cereri capturate. Când schimbi secretul, Elido trimite și X-Elido-Signature-Previous în perioada de grație, deci poți accepta oricare dintre chei cât timp actualizezi variabila. Ghidul de verificare a semnăturilor webhook are o versiune a acestui nod care verifică ambele headere, plus aceeași verificare în Node, Python și Go.
Queue mode și reîncercările
Cu verificarea semnăturii pusă la punct, rămâne întrebarea ce se întâmplă sub încărcare sau când ceva e căzut. Aici lucrează două sisteme de reîncercare, iar ele acoperă eșecuri diferite.
În queue mode al n8n, procesul principal primește webhookul, creează o execuție și îi predă ID-ul lui Redis; workerii o preiau. O rafală de evenimente se strânge în coadă în loc să blocheze răspunsul HTTP. Pentru mai mult volum de intrare poți adăuga procesoare dedicate de webhook în spatele unui load balancer, deși pentru majoritatea sarcinilor de linkuri un proces principal și doi workeri sunt amplu suficienți.
Partea Elido tratează cazul în care n8n e inaccesibil. Orice răspuns non-2xx sau timeout este reîncercat după 1, 5 și 15 minute; după trei încercări livrarea este marcată ca eșuată și o poți rearma din dashboard. Asta acoperă o repornire de container sau un deploy rapid. Nu acoperă o pană de weekend, de aceea aș combina webhookurile cu o reconciliere nocturnă care listează linkurile prin API, așa cum argumentează articolul webhookuri vs polling.
Folosește X-Webhook-Delivery drept cheie de idempotență. Reîncercările îl refolosesc.
n8n self-hosted vs n8n Cloud: compromisuri oneste
Prefer self-hostingul pentru asta, dar am văzut echipe care au regretat. Iată comparația fără discursul de vânzări al vreuneia dintre părți.
| Aspect | n8n self-hosted | n8n Cloud |
|---|---|---|
| Unde stau datele execuțiilor | Serverele tale, regiunea ta, retenția ta | Infrastructura și setările implicite n8n |
| Acces la sisteme interne | Aceeași rețea cu CRM-ul și bazele tale | Doar ce expui public |
| URL webhook public și TLS | Tu rulezi proxy-ul și certificatele | Furnizate |
| Upgrade-uri, backupuri, patchuri | Treaba ta, în fiecare lună | Gestionate |
| Cost la volum mare de evenimente | Cost fix de server | Crește cu execuțiile |
Ultimul rând taie în ambele sensuri. O VM mică e ieftină, dar o oră de inginer pe un upgrade stricat nu e, iar n8n livrează des. Dacă nimeni din echipă nu răspunde de mașină, Cloud cu nodul HTTP Request și API-ul REST Elido este opțiunea mai înțeleaptă, iar rețetele Make și IFTTT sau ghidul Zapier arată cum arată acea cale gestionată pe alte platforme.
Ce nu-ți pot spune este dacă responsabilul tău cu protecția datelor va accepta o mașină self-hosted ca fiind mai simplă decât un DPA cu un furnizor. În experiența mea, de obicei da, dar depinde cât de bine e administrată mașina. Pentru cum funcționează partea de contract din zona scurtătorului, ghidul GDPR pentru scurtătoarele de URL este locul de început. Iar dacă ești gata să conectezi primul flux, ia un token API pe un workspace și îndreaptă un nod Webhook spre el.
Articole conexe pe blog
- Self-hosting Elido pe k3s: playbook-ul - când și linkurile trebuie să trăiască în interior.
- Webhookuri pentru evenimente de link - fiecare tip de eveniment și formă de payload.
- Webhookuri vs polling pentru urmărirea clicurilor - de ce contează reconcilierea nocturnă.
- Automatizare de linkuri scurte cu Make și IFTTT - calea low-code gestionată.
- Scurtător de URL n8n - configurarea nodului HTTP Request și trei fluxuri în detaliu.
- Verifică semnăturile webhook - corp brut, fereastră anti-replay și rotirea secretelor în patru runtime-uri.
Întrebări frecvente
Pot folosi un scurtător de URL cu n8n self-hosted?
Da. n8n self-hosted poate apela orice scurtător cu API REST prin nodul HTTP Request încorporat. Pentru Elido asta înseamnă o credențială Header Auth care poartă cheia ta API și un POST către ruta de linkuri din cadrul workspace-ului. Evenimentele primite, precum link.created, ajung prin nodul Webhook încorporat al n8n, care are nevoie de un URL HTTPS public. Un eveniment click.created per clic este planificat, dar încă indisponibil.
Cum instalez community nodes pe n8n self-hosted?
Pe o singură instanță, folosește Settings, apoi Community Nodes, și lipește numele pachetului npm. În queue mode, instalarea din interfață nu ajunge la workeri, așa că instalează pachetul în fiecare container sau, începând cu n8n 2.21, listează-l în N8N_COMMUNITY_PACKAGES cu N8N_COMMUNITY_PACKAGES_MANAGED_BY_ENV setat pe true. Pentru Elido nu ai nevoie de unul: nodul HTTP Request acoperă API-ul.
Ce este WEBHOOK_URL în n8n?
Îi spune n8n ce adresă publică să afișeze în editor și să înregistreze la serviciile externe, pentru că în spatele unui reverse proxy n8n nu o poate deduce din propria gazdă și propriul port. Versiunile curente de n8n citesc N8N_WEBHOOK_URL și loghează un avertisment de depreciere pentru vechiul WEBHOOK_URL. Asociază-l cu N8N_PROXY_HOPS=1 și cu headere forwarded pe proxy.
Cum verific semnătura unui webhook în n8n?
Activează opțiunea Raw Body în nodul Webhook, apoi adaugă un nod Code care recalculează HMAC-SHA256 peste headerul de timestamp, un punct și corpul brut, folosind secretul endpointului tău. Compară-l cu headerul de semnătură în timp constant și respinge tot ce e mai vechi de cinci minute. Verifică pe octeții bruți, niciodată pe un JSON reserializat.
Are n8n queue mode nevoie de Redis?
Da. În queue mode, instanța principală și orice procesoare de webhook transformă declanșatoarele primite în ID-uri de execuție și le împing într-o coadă susținută de Redis, iar workerii trag din ea. n8n descurajează și queue mode cu SQLite, deci planifică Postgres. Fiecare proces trebuie să partajeze aceeași cheie de criptare, altfel workerii nu pot citi credențialele stocate.
Este n8n self-hosted mai bun pentru GDPR decât n8n Cloud?
Poate fi, pentru că alegi unde stau fizic datele fluxurilor, jurnalele de execuție și credențialele și cine le administrează. Nu este automat conform: devii responsabil pentru patchuri, controlul accesului, backupuri și retenție. Pentru o automatizare de linkuri care manipulează date de clic, self-hosting într-o regiune UE elimină un procesator din evidențele tale, ceea ce simplifică hârtiile.
Încearcă Elido
Lipește un URL, obții un link scurt funcțional
Fără înregistrare. Linkul este activ timp de 30 de zile. Înregistrează-te ca să-l păstrezi pentru totdeauna.
Fără înregistrare. Creează un cont gratuit pentru 50 linkuri pe lună.