Własną instancję n8n utrzymuję od ponad roku i pracuje na niej dziś ponad 20 przepływów, od porannych raportów po publikację treści na kilku stronach. Sama instalacja zajmuje około godziny. Więcej uwagi wymagają rzeczy, o których łatwo zapomnieć przy pierwszym uruchomieniu: klucz szyfrowania, kopie zapasowe i historia wykonań, która rośnie z każdym przebiegiem. Opisuję całość w kolejności, w jakiej ją konfiguruję.
Czy n8n self-hosted jest darmowy?
Tak. Wersja Community do samodzielnego hostowania nie ma opłat licencyjnych ani limitu wykonań; płacisz za serwer. Licencja fair-code ogranicza głównie odsprzedawanie n8n jako usługi, a część funkcji dla większych firm, takich jak logowanie SSO czy osobne środowiska, wymaga płatnej licencji Enterprise. Różnice między własną instalacją a n8n Cloud opisałem w przewodniku n8n: co to jest i jak działa.
Czego potrzebujesz do instalacji?
- serwera VPS z Linuksem; na start wystarczą 2 vCPU i 4 GB RAM, więcej pamięci potrzebują przepływy, które przetwarzają duże pliki albo setki elementów naraz,
- Dockera z wtyczką Compose,
- domeny albo subdomeny, na przykład
n8n.twojafirma.pl, skierowanej na adres serwera.
Plik docker-compose.yml dla n8n z PostgreSQL
Domyślnie n8n zapisuje dane w SQLite. Do instalacji firmowej wybieram PostgreSQL: lepiej znosi równoległe wykonania i łatwiej go kopiować.
services:
postgres:
image: postgres:16
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- db_data:/var/lib/postgresql/data
n8n:
image: docker.n8n.io/n8nio/n8n
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
DB_TYPE: postgresdb
DB_POSTGRESDB_HOST: postgres
DB_POSTGRESDB_DATABASE: n8n
DB_POSTGRESDB_USER: n8n
DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
N8N_HOST: n8n.twojafirma.pl
N8N_PROTOCOL: https
WEBHOOK_URL: https://n8n.twojafirma.pl/
N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
GENERIC_TIMEZONE: Europe/Warsaw
TZ: Europe/Warsaw
EXECUTIONS_DATA_PRUNE: "true"
EXECUTIONS_DATA_MAX_AGE: "336"
volumes:
- n8n_data:/home/node/.n8n
depends_on:
- postgres
volumes:
db_data:
n8n_data:
Port 5678 wystawiam tylko na 127.0.0.1, więc z internetu n8n jest dostępny wyłącznie przez serwer pośredniczący z HTTPS. W środowisku produkcyjnym podaję też konkretną wersję obrazu zamiast domyślnej najnowszej, żeby termin aktualizacji wybierać samemu.
Hasło bazy i klucz szyfrowania trzymam w pliku .env obok, poza repozytorium:
POSTGRES_PASSWORD=dlugie-losowe-haslo
N8N_ENCRYPTION_KEY=wynik-polecenia-openssl-rand-hex-32
Klucz generuję poleceniem openssl rand -hex 32, a całość uruchamiam przez docker compose up -d.
Co się stanie, gdy zgubisz klucz szyfrowania?
n8n szyfruje tym kluczem zapisane dane dostępowe: hasła, tokeny API i klucze do usług. Bez zmiennej N8N_ENCRYPTION_KEY n8n generuje własny klucz i zapisuje go w wolumenie n8n_data. Przy przenosinach na nowy serwer albo po utracie wolumenu baza z przepływami wstaje, ale zapisanych poświadczeń nie da się odszyfrować i trzeba je wpisać od nowa, jedno po drugim. Klucz przechowuję w menedżerze haseł, osobno od kopii bazy.
Jak wystawić n8n przez HTTPS?
Webhooki i logowanie wymagają HTTPS, więc przed n8n stawiam serwer pośredniczący (reverse proxy). Caddy pobiera certyfikat Let’s Encrypt samodzielnie, a konfiguracja mieści się w trzech liniach:
n8n.twojafirma.pl {
reverse_proxy 127.0.0.1:5678
}
Nginx albo Traefik zadziałają tak samo, jeśli przekazują połączenia WebSocket, z których korzysta edytor n8n. Zmienna WEBHOOK_URL musi wskazywać adres publiczny. Bez niej węzły webhook pokazują adres z localhost, pod który zewnętrzna usługa niczego nie wyśle.
Kopie zapasowe i aktualizacje
Kopia składa się z dwóch elementów: zrzutu bazy PostgreSQL i klucza szyfrowania. Zrzut bazy uruchamiaj z crona raz na dobę:
docker compose exec -T postgres pg_dump -U n8n n8n > n8n-$(date +%F).sql
Kopię wysyłam poza serwer, bo kopia na tym samym dysku przepada razem z nim. Dodatkowo eksport przepływów do plików (n8n export:workflow --all --output=... uruchomione w kontenerze) daje wersjonowaną historię zmian w repozytorium Git.
Aktualizacja to docker compose pull, a potem docker compose up -d. Przed większą wersją czytam informacje o zmianach, bo nowe wersje n8n potrafią zmienić zachowanie węzłów, a przepływy produkcyjne sprawdzam zaraz po aktualizacji.
Czego pilnuję po instalacji?
- Historia wykonań. n8n zapisuje wejście i wyjście każdego węzła. W historii jednego z moich przepływów znalazłem token dostępu zwrócony przez API dostawcy danych. Przy przepływach, które dotykają danych dostępowych albo osobowych, wyłączam w ustawieniach przepływu zapisywanie udanych wykonań, a zmienną
EXECUTIONS_DATA_MAX_AGEograniczam, jak długo n8n przechowuje resztę (wartość 336 to 14 dni). - Alerty o błędach. Przepływ, który pada po cichu, wygląda z zewnątrz tak samo jak przepływ, który nie ma nic do zrobienia. Mój radar pozycji w Google przez tydzień kończył się błędem, bo dostawca danych przeniósł swoje API pod nowy adres, a wyszło to dopiero przy przeglądzie stanu stron. Na takie sytuacje n8n ma przepływ błędów: węzeł Error Trigger w osobnym przepływie, wskazanym w ustawieniach przepływów produkcyjnych, który przy każdej porażce wysyła alert na komunikator.
- Dostęp do panelu. Silne hasła, uwierzytelnianie dwuskładnikowe dla kont i baza danych niewystawiona do internetu.
Kiedy lepiej wybrać n8n Cloud?
Gdy w firmie brakuje osoby, która raz w miesiącu zaktualizuje kontener i sprawdzi, czy kopie się wykonują. Chmura zdejmuje z Ciebie administrację w zamian za abonament z limitem wykonań. Przy kilku lekkich przepływach to rozsądny start, a przeniesienie się później na własny serwer oznacza eksport przepływów i ponowne wpisanie poświadczeń.
Jeśli wolisz, żeby instalację i opiekę wziął ktoś inny, wdrażam n8n w firmach razem z konfiguracją serwera, kopiami i monitoringiem. Przykłady przepływów, które pracują u mnie na takiej instalacji, zebrałem w tekście n8n: przykłady użycia.