n8n — self-hostowana automatyzacja procesów z 1500+ integracjami
Platforma workflow, która zdejmuje z aplikacji obowiązek gadania z piętnastoma zewnętrznymi API: kanwa z nodami, kod tam, gdzie kanwa nie wystarcza, i wszystko na własnym serwerze. Pokazujemy pełne wdrożenie w Dockerze — Postgres, tryb kolejkowy z Redisem, przycinanie danych wykonań, reverse proxy — plus konkretny podział odpowiedzialności między n8n a aplikacją w Laravelu. Na koniec rachunek z licencji Sustainable Use, która nie jest open source, i lista tego, co wywali się w n8n 3.0 w październiku 2026.
Każdy projekt, który trwa dłużej niż rok, dorasta do własnej warstwy klejowej. Zamówienie zostało opłacone, więc trzeba wysłać zdarzenie do CRM-u, wystawić fakturę w systemie księgowym, wrzucić wpis na kanał na Slacku, dopisać wiersz do arkusza, który ktoś z zarządu otwiera w poniedziałki, i jeszcze zaktualizować status w narzędziu do obsługi zgłoszeń. Nic z tego nie jest trudne. Wszystko razem to kilkanaście klas Job, kilkanaście zestawów kluczy API w .env, własna obsługa ponowień dla każdej usługi i rosnąca liczba testów, które mockują cudze HTTP.
Najbardziej dokuczliwe jest to, że ta warstwa zmienia się nie z powodu wymagań produktu, a z powodu cudzych decyzji. Ktoś w firmie zmienia narzędzie do fakturowania i trzeba wejść do kodu aplikacji, dopisać integrację, przetestować i wdrożyć. Praca deweloperska za coś, co jest w istocie zmianą procesu biznesowego.
n8n (github.com/n8n-io/n8n) proponuje wyprowadzenie tej warstwy poza aplikację. Aplikacja emituje zdarzenie w jedno miejsce, a to, co dalej się z nim dzieje, jest opisane na kanwie, którą da się zmienić bez wdrożenia. Poniżej: co ta platforma realnie potrafi, jak ją postawić w Dockerze w wariancie, który przeżyje produkcję, jak ją poprawnie zszyć z aplikacją w Laravelu, gdzie leżą granice i co mówi licencja — bo n8n nie jest open source i to nie jest szczegół.
Co to jest i na czym stoi
n8n to platforma do budowania przepływów pracy: pobiera dane z jednego miejsca, przekształca je i wysyła gdzie indziej, uruchamiana webhookiem, harmonogramem, zdarzeniem z zewnętrznej usługi albo ręcznie. Przepływ rysuje się na kanwie z nodów połączonych krawędziami, a każdy node to albo integracja z konkretną usługą, albo element logiki (warunek, pętla, agregacja), albo kawałek własnego JavaScriptu.
Nazwa bierze się od „nodemation” i czyta się n-eight-n. Jan Oberhauser, założyciel projektu, tłumaczy w README, że wszystkie sensowne domeny były zajęte, a „nodemation” było za długie, żeby wpisywać je w terminalu.
Stan repozytorium na 9 września 2026, prosto z API GitHuba:
- 203 795 gwiazdek i 60 622 forki — jeden z najpopularniejszych projektów na GitHubie w ogóle, nie tylko w swojej kategorii,
- repozytorium założone 22 czerwca 2019, kod w TypeScripcie, monorepo z pakietami CLI, edytora i nodów,
- około 425 kontrybutorów, 380 otwartych zgłoszeń i 798 otwartych pull requestów,
- ponad 1200 commitów w ostatnich trzydziestu dniach — to nie jest projekt utrzymywany po godzinach, to zespół pracujący na pełny etat,
- najnowsze wydanie
n8n@2.39.0z 8 września 2026; kanałstablew rejestrze obrazów został tego samego dnia przestawiony na tę wersję, - licencja Sustainable Use License plus n8n Enterprise License na część plików — wracamy do tego na końcu.
Skala integracji: README mówi o 1500+ integracjach i ponad 9000 szablonów przepływów w publicznej bibliotece. Ta druga liczba jest w praktyce ważniejsza od pierwszej — większość rzeczy, które chce się zrobić na start, ktoś już zrobił i opisał, a szablon importuje się do instancji jako gotowy przepływ do przerobienia.
Kadencja wydań to nowa wersja minor prawie co tydzień, z równoległymi kanałami stable (do produkcji) i beta (najnowsze wydanie, może być niestabilne). Dokumentacja zaleca aktualizację co najmniej raz w miesiącu, żeby nie przeskakiwać kilku wersji naraz — przy tej częstotliwości wydań to rozsądna rada, a nie formalność.
Instalacja w Dockerze
Najkrótsza droga to jednolinijkowiec z instalatorem, który stawia komplet usług sam:
curl -fsSL https://get.n8n.io | shDo zrozumienia, co się właściwie stawia, lepiej jednak przejść przez wariant ręczny. Minimalny start:
docker volume create n8n_data
docker run -it --rm \
--name n8n \
-p 5678:5678 \
-e GENERIC_TIMEZONE="Europe/Warsaw" \
-e TZ="Europe/Warsaw" \
-e N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true \
-v n8n_data:/home/node/.n8n \
n8nio/n8nEdytor wstaje na http://localhost:5678. Trzy rzeczy w tej komendzie są istotniejsze, niż wyglądają:
- Dwie zmienne strefy czasowej, nie jedna.
TZustawia strefę systemową kontenera, czyli to, co zwrócidatei co zobaczy kod w nodzie Code.GENERIC_TIMEZONEustawia strefę dla nodów opartych o harmonogram. Ustawienie tylko jednej z nich kończy się przepływem, który odpala się o niewłaściwej godzinie, i logami, które kłamią o tym, kiedy to było, - Wolumen na
/home/node/.n8nnie jest opcjonalny. Leży w nim baza SQLite, klucz szyfrujący poświadczenia i ustawienia instancji. Kontener bez wolumenu traci wszystko przy pierwszymdocker rm, N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=truewymusza restrykcyjne uprawnienia na pliku konfiguracyjnym. Domyślnie jestfalse, co jest wygodne przy zabawie i złe na serwerze.
Klucz szyfrujący ustaw ręcznie, zanim będzie za późno
n8n przechowuje poświadczenia do zewnętrznych usług zaszyfrowane w bazie. Klucz generuje sam przy pierwszym starcie i zapisuje w katalogu .n8n. To wygodne i jest to jednocześnie najczęstszy sposób na nieodwracalną utratę wszystkich poświadczeń: kontener odtworzony bez wolumenu dostaje nowy klucz, a rekordy w bazie zostają zaszyfrowane starym.
N8N_ENCRYPTION_KEY=<wygenerowany-losowo-klucz-trzymany-w-menedzerze-sekretow>Klucz szyfrujący ustaw jawnie przy pierwszym wdrożeniu i traktuj jak sekret produkcyjny, nie jak plik w wolumenie. Ten sam klucz musi mieć instancja główna i każdy worker — inaczej worker nie odczyta poświadczeń z bazy i wykonania będą się wywracać na uwierzytelnianiu.
Warto wiedzieć, że każdą zmienną można podać w pliku zamiast w środowisku, dopisując do jej nazwy sufiks _FILE — N8N_ENCRYPTION_KEY_FILE wskazuje na plik z kluczem. To wprost pasuje do sekretów Dockera i Kubernetesa.
Postgres zamiast SQLite
SQLite wystarcza do sprawdzenia narzędzia i do instancji, na której działa kilka przepływów. Do czegokolwiek, co ma chodzić bez przerwy i obsługiwać więcej niż paru użytkowników, dokumentacja zaleca Postgresa. Konfiguracja to komplet zmiennych DB_*:
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=...
DB_POSTGRESDB_SCHEMA=publicPrzy Postgresie katalog .n8n nadal warto trzymać na wolumenie — poza bazą SQLite leżą w nim klucz szyfrujący, logi instancji i zasoby funkcji kontroli wersji. Dokumentacja jest tu jednoznaczna: da się to obejść, ale nie warto.
Jedna pułapka, która w dokumentacji jest opatrzona ostrzeżeniem i zasługuje na powtórzenie: Postgres 18 zmienił domyślne miejsce składowania danych. Bez jawnego ustawienia PGDATA baza ląduje poza wolumenem i po restarcie wstaje pusta.
postgres:
image: postgres:18
restart: always
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
PGDATA: /var/lib/postgresql/data
volumes:
- db-storage:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d n8n"]
interval: 5s
timeout: 5s
retries: 10Druga sprawa z tej samej rodziny: przejście z istniejącego Postgresa w starszej wersji na 18 to aktualizacja wersji głównej, której nie da się zrobić samą podmianą taga obrazu. Kontener wstanie z błędem database files are incompatible with server. Dane zostają nietknięte, ale trzeba przejść ścieżką z pg_dumpall.
Warto też z góry przyjąć, że n8n dostaje własną bazę, a nie schemat w bazie aplikacji. Migracje n8n chodzą przy każdym starcie kontenera i nie ma powodu, żeby dotykały tej samej instancji, w której siedzą tabele produktu.
Zasoby i stos z asystentem
Zalecany dziś sposób instalacji to Docker Compose, przy czym pełny stos opisany w dokumentacji zawiera więcej niż samo n8n: usługi sandbox-certs, sandbox-api i sandbox-runner-1 obsługujące asystenta AI oraz searxng jako backend wyszukiwania. Wymagania to minimum 4 GB RAM i 2 vCPU — głównie z powodu runnera, który działa w trybie Docker-in-Docker i jest kontenerem uprzywilejowanym.
To ważna informacja przy wycenie hostingu. Jeśli asystent AI nie jest potrzebny, ten cały fragment stosu można pominąć i zejść z wymaganiami do poziomu zwykłej aplikacji w Node. Jeśli jest potrzebny na produkcji, dokumentacja zaleca zewnętrznego dostawcę piaskownicy (Daytona) zamiast wbudowanej — uprzywilejowany kontener z Dockerem w środku, uruchamiający kod wygenerowany przez model, to nie jest coś, co chce się mieć na tej samej maszynie co reszta.
Weryfikacja po starcie, wprost z dokumentacji:
docker compose up -d
docker compose ps
curl -sf http://localhost:5678/healthzZa reverse proxy
Instancja wystawiona pod własną domeną potrzebuje kilku zmiennych, o których łatwo zapomnieć, bo edytor działa i bez nich — psują się dopiero webhooki i linki w mailach.
N8N_HOST=n8n.przyklad.pl
N8N_PROTOCOL=https
N8N_PORT=5678
N8N_EDITOR_BASE_URL=https://n8n.przyklad.pl
WEBHOOK_URL=https://n8n.przyklad.pl
N8N_PROXY_HOPS=1N8N_EDITOR_BASE_URLto publiczny adres edytora. Używany także w mailach wysyłanych przez n8n i jako adres powrotny przy uwierzytelnianiu SAML,WEBHOOK_URLrozstrzyga, jaki adres n8n pokaże w nodzie webhooka i jaki zarejestruje w zewnętrznych usługach. Bez tego dostajeszhttp://localhost:5678/webhook/...i wklejasz go do panelu dostawcy płatności,N8N_PROXY_HOPSdomyślnie wynosi0. Za jednym proxy trzeba ustawić1, inaczej n8n widzi adres IP proxy zamiast klienta,N8N_SECURE_COOKIEjest domyślnietrue. Przy dostępie po czystym HTTP (na przykład z adresu IP w sieci wewnętrznej) logowanie nie zadziała, dopóki nie ustawi się tego nafalse— co jest akceptowalne tylko lokalnie,N8N_PATHpozwala wystawić n8n na podścieżce, ale dokumentacja wprost odradza łączenie go z reverse proxy: albo subdomena z proxy, albo podścieżka bez. Kombinacja obu psuje nawigację.
Skalowanie: tryb kolejkowy
Domyślnie n8n działa w trybie regular — jeden proces przyjmuje wywołania i sam wykonuje przepływy. Do większego obciążenia jest tryb queue, w którym instancja główna tylko generuje wykonania, a robotę robią osobne procesy worker.
Przepływ danych wygląda tak: instancja główna obsługuje timery i webhooki i tworzy wykonanie bez uruchamiania go, przekazuje jego identyfikator do Redisa, worker podnosi zadanie z kolejki, pobiera definicję przepływu z bazy, wykonuje ją, zapisuje wynik do bazy i informuje Redisa o zakończeniu, a ten powiadamia instancję główną.
EXECUTIONS_MODE=queue
QUEUE_BULL_REDIS_HOST=redis
QUEUE_BULL_REDIS_PORT=6379
QUEUE_BULL_REDIS_PASSWORD=...
N8N_ENCRYPTION_KEY=<ten-sam-co-w-instancji-glownej>
QUEUE_HEALTH_CHECK_ACTIVE=trueWorker to ten sam obraz z innym argumentem:
docker run --name n8n-worker n8nio/n8n workerKażdy worker wystawia własny serwer z punktami /healthz i /healthz/readiness (drugi sprawdza połączenia z bazą i Redisem), o ile włączy się QUEUE_HEALTH_CHECK_ACTIVE. To jest dokładnie to, czego potrzebuje sonda w Kubernetesie albo w orkiestratorze kontenerów. Domyślny czas na dokończenie zadań przy wyłączaniu procesu to 30 sekund i steruje nim N8N_GRACEFUL_SHUTDOWN_TIMEOUT.
Trzy ograniczenia trybu kolejkowego, które trzeba znać przed decyzją:
- SQLite nie wchodzi w grę. Rozproszony układ nad SQLite nie jest wspierany — Postgres jest wymogiem, nie zaleceniem,
- Dane binarne na dysku nie działają w trybie kolejkowym. Przepływy, które muszą utrwalać pliki, potrzebują zewnętrznego składowania w S3 — a to jest funkcja płatna, poza edycją Community. Jeśli automatyzacja przetwarza faktury w PDF, to zdanie zmienia rachunek za całe wdrożenie,
- Tryb multi-main jest płatny. Sam tryb kolejkowy jest w darmowej edycji, ale wiele instancji głównych naraz (czyli brak pojedynczego punktu awarii po stronie triggerów) już nie.
Dodatkowo warto od razu ustawić N8N_CONCURRENCY_PRODUCTION_LIMIT — domyślnie jest -1, czyli bez limitu. Jeden przepływ odpalony w pętli po dużym zbiorze danych potrafi bez tego zająć cały worker.
Dane wykonań rosną szybciej, niż się wydaje
n8n domyślnie zapisuje pełne dane wejściowe i wyjściowe każdego noda w każdym wykonaniu — po sukcesie i po błędzie. Przy przepływie odpalanym co minutę i przenoszącym kilkaset rekordów tabela wykonań rośnie w tempie, które zaskakuje po miesiącu, a nie po roku.
Przycinanie jest włączone domyślnie (EXECUTIONS_DATA_PRUNE=true), ale progi są hojne: 336 godzin, czyli 14 dni (EXECUTIONS_DATA_MAX_AGE) i 10 000 wykonań (EXECUTIONS_DATA_PRUNE_MAX_COUNT). Usuwanie jest dwufazowe — miękkie oznaczanie co 60 minut, twarde usuwanie co 15 minut, z godzinnym buforem między jednym a drugim.
Realistyczny zestaw dla instancji, która ma po prostu działać:
EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
EXECUTIONS_DATA_SAVE_ON_ERROR=all
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false
EXECUTIONS_DATA_MAX_AGE=168
EXECUTIONS_DATA_PRUNE_MAX_COUNT=5000
N8N_DEFAULT_BINARY_DATA_MODE=filesystemZapisywanie danych tylko przy błędach to zmiana, którą trzeba podjąć świadomie: diagnostyka udanego wykonania staje się niemożliwa, bo nie ma czego obejrzeć. W zamian baza przestaje puchnąć. Przy przepływach obsługujących dane osobowe ten wybór ma jeszcze drugie dno — dane z każdego przebiegu leżą w bazie n8n przez dwa tygodnie i podlegają tym samym obowiązkom co reszta danych osobowych w firmie. EXECUTIONS_DATA_SAVE_ON_SUCCESS=none jest w tym kontekście nie tylko oszczędnością miejsca.
Ostatnia zmienna przenosi dane binarne z bazy na dysk. Domyślny tryb (default) trzyma pliki w bazie danych, z limitem 512 MB na plik — a plik w bazie to plik w każdej kopii zapasowej bazy.
Node Code i jego granice
Kanwa załatwia większość przypadków, ale nie wszystkie. Node Code pozwala wstawić w przepływ własny JavaScript, w dwóch trybach: Run Once for All Items (kod wykonuje się raz, niezależnie od liczby elementów wejściowych) i Run Once for Each Item (kod wykonuje się dla każdego elementu osobno). Dostępne są obietnice, console.log trafia do konsoli przeglądarki, a dane i metody n8n są pod zmiennymi z prefiksem $.
Domyślnie importowanie modułów jest zablokowane. Przy self-hostingu odblokowuje się je dwiema zmiennymi:
# wszystkie moduły wbudowane Node.js
NODE_FUNCTION_ALLOW_BUILTIN=*
# albo tylko wybrane
NODE_FUNCTION_ALLOW_BUILTIN=crypto,fs
# moduły zewnętrzne z node_modules instancji
NODE_FUNCTION_ALLOW_EXTERNAL=luxon,lodashUwaga niepozorna, a kosztująca godzinę szukania: jeśli instancja korzysta z task runnerów, te zmienne trzeba ustawić na runnerach, a nie na głównym procesie n8n. Od wersji 2.0 runnery są włączone domyślnie, więc dotyczy to praktycznie każdego świeżego wdrożenia.
O Pythonie warto wiedzieć jedno zdanie, żeby nie planować na nim wdrożenia: n8n 2 nie wspiera już Pythona w nodzie Code. Wsparcie istniało od wersji 1.0 i było realizowane przez Pyodide — port CPythona do WebAssembly, ograniczony do paczek dostępnych w Pyodide i wolniejszy od JavaScriptu z powodu dodatkowej kompilacji. Dokumentacja opisuje tę funkcję jako przestarzałą i wycofaną.
Jak zszyć to z aplikacją w Laravelu
Tu zaczyna się część, która decyduje, czy n8n będzie pomocne, czy stanie się drugim, nietestowanym backendem obok pierwszego.
Kierunek pierwszy: aplikacja powiadamia n8n
Node Webhook wystawia adres, pod który można wysłać żądanie. Dwie rzeczy o nim, zanim pójdzie kod:
- Są dwa adresy: testowy i produkcyjny. Testowy działa tylko wtedy, gdy w edytorze wciśnie się „Listen for Test Event”, i pokazuje dane wprost na kanwie. Produkcyjny działa po opublikowaniu przepływu i nie pokazuje nic w edytorze — dane wykonania oglądasz w zakładce Executions. Wklejenie adresu testowego do konfiguracji aplikacji to najczęstszy pierwszy błąd i objawia się przepływem, który „działał wczoraj”,
- Uwierzytelnianie jest wbudowane. Node przyjmuje Basic auth, uwierzytelnianie nagłówkiem albo JWT. Webhook bez żadnego z tych trybów to publiczny punkt wejścia do procesu biznesowego,
- Limit rozmiaru to 16 MB, zmienny przez
N8N_PAYLOAD_SIZE_MAX. Dla plików wmultipart/form-datajest osobny limit zN8N_FORMDATA_FILE_SIZE_MAX, domyślnie 200 MB.
Po stronie Laravela wywołanie idzie z kolejkowanego nasłuchiwacza, nie z kontrolera — zewnętrzne HTTP w cyklu żądania to gwarantowany incydent w dniu, w którym n8n będzie restartowane:
<?php
namespace App\Listeners;
use App\Events\OrderPaid;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Http;
class NotifyAutomationPlatform implements ShouldQueue
{
public int $tries = 5;
public array $backoff = [10, 60, 300];
public function handle(OrderPaid $event): void
{
Http::withHeaders([
'X-Automation-Token' => config('services.n8n.token'),
])
->timeout(10)
->post(config('services.n8n.order_paid_url'), [
'order_id' => $event->order->getKey(),
'total_gross' => $event->order->total_gross,
'currency' => $event->order->currency,
'customer_email' => $event->order->customer->email,
])
->throw();
}
}Ładunek jest tu celowo płaski i minimalny: identyfikatory plus to, co potrzebne do decyzji. Jeśli przepływ potrzebuje więcej, niech dopyta API aplikacji — inaczej każda zmiana modelu w Laravelu wymusza zmianę przepływu na kanwie.
Kierunek drugi: n8n wywołuje aplikację
Kiedy przepływ ma coś zapisać w aplikacji, obowiązuje jedna zasada: przez API, nigdy wprost do bazy. Node Postgres potrafi połączyć się z bazą aplikacji i to jest właśnie ta wygoda, która za pół roku wywala się na obserwatorze modelu, który się nie wykonał, walidacji, która się nie odpaliła, i cache'u, który się nie unieważnił.
<?php
// routes/api.php
use App\Http\Controllers\Api\Automation\OrderStatusController;
use Illuminate\Support\Facades\Route;
Route::middleware('automation.token')
->prefix('automation')
->group(function (): void {
Route::patch('orders/{order}/status', OrderStatusController::class);
});<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class VerifyAutomationToken
{
public function handle(Request $request, Closure $next): Response
{
$expected = (string) config('services.n8n.inbound_token');
$provided = (string) $request->header('X-Automation-Token');
abort_unless(
$expected !== '' && hash_equals($expected, $provided),
Response::HTTP_UNAUTHORIZED,
);
return $next($request);
}
}hash_equals zamiast === nie jest tu ozdobą — porównanie sekretów w stałym czasie to standard, a nie nadmiarowa ostrożność. Reszta jest zwyczajna: osobny prefiks tras, osobny token, własny kontroler z FormRequest, normalne testy funkcjonalne. Dzięki temu przepływ na kanwie jest jednym z klientów API i podlega tym samym regułom co każdy inny.
Co zostaje w Laravelu, a co idzie na kanwę
Podział, który sprawdza się w praktyce:
- W aplikacji: wszystko, co musi być spójne (transakcje, zmiany stanu zamówienia, rozliczenia), wszystko, co ma testy, i wszystko, co jest częścią produktu — czyli to, za co klient płaci,
- Na kanwie: rozsyłanie zdarzeń do zewnętrznych usług, powiadomienia, raporty cykliczne, uzupełnianie danych z zewnętrznych API, procesy, które zmieniają się częściej niż raz na kwartał i o których zmianie decyduje ktoś inny niż zespół deweloperski,
- Nigdzie: logika, która musi być atomowa, ale została rozłożona na sześć nodów z wywołaniami HTTP pomiędzy. Przepływ nie ma transakcji — awaria w czwartym nodzie zostawia trzy pierwsze wykonane. Da się to obsłużyć kompensacją, ale trzeba ją napisać świadomie, a nie odkryć po incydencie.
Wersjonowanie i praca zespołowa
Tu jest najbardziej odczuwalna różnica między n8n a kodem w repozytorium. Przepływy są rekordami w bazie danych, nie plikami w Git. Darmowa edycja Community nie ma kontroli wersji przez Git, nie ma projektów, nie ma współdzielenia przepływów ani poświadczeń (dostęp ma właściciel instancji i autor) i nie ma środowisk. Wszystko to są funkcje planów płatnych.
Praktyczne konsekwencje i obejścia:
- Eksportuj definicje do repozytorium. Przepływ to JSON, dostępny przez CLI, przez publiczne API i przez „Import from File” w edytorze. Cykliczny eksport do repozytorium daje historię zmian i możliwość odtworzenia instancji od zera. To nie to samo co Git w edytorze, ale ratuje w dniu, w którym ktoś skasuje przepływ,
- Zarejestruj instancję — bezpłatnie. Edycja „Registered Community” to ta sama darmowa edycja z kluczem licencyjnym otrzymanym za podanie adresu e-mail. Odblokowuje foldery, debugowanie w edytorze (kopiowanie i przypinanie danych z wykonania) oraz własne dane wykonań. Przy dwudziestu przepływach same foldery są warte tej minuty,
- Model Save/Publish z wersji 2.0 rozwiązuje część problemu. Przycisk Save zapisuje zmiany bez ruszania wersji produkcyjnej, a Publish wypuszcza je na żywo. Wcześniej zapis oznaczał natychmiastową zmianę w działającym procesie,
- Dane przypięte w edytorze nie działają na produkcji. Przypięcie zamraża wyjście noda na czas pracy nad przepływem; wykonanie produkcyjne zawsze pobiera dane od nowa. Dobrze o tym pamiętać, zanim przypięty rekord testowy uzna się za dowód, że przepływ działa.
Błędy, obserwowalność, API
Do obsługi awarii służy przepływ błędów: osobny przepływ zaczynający się nodem Error Trigger, wskazany w ustawieniach przepływu głównego. Jeden taki przepływ może obsługiwać wiele innych. Dostaje strukturę, którą da się od razu wysłać na Slacka albo do systemu zgłoszeń:
[
{
"execution": {
"id": "231",
"url": "https://n8n.przyklad.pl/execution/231",
"error": { "message": "...", "stack": "..." },
"lastNodeExecuted": "Node With Error",
"mode": "manual"
},
"workflow": { "id": "1", "name": "Example Workflow" }
}
]Dwie rzeczy do zapamiętania: execution.id i execution.url pojawiają się tylko wtedy, gdy wykonanie zostało zapisane w bazie (co wiąże się z decyzją o EXECUTIONS_DATA_SAVE_ON_ERROR z poprzedniej sekcji), a błąd w samym nodzie startowym daje inny kształt ładunku — z sekcją trigger zamiast pełnego execution.
Metryki w formacie Prometheusa wystawia N8N_METRICS=true pod /metrics, z bogatym zestawem przełączników: metryki kolejki, cache'u, harmonogramu, triggerów odpytujących, DNS-a, a także etykiety per identyfikator przepływu i typ noda. Domyślnie wszystkie są wyłączone i dokładnie tak powinno zostać — etykieta z identyfikatorem przepływu na instancji z setką przepływów to eksplozja kardynalności w Prometheusie. Punkt sprawdzania stanu to /healthz, konfigurowalny przez N8N_ENDPOINT_HEALTH.
Publiczne REST API pozwala zarządzać przepływami, wykonaniami, poświadczeniami, folderami i tabelami danych z zewnątrz. Uwierzytelnianie to klucz w nagłówku:
curl -X GET 'https://n8n.przyklad.pl/api/v1/workflows?active=true' \
-H 'accept: application/json' \
-H 'X-N8N-API-KEY: <klucz>'Klucze tworzy się w Settings → n8n API, z etykietą i datą wygaśnięcia; zakresy uprawnień dla klucza są dostępne w planie Enterprise. Jeśli API nie jest używane, dokumentacja opisuje osobno, jak je wyłączyć — i warto to zrobić, bo klucz bez zakresów to klucz do całej instancji.
Warstwa AI: agenci i MCP
Część, o którą n8n rozrosło się najbardziej w ostatnich wydaniach, to obsługa modeli językowych. Node AI Agent spina model, narzędzia i pamięć w jedną jednostkę, którą wstawia się w przepływ jak każdy inny node, z podmienialnym dostawcą modelu.
Ciekawsze z perspektywy zespołu developerskiego jest jednak wsparcie dla Model Context Protocol, i to w trzech niezależnych rolach:
- MCP na poziomie instancji — n8n wystawia własny serwer MCP, więc klient (Claude Desktop, Claude Code, Codex, Cursor) może budować i edytować przepływy w instancji na podstawie opisu w języku naturalnym. Edycja istniejących przepływów działa od wersji 2.13,
- MCP Server Trigger — pojedynczy przepływ staje się serwerem MCP wystawiającym dokładnie te narzędzia, które się w nim zaprojektuje. To najkrótsza znana nam droga do udostępnienia wewnętrznego API jako narzędzia dla asystenta, bez pisania serwera MCP od zera,
- MCP Client Tool — kierunek odwrotny: przepływ n8n występuje jako klient i woła zewnętrzne serwery MCP.
Uwierzytelnianie klientów odbywa się przez OAuth albo klucz API. Jak przy każdym otwarciu instancji na narzędzia zewnętrzne: dostęp do serwera MCP to dostęp do przepływów, a przepływy mają poświadczenia do wszystkich podłączonych usług.
Licencja: to nie jest open source
n8n określa się jako fair-code, nie open source, i ta różnica ma praktyczne skutki. Kod jest widoczny, można go modyfikować i uruchamiać u siebie, ale licencja zawiera ograniczenie, którego nie ma w MIT ani w Apache 2.0.
Repozytorium dzieli się na trzy części:
- pliki i katalogi z
.eew nazwie nie są objęte Sustainable Use License — ich użycie wymaga ważnej licencji n8n Enterprise, - zawartość gałęzi innych niż
masternie jest licencjonowana wcale (drobiazg, ale wart odnotowania, jeśli ktoś planuje pracę na forku z gałęzi rozwojowej), - reszta jest dostępna na Sustainable Use License w wersji 1.0.
Sedno tej licencji to jedno ograniczenie: oprogramowania wolno używać i modyfikować wyłącznie na własne wewnętrzne potrzeby biznesowe albo do celów niekomercyjnych i osobistych, a rozprowadzać je lub udostępniać innym tylko nieodpłatnie i w celach niekomercyjnych. Nie wolno też usuwać ani zasłaniać informacji o licencji i prawach autorskich.
Co to znaczy w praktyce dla agencji i zespołu produktowego:
- Instancja n8n obsługująca własne procesy — bez problemu. To wprost „własne wewnętrzne potrzeby biznesowe”, niezależnie od tego, że firma jest komercyjna i że automatyzowane procesy przynoszą pieniądze,
- Wdrożenie i utrzymanie instancji u klienta, na jego infrastrukturze — również w porządku. Klient używa n8n na własne potrzeby, a wynagrodzenie za wdrożenie jest zapłatą za pracę, nie za oprogramowanie,
- Sprzedawanie dostępu do n8n jako usługi — nie. Hostowanie instancji dla wielu klientów i pobieranie za to abonamentu to udostępnianie oprogramowania odpłatnie, czyli dokładnie to, co ograniczenie wyklucza. To samo dotyczy produktu, w którym n8n jest ukrytym silnikiem oferowanym użytkownikom końcowym,
- Naruszenie ma 30 dni na naprawę. Licencja przewiduje automatyczne wygaśnięcie w razie użycia sprzecznego z warunkami, z przywróceniem wstecz, jeśli naruszenie ustanie w ciągu 30 dni od powiadomienia. Kolejne naruszenie po przywróceniu kończy licencję trwale.
Jeśli model wdrożenia znajduje się gdziekolwiek blisko granicy „udostępniamy n8n klientom”, to jest moment na e-mail do license@n8n.io, a nie na własną interpretację. Sustainable Use License jest krótka i czytelna, ale nie odpowiada na pytanie, po której stronie leży konkretny model biznesowy.Osobno warto ustawić oczekiwania co do funkcji. Darmowa Community ma, jak pisze dokumentacja, „prawie kompletny zestaw funkcji”, ale poza nim zostają: własne zmienne, środowiska, zewnętrzne magazyny sekretów, zewnętrzne składowanie danych binarnych, strumieniowanie logów (zwykłe logowanie jest w zestawie), tryb multi-main, projekty, SSO (SAML i LDAP), współdzielenie przepływów i poświadczeń oraz kontrola wersji przez Git. Definitywnym źródłem prawdy o podziale funkcji jest cennik n8n, bo ten podział się zmienia.
Co się zepsuje w n8n 3.0
Wersja 3.0 jest zapowiedziana na październik 2026, czyli za miesiąc od publikacji tego wpisu. Lista zmian łamiących zgodność jest już opublikowana i część z nich ma bezpośredni wpływ na sposób wdrożenia:
- Self-hosting tylko przez Dockera. Instalacje przez
npminpx n8nprzestaną być wspierane. Jeśli instancja stoi dziś na globalnym pakiecie npm, to jest zadanie do zaplanowania teraz, - Usunięte nody: Function, Function Item i Item Lists. Zamiennikiem pierwszych dwóch jest node Code w odpowiednim trybie, a Item Lists rozpada się na Split Out, Aggregate, Sort, Limit, Remove Duplicates i Summarize,
- Stare tryby noda AI Agent znikają — wersja 1 noda wraz z trybami SQL Agent, Conversational Agent, OpenAI Functions Agent, Plan and Execute Agent i ReAct Agent. Przepływy używające już trybu Tools Agent przechodzą aktualizację bez zmiany zachowania,
- Pomocnik
$getPairedItemzostaje usunięty na rzecz standardowego mechanizmu wiązania elementów (pairedItem,$("<node>").item), - Limity dekompresji spadają: domyślny maksymalny rozmiar rozpakowanego archiwum z 2 GiB do 256 MiB, a liczba wpisów w archiwum z 5000 do 1000. Przepływy pracujące na dużych archiwach muszą jawnie przywrócić stare wartości przed aktualizacją,
- Wycofane funkcje: Chat Hub oraz import przepływu z adresu URL w edytorze (pozostają kopiuj-wklej, import z pliku, CLI i API).
Kontekst z poprzedniej wersji głównej: n8n 2.0 wyszło 5 grudnia 2025 i było wydaniem „hardeningowym”, nie funkcjonalnym. Wtedy weszły task runnery jako domyślny sposób wykonywania kodu, zablokowany dostęp do zmiennych środowiskowych z noda Code, wyłączone domyślnie nody ExecuteCommand i LocalFileTrigger oraz usunięcie trybu trzymania danych binarnych w pamięci. Widać z tego kierunek, w którym idzie projekt: kolejne wersje główne zabierają luźne domyślne ustawienia, na których łatwo było zbudować coś działającego i niebezpiecznego. Do każdej wersji głównej n8n dostarcza Migration Report — narzędzie wskazujące problemy na poziomie przepływów i instancji przed aktualizacją. Warto je odpalić przed, a nie po.
Podsumowanie
n8n rozwiązuje konkretny, powtarzalny problem: warstwa integracji z zewnętrznymi usługami przestaje być kodem, który trzeba wdrażać, i staje się konfiguracją, którą można zmienić. Przy 1500 integracjach i 9000 szablonów większość typowych połączeń jest gotowa. Co z tego wynika przy planowaniu wdrożenia:
- Projekt jest zdrowy i bardzo aktywny — 203 795 gwiazdek, ponad 1200 commitów w trzydziestu dniach, wydanie minor prawie co tydzień, kanały
stableibeta. Ryzyko porzucenia jest tu praktycznie zerowe; realne ryzyko to tempo zmian, - Docker Compose z Postgresem to minimum produkcyjne — SQLite tylko do sprawdzenia narzędzia, wolumen na
/home/node/.n8nobowiązkowo,PGDATAjawnie przy Postgresie 18, żeby baza nie wstała pusta, N8N_ENCRYPTION_KEYustaw ręcznie przy pierwszym wdrożeniu — automatyczny klucz w wolumenie to najkrótsza droga do utraty wszystkich poświadczeń i ten sam klucz muszą mieć workery,- Za reverse proxy potrzebne są
N8N_EDITOR_BASE_URL,WEBHOOK_URLiN8N_PROXY_HOPS, bo edytor działa i bez nich, a webhooki nie, - Tryb kolejkowy z Redisem skaluje wykonania, ale wyklucza SQLite i dane binarne na dysku (potrzebne S3, funkcja płatna), a tryb multi-main jest w planie płatnym,
- Przycinanie danych wykonań przestaw z domyślnego — 14 dni i 10 000 wykonań to hojne progi, a przy danych osobowych zapisywanie pełnych ładunków każdego udanego przebiegu to decyzja, nie ustawienie techniczne,
- Integracja z Laravelem: webhook w jedną stronę, API w drugą. Zdarzenia z kolejkowanego nasłuchiwacza, wejście przez dedykowane trasy z tokenem w nagłówku sprawdzanym przez
hash_equals, i żadnego pisania z n8n wprost do bazy aplikacji, - Transakcyjności nie ma. Przepływ z sześciu nodów, który wywali się na czwartym, zostawia trzy pierwsze wykonane. Logika wymagająca atomowości zostaje w aplikacji,
- Zarejestruj darmową instancję — foldery, debugowanie w edytorze i własne dane wykonań za podanie adresu e-mail. Definicje przepływów eksportuj do repozytorium, bo Git w edytorze jest funkcją płatną,
- Aktualizuj co najmniej raz w miesiącu i przeczytaj listę zmian łamiących zgodność przed 3.0 w październiku 2026 — zniknie wsparcie dla instalacji przez npm, trzy stare nody i pierwsza wersja noda AI Agent.
Licencja: n8n jest rozpowszechniane jako fair-code na Sustainable Use License 1.0, z osobną n8n Enterprise License na pliki i katalogi zawierające .ee w nazwie. To nie jest licencja open source w rozumieniu OSI. Wolno używać i modyfikować n8n na własne wewnętrzne potrzeby biznesowe oraz do celów niekomercyjnych, a udostępniać je innym wyłącznie nieodpłatnie i niekomercyjnie. Instancja obsługująca procesy własnej firmy albo firmy klienta na jego infrastrukturze mieści się w tych warunkach bez zastrzeżeń. Odpłatne hostowanie n8n dla klientów albo wbudowanie go jako silnika w sprzedawany produkt — nie. Licencja przewiduje 30 dni na usunięcie naruszenia od momentu powiadomienia, z przywróceniem uprawnień wstecz, ale kolejne naruszenie kończy je trwale. Przy modelu biznesowym blisko tej granicy pytanie do license@n8n.io jest tańsze niż każda inna droga. Osobno: darmowa edycja Community nie zawiera SSO, projektów, środowisk, zewnętrznych sekretów, zewnętrznego składowania danych binarnych, strumieniowania logów, trybu multi-main, współdzielenia przepływów ani kontroli wersji przez Git — to funkcje planów Business i Enterprise.