Poradniki 21 min czytania

n8n Docker: instalacja i konfiguracja krok po kroku

Autor: Bartłomiej Bernat
n8n w Dockerze - kontener n8n z workflowem obok kontenerów reverse proxy z kłódką i bazy danych na jednym serwerze, z wolumenem na dane i ruchem z internetu

Co to jest n8n w Dockerze i jakie daje zalety?

n8n w Dockerze tworzy spójne, izolowane środowisko, w którym aplikacja działa razem ze wszystkimi potrzebnymi zależnościami. Dzięki temu hosting automatyzacji jest prostszy, a problemy wynikające z różnic między systemami operacyjnymi i bibliotekami pojawiają się znacznie rzadziej. Dokumentacja n8n zaleca Dockera do większości instalacji na własnym serwerze.

n8n to platforma do budowania zaawansowanych przepływów pracy i agentów AI. Jej kod źródłowy jest publicznie dostępny, ale na licencji fair-code (Sustainable Use License), a nie open source. Jeśli dopiero poznajesz narzędzie, zacznij od wpisu n8n: co to jest, jak działa i ile kosztuje. Kontener uruchomisz na komputerze, serwerze Linux czy VPS. Nie trzeba więc instalować wszystkich zależności bezpośrednio w systemie operacyjnym, co ułatwia wdrażanie i późniejszą konfigurację automatyzacji.

Najważniejsze korzyści z używania n8n w Dockerze to:

  • przenośność: możliwość uruchomienia na różnych platformach,
  • izolacja aplikacji: kontener oddziela n8n od pozostałych usług,
  • uproszczona instalacja: środowisko można szybciej wdrożyć i skonfigurować,
  • mniej problemów: mniejsze ryzyko niezgodności systemowych,
  • kontrola: zachowujesz pełną kontrolę nad danymi i infrastrukturą,
  • dostosowanie: środowisko automatyzacji można elastycznie konfigurować.

Trzeba jednak pamiętać, że Docker nie zwalnia administratora z odpowiedzialności. Przy samodzielnym hostingu nadal należy zarządzać zasobami serwera, regularnie instalować aktualizacje, wykonywać kopie zapasowe i dbać o bezpieczeństwo kontenera n8n.

Jakie są wymagania do uruchomienia n8n na Dockerze?

Aby uruchomić n8n na Dockerze, potrzebujesz Docker Desktop dla systemu macOS, Windows lub Linux. Zawiera on Docker Engine i Docker Compose. Jeśli korzystasz z serwera Linux bez interfejsu graficznego, na przykład z VPS, zainstaluj osobno Docker Engine oraz Docker Compose.

Przed instalacją n8n sprawdź, czy oba narzędzia są dostępne:

docker --version
docker compose version

Wymagana jest wersja Compose v2, czyli polecenie docker compose (ze spacją). Starszego polecenia docker-compose oficjalny skrypt instalacyjny n8n nie obsługuje.

Self-hosting n8n wymaga wiedzy technicznej z zakresu:

  • serwerów i kontenerów,
  • konfiguracji DNS,
  • reguł firewalla,
  • wykonywania kopii zapasowych.

n8n poleca samodzielny hosting doświadczonym użytkownikom, bo błędy mogą skończyć się utratą danych, lukami bezpieczeństwa i przestojami. Jeśli nie masz doświadczenia z serwerami, producent sugeruje n8n Cloud. Na VPS to Ty odpowiadasz za dostępność zasobów, aktualizacje, bezpieczeństwo i prawidłową konfigurację środowiska Docker.

Bądź na bieżąco z AI

Zapisz się na newsletter i otrzymuj najnowsze poradniki, recenzje narzędzi AI i rankingi prosto na swoją skrzynkę.

Bez spamu. Wypisz się w dowolnym momencie.

Jak zainstalować n8n w kontenerze Docker?

Do szybkiego testu na własnym komputerze wystarczą dwa polecenia z dokumentacji n8n. Najpierw utwórz wolumen na dane:

docker volume create n8n_data

Następnie uruchom kontener. Strefę czasową ustaw na swoją, dla Polski to Europe/Warsaw:

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/n8n

Polecenie pobiera obraz kontenera, mapuje port 5678 i montuje wolumen n8n_data w katalogu /home/node/.n8n. GENERIC_TIMEZONE ustawia strefę czasową harmonogramów n8n, a TZ czas systemowy kontenera. Bez nich n8n liczy czas według strefy Nowego Jorku.

Po uruchomieniu edytor n8n otworzysz pod adresem http://localhost:5678.

Flagi -it --rm zapewniają interaktywną pracę oraz automatyczne usunięcie kontenera po zamknięciu terminala. Dane zapisane w wolumenie n8n_data zostają, więc kolejne uruchomienie tym samym poleceniem wróci do Twoich workflowów. To jednak tryb do prób. Do stałej pracy użyj Docker Compose.

Najszybszą drogą do pełnej instalacji jest oficjalny skrypt n8n:

curl -fsSL https://get.n8n.io | sh

Skrypt wymaga Dockera na Linuksie albo macOS, a na Windowsie działa przez WSL. Tworzy instalację Docker Compose z plikami compose.yml i .env i uruchamia n8n razem z usługą sandbox dla asystenta AI i wyszukiwarką SearXNG. Później zaktualizujesz ją poleceniem curl -fsSL https://get.n8n.io | sh -s -- --upgrade. Jak przy każdym skrypcie przekazywanym prosto do powłoki, warto najpierw obejrzeć go w przeglądarce.

Dlaczego warto wdrożyć n8n przez Docker Compose?

Wdrożenie n8n za pomocą Docker Compose oferuje większą wygodę i elastyczność niż uruchamianie aplikacji poleceniem docker run. Całe środowisko można opisać w jednym, przejrzystym pliku YAML, co ułatwia zarządzanie usługami, ich zależnościami oraz konfiguracją.

Najważniejsze zalety tego rozwiązania to:

  • powtarzalność: n8n można łatwo uruchomić na różnych serwerach, ograniczając ryzyko błędów konfiguracyjnych,
  • centralizacja konfiguracji: zmienne środowiskowe, porty i pozostałe ustawienia znajdują się w jednym pliku, dzięki czemu łatwiej je kontrolować i modyfikować,
  • obsługa wolumenów: proste podłączanie wolumenów do kontenerów pozwala zachować trwałość danych,
  • zintegrowane usługi: n8n można bez większego wysiłku połączyć z bazą PostgreSQL oraz reverse proxy w środowisku produkcyjnym.

Docker Compose umożliwia zarządzanie całym stosem aplikacji, co byłoby znacznie trudniejsze przy korzystaniu wyłącznie z pojedynczego polecenia docker run. W jednej definicji można uwzględnić nie tylko n8n, lecz także dodatkowe usługi współpracujące z aplikacją. Dokumentacja n8n poleca Compose właśnie do wdrożeń produkcyjnych z bazą danych i dodatkowymi usługami, a gotowe pliki dla różnych konfiguracji udostępnia w repozytorium n8n-io/n8n-hosting.

Plik Compose pełni również funkcję dokumentacji. Administratorzy mogą szybko przeanalizować konfigurację i wprowadzić potrzebne zmiany bez przeszukiwania wielu niezależnych poleceń. Aktualizację n8n ułatwiają proste komendy: docker compose pull, docker compose down oraz docker compose up -d. Dane przechowywane w wolumenach pozostają przy tym nienaruszone niezależnie od cyklu życia kontenerów.

Jak stworzyć plik Docker Compose dla n8n i go uruchomić?

Utwórz katalog projektu, na przykład n8n-compose, i dodaj w nim plik compose.yaml z definicją usługi n8n. Wykorzystaj obraz n8nio/n8n, skonfiguruj port 5678 oraz trwały wolumen na dane:

services:
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - GENERIC_TIMEZONE=Europe/Warsaw
      - TZ=Europe/Warsaw
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

To minimalna konfiguracja do pracy na własnym komputerze. Mapowanie portu 5678 otwiera edytor pod adresem http://localhost:5678, wolumen n8n_data chroni ustawienia i dane przed utratą podczas odtwarzania kontenera, a restart: always sprawia, że n8n wstaje sam po restarcie Dockera.

Uruchom n8n w tle:

docker compose up -d

Na Linuksie poprzedź polecenia sudo, jeśli Twój użytkownik nie należy do grupy docker. Status kontenera sprawdzisz poleceniem docker compose ps, a zatrzymasz go z zachowaniem wolumenu danych poleceniem docker compose stop.

Na serwerze produkcyjnym nie wystawiaj portu 5678 na świat. Oficjalny plik Compose dodaje Traefika jako reverse proxy, który obsługuje porty 80 i 443 oraz certyfikat HTTPS, a n8n nasłuchuje tylko lokalnie pod adresem 127.0.0.1:5678. Pełny plik znajdziesz w sekcji o certyfikacie SSL.

Jak skonfigurować kontener n8n i jakie zmienne środowiskowe ustawić?

Konfiguracja kontenera n8n opiera się na zmiennych środowiskowych. Możesz zadeklarować je bezpośrednio w sekcji environment pliku compose.yaml:

services:
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    environment:
      - N8N_HOST=n8n.example.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - N8N_WEBHOOK_URL=https://n8n.example.com/
      - GENERIC_TIMEZONE=Europe/Warsaw
      - TZ=Europe/Warsaw
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

Zmienne N8N_HOST, N8N_PORT i N8N_PROTOCOL określają adres, port i protokół instancji. Jeżeli n8n działa za reverse proxy z certyfikatem SSL, ustaw N8N_PROTOCOL=https. Przy instalacji lokalnej możesz natomiast użyć http.

N8N_WEBHOOK_URL wskazuje publiczny adres webhooków. Powinien odpowiadać adresowi, pod którym zewnętrzne usługi łączą się z n8n, bo nieprawidłowa wartość sprawi, że webhooki będą nieosiągalne. Zmienna działa od wersji 2.30, w starszych instalacjach nazywa się WEBHOOK_URL.

Za strefę czasową odpowiadają dwie zmienne:

  • GENERIC_TIMEZONE określa strefę harmonogramów n8n, na przykład węzła Schedule,
  • TZ ustawia systemowy czas kontenera, czyli to, co zwraca polecenie date.

W przypadku Polski dla obu zmiennych ustaw wartość Europe/Warsaw. Domyślna strefa n8n to America/New_York.

Ustawienie N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true wymusza uprawnienia 0600 do pliku ustawień, zmniejszając ryzyko nieautoryzowanego dostępu. Od n8n 2.0 to zachowanie domyślne.

Zmienna N8N_ENCRYPTION_KEY ustala klucz, którym n8n szyfruje zapisane poświadczenia. Bez niej n8n wygeneruje losowy klucz przy pierwszym uruchomieniu i zapisze go w katalogu /home/node/.n8n. Własny klucz zadziała tylko wtedy, gdy instancja nie zapisała jeszcze swojego, więc ustaw go przed pierwszym startem. Przechowuj go razem z kopią zapasową, bo zmiana klucza po zapisaniu poświadczeń uniemożliwi ich odszyfrowanie.

Wartości wrażliwe trzymaj w pliku .env w katalogu projektu. Docker Compose wczytuje go automatycznie i podstawia wartości w miejsce zapisu ${NAZWA_ZMIENNEJ}:

N8N_ENCRYPTION_KEY=zmien-na-staly-losowy-klucz

Plik .env zawiera wrażliwe dane, dlatego nie publikuj go w repozytoriach ani nie udostępniaj osobom nieuprawnionym.

Jak zapewnić trwałość danych w kontenerze n8n?

Trwałość danych kontenera n8n zapewnia wolumen n8n_data zamontowany w katalogu /home/node/.n8n. Znajdują się tam:

  • baza SQLite,
  • workflowy,
  • poświadczenia,
  • logi,
  • ustawienia,
  • klucz szyfrowania.

Dzięki temu dane aplikacji pozostają dostępne po restarcie, usunięciu albo wymianie kontenera. W pliku compose.yaml wolumen konfiguruje się następująco:

services:
  n8n:
    image: n8nio/n8n
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

Samo usunięcie kontenera nie kasuje danych zapisanych w wolumenie. Trwałość danych zależy jednak od zachowania wolumenu n8n_data: jego usunięcie oznacza utratę konfiguracji, workflowów, poświadczeń oraz pozostałych plików aplikacji. Uważaj na polecenie docker compose down -v, bo flaga -v usuwa także wolumeny.

Przy planowanej migracji na PostgreSQL wolumen n8n_data nadal jest potrzebny. Katalog /home/node/.n8n zawiera ważne ustawienia i klucz szyfrowania, dlatego jego brak może odciąć dostęp do zapisanej konfiguracji i poświadczeń.

Jak zrobić kopię zapasową wolumenu danych n8n?

Kopia zapasowa n8n powinna obejmować wolumen n8n_data oraz klucz szyfrowania (N8N_ENCRYPTION_KEY). Klucz jest konieczny do odszyfrowania zapisanych poświadczeń po przywróceniu środowiska.

Zacznij od eksportu workflowów i poświadczeń poleceniami CLI n8n. Działają one wewnątrz uruchomionego kontenera, więc wykonaj je, zanim go zatrzymasz:

docker exec -u node -it <kontener> n8n export:workflow --backup --output=/files/backups/
docker exec -u node -it <kontener> n8n export:credentials --backup --output=/files/backups/

W miejsce <kontener> wpisz nazwę kontenera z docker ps. W Compose ma ona zwykle postać n8n-compose-n8n-1. Ścieżka w --output dotyczy systemu plików kontenera, dlatego wskaż katalog zamontowany z hosta. W oficjalnym pliku Compose to /files, czyli ./local-files na serwerze. Flaga --backup eksportuje wyłącznie workflowy i poświadczenia, więc nie zastępuje kopii całego wolumenu.

Następnie zatrzymaj kontener n8n, żeby ograniczyć ryzyko niespójności plików SQLite:

docker compose stop n8n

Teraz utwórz archiwum wolumenu przy użyciu tymczasowego kontenera:

docker volume ls
mkdir -p backups
docker run --rm \
  -v n8n_data:/source:ro \
  -v "$PWD/backups":/backup \
  alpine \
  tar czf /backup/n8n_data.tar.gz -C /source .

Docker Compose dodaje do nazwy wolumenu przedrostek z nazwą projektu, na przykład n8n-compose_n8n_data. Sprawdź pełną nazwę w wyniku docker volume ls i wpisz ją zamiast n8n_data. Sama nazwa n8n_data utworzyłaby nowy, pusty wolumen i archiwum nie zawierałoby Twoich danych.

Plik n8n_data.tar.gz zawiera między innymi bazę SQLite, workflowy, poświadczenia, ustawienia, logi oraz klucz szyfrowania zapisany w katalogu /home/node/.n8n. Jeżeli n8n korzysta z PostgreSQL, kopia musi uwzględniać również tę bazę, bo archiwum wolumenu n8n_data jej nie zastępuje.

Kopię zapasową twórz przed każdą aktualizacją n8n. Pliki przechowuj poza hostem, na przykład na innym serwerze lub w szyfrowanym magazynie, a klucza szyfrowania nie umieszczaj w publicznych repozytoriach. Po zakończeniu uruchom usługę ponownie:

docker compose start n8n

Jak skonfigurować bazę danych w kontenerze n8n?

n8n obsługuje dwie bazy danych: SQLite i PostgreSQL. SQLite jest rozwiązaniem domyślnym, najlepiej sprawdzającym się w małych, lokalnych instalacjach. Plik database.sqlite jest przechowywany w katalogu /home/node/.n8n, więc trafia do wolumenu n8n_data razem z resztą danych.

SQLite nie wymaga żadnych zmiennych środowiskowych. Jeśli nie skonfigurujesz bazy, n8n przy pierwszym uruchomieniu sam utworzy plik database.sqlite w wolumenie. Usunięcie kontenera nie naruszy jego zawartości, ale skasowanie wolumenu oznacza utratę workflowów, poświadczeń i konfiguracji.

Od wersji n8n 2.0 SQLite działa wyłącznie przez sterownik z pulą połączeń w trybie WAL, według n8n nawet 10 razy szybszy od poprzedniego. MySQL i MariaDB nie są już obsługiwane jako baza n8n, dlatego nowe wdrożenia powinny korzystać z SQLite lub PostgreSQL.

Przy większych wdrożeniach, wielu użytkownikach i workflowach działających całą dobę bardziej odpowiedni będzie PostgreSQL. Uruchamia się go jako oddzielną usługę w tym samym pliku Docker Compose i łączy z n8n za pomocą zmiennych środowiskowych.

Jak skonfigurować bazę PostgreSQL w n8n?

Aby skonfigurować bazę PostgreSQL w n8n, ustaw zmienną DB_TYPE=postgresdb i uzupełnij parametry połączenia. Przykład z bazą w osobnym kontenerze:

services:
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      - DB_POSTGRESDB_SCHEMA=public
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=Europe/Warsaw
      - TZ=Europe/Warsaw
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres

  postgres:
    image: postgres:17
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  n8n_data:
  postgres_data:

Hasło do bazy i klucz szyfrowania wpisz do pliku .env (POSTGRES_PASSWORD=... i N8N_ENCRYPTION_KEY=...), zamiast umieszczać je bezpośrednio w pliku Compose.

Zwróć uwagę, aby DB_POSTGRESDB_HOST odpowiadało nazwie usługi PostgreSQL zdefiniowanej w pliku Compose. W tym przypadku należy użyć postgres, a nie localhost. Domyślne wartości to port 5432, baza n8n i schemat public. Konto określone przez DB_POSTGRESDB_USER musi mieć uprawnienia pozwalające na tworzenie i modyfikowanie schematów tabel, bo bez nich n8n nie przeprowadzi inicjalizacji bazy ani migracji.

n8n obsługuje PostgreSQL w wersjach 16, 17 i 18 (stan z lipca 2026). Obraz bazy przypnij więc do konkretnej wersji głównej, na przykład postgres:17, zamiast pobierać zawsze najnowszą. Bazy zgodne z PostgreSQL, takie jak AlloyDB, CockroachDB czy YugabyteDB, nie są wspierane. Gotowy plik Compose z PostgreSQL znajdziesz też w repozytorium n8n-hosting, w katalogu docker-compose/withPostgres.

Dane PostgreSQL zapisuj w osobnym wolumenie, na przykład postgres_data. Kopia zapasowa powinna obejmować zarówno ten wolumen, jak i n8n_data, bo w katalogu /home/node/.n8n nadal znajdują się ważne ustawienia n8n oraz klucz szyfrowania.

Jak skonfigurować webhooki i publiczny adres n8n?

Webhooki wykorzystywane przez zewnętrzne usługi wymagają, aby instancja n8n była dostępna publicznie. Adres http://localhost:5678 działa wyłącznie lokalnie, dlatego nie pozwala odbierać zapytań z internetu.

W środowisku produkcyjnym trzeba skonfigurować:

  • domenę lub subdomenę wskazującą na serwer,
  • certyfikat HTTPS,
  • publiczny adres webhooka w zmiennej N8N_WEBHOOK_URL,
  • reverse proxy przekazujące prawidłowe nagłówki.

Przykładowa konfiguracja zmiennych środowiskowych może wyglądać tak:

environment:
  - N8N_HOST=n8n.example.com
  - N8N_PORT=5678
  - N8N_PROTOCOL=https
  - N8N_WEBHOOK_URL=https://n8n.example.com/
  - N8N_PROXY_HOPS=1

n8n składa adres webhooka z N8N_PROTOCOL, N8N_HOST i N8N_PORT. Za reverse proxy dałoby to adres z wewnętrznym portem 5678, choć ruch z internetu przychodzi na port 443. Taki adres nie jest dostępny dla zewnętrznych usług, więc webhooki przestaną działać, nawet jeśli sam edytor n8n działa bez zarzutu. Dlatego za proxy ustaw N8N_WEBHOOK_URL ręcznie, z pełnym adresem https:// i ukośnikiem na końcu, jak w przykładach z dokumentacji. Zmienna N8N_PROXY_HOPS=1 informuje n8n, że działa za jednym serwerem proxy.

Proxy powinno przekazywać do kontenera następujące nagłówki:

  • X-Forwarded-For,
  • X-Forwarded-Host,
  • X-Forwarded-Proto.

Nagłówek X-Forwarded-Proto wskazuje n8n, że połączenie z użytkownikiem odbywa się przez HTTPS. X-Forwarded-Host przekazuje właściwą domenę, natomiast X-Forwarded-For zawiera adres źródłowy klienta.

Po zmianie zmiennych środowiskowych odtwórz kontener:

docker compose down
docker compose up -d

Następnie sprawdź adres wygenerowany w węźle Webhook. Powinien prowadzić do publicznej domeny, na przykład https://n8n.example.com/webhook/.... Publiczny adres webhooka nie jest tym samym co lokalny adres kontenera: wewnętrzny port 5678 służy do komunikacji n8n z reverse proxy, a zewnętrzna usługa łączy się z domeną dostępną przez HTTPS.

Jak skonfigurować tunel dla webhooków?

Tunel dla webhooków pozwala przekazywać żądania z internetu do lokalnego kontenera n8n bez kupowania domeny i stawiania reverse proxy. Opcja n8n --tunnel została usunięta w wersji n8n 2.0, dlatego dokumentacja odsyła do zewnętrznych narzędzi, takich jak:

  • ngrok,
  • localtunnel,
  • Cloudflare Tunnel.

Najprostszy wariant to szybki tunel uruchomiony na tym samym komputerze co kontener:

cloudflared tunnel --url http://localhost:5678
# albo
ngrok http 5678

Narzędzie wypisze publiczny adres HTTPS. Przypisz go do zmiennej N8N_WEBHOOK_URL, dodaj N8N_PROXY_HOPS=1 i odtwórz kontener. Wówczas zewnętrzna usługa przekaże żądanie do lokalnej instancji n8n zamiast kierować je na niedostępny adres localhost. Adres szybkiego tunelu Cloudflare zmienia się przy każdym uruchomieniu, więc po restarcie tunelu zaktualizuj też zmienną.

Takie rozwiązanie sprawdza się podczas tworzenia i testowania workflowów, ale nie jest przeznaczone do zastosowań produkcyjnych.

Jak zarządzać bezpieczeństwem serwera n8n?

Bezpieczeństwo serwera automatyzacji wymaga regularnych aktualizacji, ograniczania dostępu i stałej kontroli usług dostępnych w internecie. Administrator odpowiedzialny za self-hosting powinien zadbać o:

  • regularne aktualizacje systemu, Dockera i n8n,
  • prawidłową konfigurację firewalla,
  • ograniczenie liczby otwartych portów,
  • kontrolę dostępu do serwera oraz panelu n8n,
  • regularne kopie zapasowe danych i konfiguracji,
  • monitoring kontenera oraz dostępnych zasobów.

W środowisku produkcyjnym port 5678 nie powinien być dostępny publicznie. Kontener n8n należy skonfigurować tak, aby nasłuchiwał wyłącznie lokalnie, pod adresem 127.0.0.1:5678, a ruch z internetu przechodził przez reverse proxy z HTTPS. Publicznie wystarczy udostępnić porty 80 i 443.

Firewall powinien blokować nieużywane porty i dopuszczać wyłącznie niezbędne połączenia. Po każdej zmianie konfiguracji reverse proxy, domeny lub Dockera sprawdź ponownie reguły zapory. Zbyt szerokie uprawnienia sieciowe zwiększają ryzyko nieautoryzowanego dostępu do edytora n8n, webhooków oraz danych uwierzytelniających.

HTTPS jest w n8n wymagany nie tylko dla bezpieczeństwa. n8n domyślnie wysyła ciasteczko sesji wyłącznie przez bezpieczne połączenie (zmienna N8N_SECURE_COOKIE), więc wejście przez http://IP-serwera:5678 zatrzyma się na ekranie logowania. Zamiast wyłączać tę ochronę, postaw przed n8n reverse proxy z certyfikatem.

Szczególnej ochrony wymaga klucz N8N_ENCRYPTION_KEY, którym n8n szyfruje zapisane poświadczenia. Po ich zapisaniu klucz musi pozostać stały, a jego zmiana uniemożliwi odszyfrowanie danych. Nie przechowuj go w publicznym repozytorium i ogranicz dostęp do pliku .env.

Ustawienie N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true wymusza właściwe uprawnienia do pliku ustawień. Dostęp do katalogu /home/node/.n8n oraz wolumenu n8n_data powinien mieć wyłącznie administrator i konto używane przez n8n, bo znajdują się tam workflowy, poświadczenia, baza SQLite, logi oraz klucz szyfrowania.

Osobną warstwą ochrony są task runnery, które wykonują kod z węzła Code. Dokumentacja ostrzega, że w domyślnym trybie internal każdy, kto może edytować workflow, mógłby potencjalnie odczytać bazę danych, klucz szyfrowania, zapisane poświadczenia i zmienne środowiskowe. Na produkcji i na każdej instancji z wrażliwymi danymi uruchom runnery w trybie external (szczegóły w ostatniej sekcji).

Jak skonfigurować certyfikat SSL dla n8n?

Najprostszym sposobem na certyfikat SSL dla n8n jest oficjalna konfiguracja z Traefikiem jako reverse proxy. Traefik obsługuje ruch na portach 80 i 443, przekierowuje HTTP na HTTPS, a następnie sam pobiera i odnawia certyfikat Let’s Encrypt.

Na początku skieruj rekord A subdomeny, na przykład n8n, na adres IP serwera. Następnie w katalogu projektu (np. n8n-compose) utwórz plik .env:

DOMAIN_NAME=example.com
SUBDOMAIN=n8n
GENERIC_TIMEZONE=Europe/Warsaw
SSL_EMAIL=admin@example.com

DOMAIN_NAME i SUBDOMAIN razem wyznaczają adres instancji, w tym przykładzie https://n8n.example.com. Adres e-mail służy do rejestracji certyfikatu. W tym samym katalogu utwórz folder local-files (mkdir local-files), który n8n widzi jako /files i może w nim odczytywać oraz zapisywać pliki.

Plik compose.yaml z dokumentacji n8n wygląda tak:

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - N8N_WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${GENERIC_TIMEZONE}
      - N8N_RESTRICT_FILE_ACCESS_TO=/files
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
  traefik_data:

Uruchom stos poleceniem sudo docker compose up -d. Traefik będzie przekazywać żądania do n8n, którego kontener pozostanie dostępny tylko lokalnie pod adresem 127.0.0.1:5678, a aplikacja zacznie działać pod adresem https://n8n.example.com, wyłącznie przez HTTPS. Za reverse proxy dokumentacja konfiguracji webhooków zaleca też dopisanie w sekcji environment zmiennej N8N_PROXY_HOPS=1. W wersjach starszych niż 2.30 zamiast N8N_WEBHOOK_URL użyj WEBHOOK_URL.

HTTPS szyfruje sesje oraz webhooki, dlatego certyfikat SSL ma kluczowe znaczenie w bezpiecznym środowisku produkcyjnym. Jeśli instancja nie odpowiada, sprawdź, czy rekord DNS wskazuje właściwy adres IP i czy firewall przepuszcza połączenia na portach 80 i 443. Traefik musi też móc zapisać certyfikat w wolumenie traefik_data, żeby automatycznie go odnawiać.

Jak aktualizować n8n w Dockerze?

Przed aktualizacją n8n koniecznie wykonaj kopię zapasową wolumenu danych i zachowaj wartość zmiennej N8N_ENCRYPTION_KEY. Jeśli korzystasz z PostgreSQL, backup powinien obejmować także tę bazę.

Aby pobrać najnowszą wersję obrazu dla pojedynczego kontenera, wykonaj:

docker pull n8nio/n8n

Możesz również wskazać kanał albo konkretną wersję:

docker pull n8nio/n8n:stable
docker pull n8nio/n8n:2.44.4

Po pobraniu obrazu zatrzymaj i usuń dotychczasowy kontener:

docker stop n8n
docker rm n8n

Następnie uruchom n8n ponownie, używając tego samego wolumenu i dotychczasowych zmiennych środowiskowych:

docker run -d \
  --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/n8n:stable

Wolumen n8n_data zawiera workflowy, poświadczenia, bazę SQLite, ustawienia i klucz szyfrowania. Samo usunięcie kontenera nie spowoduje więc utraty danych.

Jeżeli używasz Docker Compose, aktualizacja sprowadza się do trzech poleceń wykonanych w katalogu z plikiem Compose:

docker compose pull
docker compose down
docker compose up -d
  • docker compose pull pobiera nowy obraz,
  • docker compose down zatrzymuje i usuwa dotychczasowe kontenery,
  • docker compose up -d uruchamia n8n ponownie z niezmienioną konfiguracją i wolumenami.

W przypadku PostgreSQL polecenia te obejmują cały stos usług.

n8n wydaje nową wersję minor prawie co tydzień. W środowisku produkcyjnym zalecany jest kanał stable, a kanał beta udostępnia nowsze, ale potencjalnie niestabilne zmiany, dlatego lepiej wykorzystywać go do testów. W październiku 2026 wersja stable to 2.44.4, a beta 2.45.0. Na serwerze produkcyjnym przypnij w pliku Compose konkretną wersję, np. image: n8nio/n8n:2.44.4, i podnoś ją świadomie. Obraz bez numeru wersji po każdym docker compose pull przeskoczy na najnowsze wydanie i przy starcie od razu przeprowadzi migrację bazy.

Po zakończeniu aktualizacji sprawdź stan usług:

docker compose ps
docker compose logs -f n8n

Otwórz także panel n8n i przetestuj kluczowe workflowy oraz webhooki. Dane pozostaną nienaruszone, dopóki zachowasz wolumen n8n_data i niezmieniony klucz N8N_ENCRYPTION_KEY.

Jak monitorować kontener n8n?

Monitoring kontenera n8n warto prowadzić w pięciu obszarach:

  • stan kontenera,
  • działanie aplikacji,
  • logi,
  • zasoby hosta,
  • certyfikat i wolumen danych.

Stan kontenera sprawdzisz poleceniami:

docker compose ps
docker inspect <kontener>
docker stats <kontener>

Pierwsze wyświetla status usług, drugie szczegółowe informacje o kontenerze, a trzecie bieżące zużycie procesora, pamięci, sieci i operacji dyskowych. W Compose kontener ma zwykle nazwę w rodzaju n8n-compose-n8n-1, a dokładną nazwę zobaczysz w wyniku docker compose ps.

Dostępność instancji n8n zweryfikujesz endpointem /healthz. Gdy aplikacja jest osiągalna, zwraca on kod HTTP 200:

curl -I https://n8n.example.com/healthz

Sam kod 200 nie oznacza jednak, że połączenie z bazą danych działa prawidłowo. Do sprawdzenia połączenia oraz migracji bazy służy endpoint /healthz/readiness:

curl -I https://n8n.example.com/healthz/readiness

Endpoint /healthz dobrze sprawdza się przy monitorowaniu dostępności usługi, natomiast /healthz/readiness pozwala ocenić gotowość n8n do obsługi workflowów i webhooków. Oba można podłączyć do systemu monitoringu albo sondy reverse proxy.

Do analizy logów kontenera użyj:

docker compose logs --tail=100 n8n
docker compose logs -f n8n

Szczególną uwagę zwracaj na błędy połączenia z PostgreSQL, nieudane migracje, problemy z webhookami, błędy uwierzytelniania oraz cykliczne restarty kontenera. Status i kod zakończenia procesu sprawdzisz poleceniem:

docker inspect -f '{{.State.Status}} {{.State.ExitCode}}' <kontener>

Monitoring powinien uwzględniać również zasoby hosta: wolne miejsce na dysku, pamięć RAM, obciążenie procesora i stan systemu plików, na którym leży wolumen n8n_data. Brak przestrzeni może uniemożliwić zapis workflowów, logów lub bazy SQLite. W przypadku PostgreSQL monitoruj także wolumen postgres_data oraz dostępność bazy.

Metryki Prometheusa udostępnia endpoint /metrics, który domyślnie jest wyłączony. Włączysz go zmienną środowiskową N8N_METRICS=true, a metryki pobierzesz pod adresem https://n8n.example.com/metrics. Endpoint działa we wszystkich edycjach self-hosted, ale nie w n8n Cloud. Udostępnij go wyłącznie systemowi monitoringu, bo ujawnia informacje operacyjne o instancji. Prometheus może gromadzić te dane, a Grafana prezentować je na dashboardach.

Regularnie weryfikuj też datę wygaśnięcia certyfikatu SSL i możliwość połączenia z publicznym adresem webhooków. Monitorowanie nie zastępuje kopii zapasowych. Alarmy warto skonfigurować dla takich sytuacji jak:

  • niedostępność /healthz,
  • brak gotowości /healthz/readiness,
  • błędy w logach,
  • restarty kontenera,
  • wysokie zużycie zasobów,
  • brak wolnego miejsca,
  • problemy z bazą danych.

Jakie zmiany w n8n 2.0 dotyczą instalacji w Dockerze?

Wersja n8n 2.0 przyniosła ważne zmiany w konfiguracji kontenera Docker, bezpieczeństwie oraz obsługiwanych bazach danych.

Task runnery, które wykonują kod z węzła Code, są teraz zawsze włączone, więc zmienna N8N_RUNNERS_ENABLED nie jest już potrzebna. Domyślnie działają w trybie internal, jako proces potomny n8n, którego dokumentacja nie zaleca na produkcji. Tryb external wymaga osobnego kontenera n8nio/runners w tej samej wersji co n8n, bo główny obraz n8nio/n8n nie zawiera już runnera dla tego trybu. Kontener n8n dostaje wtedy zmienne N8N_RUNNERS_MODE=external, N8N_RUNNERS_AUTH_TOKEN (wspólny sekret obu kontenerów) i N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0, a broker nasłuchuje na porcie 5679.

Uruchamianie Pythona w węźle Code jest możliwe wyłącznie w trybie external. Instalacja samego głównego kontenera n8n nie pozwoli wykonywać kodu Python.

W n8n 2.0 zaostrzono także domyślne zabezpieczenia:

  • węzeł Code nie ma dostępu do zmiennych środowiskowych (N8N_BLOCK_ENV_ACCESS_IN_NODE=true),
  • plik ustawień musi mieć uprawnienia 0600,
  • węzły plikowe mogą domyślnie korzystać tylko z katalogu ~/.n8n-files (N8N_RESTRICT_FILE_ACCESS_TO),
  • węzły Execute Command i Local File Trigger są wyłączone (NODES_EXCLUDE),
  • adresy zwrotne OAuth wymagają uwierzytelnienia.

Zmiany te ograniczają ryzyko odczytu sekretów, wykonywania poleceń systemowych i uzyskiwania dostępu do plików hosta z poziomu workflowów. Przy migracji starszej instalacji sprawdź workflowy wykorzystujące te funkcje, bo niektóre z nich mogą wymagać przebudowy.

Opcja --tunnel została usunięta. Do testowania webhooków z lokalnego kontenera potrzebne jest zewnętrzne rozwiązanie, na przykład ngrok, localtunnel lub Cloudflare Tunnel. Publiczny adres tunelu należy następnie ustawić w zmiennej N8N_WEBHOOK_URL.

Zmieniły się też nazwy kanałów wydań: latest to teraz stable, a next to beta. Stare tagi obrazów jeszcze działają, ale znikną w przyszłej wersji głównej, więc w plikach Compose używaj nowych nazw albo konkretnych numerów wersji.

Wersja n8n 2.0 nie obsługuje MySQL ani MariaDB jako bazy n8n. Nowa instalacja w Dockerze powinna korzystać z SQLite lub PostgreSQL. Przed aktualizacją starszego środowiska sprawdź używany typ bazy danych i wykonaj kopię zapasową.

Bartłomiej Bernat

Bartłomiej Bernat

Entuzjasta AI i autor bloga AIGuide.pl. Pomagam zrozumieć sztuczną inteligencję w prostych krokach — od narzędzi po praktyczne zastosowania.

Może Cię również zainteresować