DEV Community

Andrzej Klusiewicz
Andrzej Klusiewicz

Posted on

Jak postawić n8n na własnym serwerze — kompletny tutorial krok po kroku (self-hosted)

n8n Cloud jest wygodne, ale własny serwer daje pełną kontrolę nad danymi i brak limitów wykonań — kluczowe dla firm przetwarzających dane klientów przez AI. Poniżej kompletny, sprawdzony przepis na postawienie n8n na własnym VPS (Docker + reverse proxy + HTTPS) krok po kroku.


Z tego artykułu dowiesz się:

  • Jak przygotować serwer VPS i skonfigurować DNS
  • Jak zainstalować Dockera i docker-compose w minutę
  • Jak skonfigurować n8n z PostgreSQL jako bazą danych
  • Jak postawić nginx jako reverse proxy z HTTPS (Let's Encrypt)
  • Jak skonfigurować automatyczne kopie zapasowe i aktualizacje
  • Jak rozwiązać najczęstsze problemy przy instalacji

n8n self-hosted daje Ci pełną kontrolę: brak limitów operacji, dane zostają w Twojej infrastrukturze, możesz podłączyć wewnętrzne systemy firmy bez otwierania ich na świat. Jedynym kosztem jest serwer VPS - od ok. 6 euro miesięcznie.

Ten tutorial przeprowadzi Cię przez kompletny, produkcyjny setup na Ubuntu LTS: Docker + docker-compose, n8n z PostgreSQL, nginx jako reverse proxy, automatyczne certyfikaty HTTPS, backup i procedurę aktualizacji. Każda komenda jest gotowa do skopiowania.

Wymagania - co potrzebujesz przed startem

Serwer VPS

Minimalne wymagania: 2 GB RAM, 20 GB SSD, Ubuntu LTS. Przy kilku aktywnych workflowach i integracji z AI zalecamy 4 GB RAM.

Dostawca Produkt RAM / CPU / Dysk Cena/mies. Uwagi
Hetzner CX22 4 GB / 2 vCPU / 40 GB ~6 EUR Polecany - świetny stosunek ceny do wydajności
Contabo VPS S 8 GB / 4 vCPU / 50 GB ~7 EUR Dużo zasobów za mało pieniędzy
OVHcloud VPS Starter 2 GB / 1 vCPU / 20 GB ~4 EUR Minimum - tylko dla małych instalacji
DigitalOcean Droplet Basic 2 GB / 1 vCPU / 50 GB ~12 USD Dobry panel i dokumentacja

Domena

Potrzebujesz domeny (lub subdomeny), np. n8n.twoja-firma.pl. Certyfikat HTTPS od Let's Encrypt wymaga publicznej domeny wskazującej na Twój serwer.

Dostęp SSH

Wymagany dostęp root przez SSH. Potrzebujesz dostępu do serwera przez SSH jako root (lub użytkownik z sudo). Wszystkie komendy poniżej zakładają, że jesteś zalogowany jako root.

Wskazówka: Jeśli dopiero tworzysz VPS, wybierz Ubuntu LTS przy zamówieniu. Ustaw swój klucz SSH jeszcze w panelu dostawcy - to bezpieczniejsze niż logowanie hasłem.

Krok 1: Konfiguracja DNS

KROK 1 Przed instalacją czegokolwiek na serwerze skonfiguruj DNS. Let's Encrypt wymaga, żeby domena wskazywała na serwer przed wystawieniem certyfikatu. Propagacja DNS może trwać od kilku minut do kilku godzin - zrób to teraz.

Wejdź do panelu swojego rejestratora domeny (nazwa.pl, OVH, CloudFlare itp.) i dodaj rekord:

Kopiuj

Typ rekordu:  A
Nazwa:        n8n          (lub inna subdomena, np. automatyzacje)
Wartość:      1.2.3.4      (wpisz IP swojego serwera)
TTL:          3600         (lub zostaw domyślne)
Enter fullscreen mode Exit fullscreen mode

Sprawdź propagację DNS (możesz uruchomić to z dowolnego komputera):

Kopiuj

nslookup n8n.twoja-domena.pl
# Powinno zwrócić IP Twojego serwera
Enter fullscreen mode Exit fullscreen mode

Możesz też sprawdzić propagację DNS na stronie dnschecker.org - wpisz subdomenę i wybierz typ rekordu A.

Krok 2: Podstawowe zabezpieczenie serwera

KROK 2 Zanim zainstalujemy n8n, zabezpiecz serwer. To zajmie 5 minut i zapobiegnie większości ataków botów.

Aktualizacja systemu

Kopiuj

apt-get update && apt-get upgrade -y
Enter fullscreen mode Exit fullscreen mode

Firewall - zezwól tylko na SSH, HTTP i HTTPS

Kopiuj

# Instalacja UFW (jeśli nie ma)
apt-get install -y ufw

# Domyślnie blokuj wszystko przychodzące
ufw default deny incoming
ufw default allow outgoing

# Zezwól na SSH (ważne - inaczej zablokujesz się!)
ufw allow 22/tcp

# Zezwól na HTTP i HTTPS
ufw allow 80/tcp
ufw allow 443/tcp

# Włącz firewall
ufw enable

# Sprawdź status
ufw status verbose
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik:

Kopiuj

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
Enter fullscreen mode Exit fullscreen mode

Uwaga: Port 5678 (n8n) nie powinien być otwarty bezpośrednio. Do n8n trafia się przez nginx na porcie 443 (HTTPS). nginx komunikuje się z n8n wewnętrznie przez localhost:5678.

Zabezpieczenie SSH (opcjonalne, ale zalecane)

Jeśli logujesz się kluczem SSH (zalecane!), możesz wyłączyć logowanie hasłem:

Kopiuj

# Edytuj konfigurację SSH
nano /etc/ssh/sshd_config

# Znajdź i zmień te linie:
# PasswordAuthentication no
# PermitRootLogin prohibit-password

# Zrestartuj SSH
systemctl restart sshd
Enter fullscreen mode Exit fullscreen mode

Krok 3: Instalacja Dockera i Docker Compose

KROK 3 Używamy oficjalnego skryptu instalacyjnego Docker - to najszybsza i najwygodniejsza metoda na Ubuntu.

Kopiuj

# Upewnij się, że curl jest zainstalowany (na Ubuntu zwykle już jest)
apt-get install -y curl

# Pobierz i uruchom oficjalny skrypt instalacyjny Docker
curl -fsSL https://get.docker.com | sh

# Uruchom Docker i włącz autostart przy starcie systemu
systemctl enable --now docker

# Sprawdź wersję Dockera
docker --version

# Sprawdź wersję Docker Compose (wbudowany w nowe wersje Dockera)
docker compose version
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik:

Kopiuj

Docker version 29.0.3, build 4f9b861
Docker Compose version v2.34.0
Enter fullscreen mode Exit fullscreen mode

Docker Compose v2 (wbudowany) używa komendy docker compose (bez myślnika). Starszy Docker Compose v1 (osobny pakiet) używał docker-compose. W tym tutorialu używamy nowej wersji.

Krok 4: Struktura katalogów i plik .env

KROK 4 Trzymamy wszystkie pliki n8n w jednym katalogu. Hasła i poufne dane trafiają do pliku .env - dzięki temu nie ma ich bezpośrednio w docker-compose.yml.

Dlaczego PostgreSQL, skoro n8n domyślnie używa SQLite?

n8n musi gdzieś przechowywać swój stan: definicje workflowów, zapisane credentials (hasła do zewnętrznych serwisów), historię wykonań oraz harmonogramy. Wszystko to trafia do bazy danych - bez niej n8n nie uruchomi się w ogóle.

Domyślnie n8n zapisuje te dane do pliku SQLite - co jest w porządku na lokalnym komputerze lub przy kilku testowych workflowach. Na produkcyjnym serwerze SQLite szybko staje się wąskim gardłem: obsługuje tylko jeden zapis naraz, więc przy równoległych wykonaniach workflowów zaczyna kolejkować operacje, a przy większym obciążeniu - gubić je lub crashować.

PostgreSQL nie ma tego problemu. Obsługuje wiele równoczesnych połączeń, sprawnie zarządza blokadami i pozwala na niezawodny backup przez pg_dump. To dlatego n8n Cloud sam z siebie działa na PostgreSQL - i to samo polecamy dla każdego setupa produkcyjnego.

W poniższym .env zobaczysz zmienne POSTGRES_* - to właśnie konfiguracja tej bazy.

Kopiuj

# Utwórz katalog
mkdir -p /opt/n8n

# Przejdź do katalogu
cd /opt/n8n
Enter fullscreen mode Exit fullscreen mode

Utwórz plik .env z konfiguracją (zmień wszystkie wartości na własne!):

Kopiuj

nano /opt/n8n/.env
Enter fullscreen mode Exit fullscreen mode

Wklej poniższą zawartość i dostosuj zmienne:

Kopiuj

# ===================================================
# KONFIGURACJA N8N - dostosuj wszystkie wartości!
# ===================================================

# --- Twoja domena ---
N8N_HOST=n8n.twoja-domena.pl
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.twoja-domena.pl

# --- Baza danych PostgreSQL ---
POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=TutajWpiszMocneHaslo123!

# --- Strefa czasowa ---
GENERIC_TIMEZONE=Europe/Warsaw
TZ=Europe/Warsaw

# --- Szyfrowanie danych (wygeneruj losowy ciąg!) ---
# Możesz wygenerować przez: openssl rand -hex 32
N8N_ENCRYPTION_KEY=zmien_na_losowy_64_znakowy_ciag

# --- Opcjonalne: własne emaile powiadomień ---
# N8N_EMAIL_MODE=smtp
# N8N_SMTP_HOST=smtp.gmail.com
# N8N_SMTP_PORT=587
# N8N_SMTP_USER=twoj@email.pl
# N8N_SMTP_PASS=haslo-do-emaila
# N8N_SMTP_SENDER=twoj@email.pl
Enter fullscreen mode Exit fullscreen mode

Wygeneruj bezpieczny klucz szyfrowania:

Kopiuj

openssl rand -hex 32
# Skopiuj wynik i wklej jako wartość N8N_ENCRYPTION_KEY w pliku .env
Enter fullscreen mode Exit fullscreen mode

Ważne: Wartość N8N_ENCRYPTION_KEY jest używana do szyfrowania credentials (haseł do zewnętrznych serwisów). Jeśli ją zmienisz po zapisaniu pierwszych credentials, stracisz dostęp do wszystkich zapisanych haseł. Zapisz ją w bezpiecznym miejscu!

Krok 5: Plik docker-compose.yml

KROK 5 Plik docker-compose.yml definiuje dwa kontenery: PostgreSQL (baza danych) i n8n. PostgreSQL jest preferowany nad domyślnym SQLite - jest szybszy i bezpieczniejszy przy dużej liczbie wykonań.

Kopiuj

nano /opt/n8n/docker-compose.yml
Enter fullscreen mode Exit fullscreen mode

Wklej poniższy plik konfiguracyjny:

Kopiuj

services:

  # ─────────────────────────────────────────────
  # Baza danych PostgreSQL
  # ─────────────────────────────────────────────
  postgres:
    image: postgres:16-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 10
      start_period: 30s

  # ─────────────────────────────────────────────
  # n8n - główna aplikacja
  # ─────────────────────────────────────────────
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    container_name: n8n-app
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"   # port wystawiony tylko lokalnie (nginx przekieruje)
    environment:
      # Baza danych
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
      - DB_POSTGRESDB_USER=${POSTGRES_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
      # Konfiguracja hosta i protokołu
      - N8N_HOST=${N8N_HOST}
      - N8N_PROTOCOL=${N8N_PROTOCOL}
      - WEBHOOK_URL=${WEBHOOK_URL}
      # Szyfrowanie i strefa czasowa
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - TZ=${TZ}
      # Optymalizacje produkcyjne
      - N8N_LOG_LEVEL=warn
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=336    # 14 dni historii wykonań
      - N8N_METRICS=true
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

# ─────────────────────────────────────────────
# Wolumeny (dane persystowane)
# ─────────────────────────────────────────────
volumes:
  postgres_data:
  n8n_data:
Enter fullscreen mode Exit fullscreen mode

Kilka ważnych szczegółów tej konfiguracji:

  • 127.0.0.1:5678:5678 - port 5678 jest wystawiony tylko na localhost, nie na zewnątrz. To kluczowe dla bezpieczeństwa - dostęp do n8n odbywa się wyłącznie przez nginx.
  • restart: unless-stopped - kontener automatycznie restartuje się po restarcie serwera, ale nie przy ręcznym zatrzymaniu.
  • EXECUTIONS_DATA_PRUNE=true - automatyczne czyszczenie starych wykonań. Bez tego baza rośnie bez ograniczeń.
  • service_healthy - n8n czeka na zdrowy PostgreSQL przed startem. Eliminuje błąd "could not connect to database".

Krok 6: nginx jako reverse proxy

KROK 6 nginx odbiera połączenia na portach 80 (HTTP) i 443 (HTTPS) i przekazuje je do n8n. Obsługuje też WebSockety - są wymagane do komunikacji n8n w czasie rzeczywistym (np. podgląd wykonań na żywo).

Kopiuj

# Instalacja nginx
apt-get install -y nginx

# Sprawdź status
systemctl status nginx
Enter fullscreen mode Exit fullscreen mode

Utwórz konfigurację wirtualnego hosta dla n8n:

Kopiuj

nano /etc/nginx/sites-available/n8n
Enter fullscreen mode Exit fullscreen mode

Na początek wklej tymczasową konfigurację - tylko HTTP. Pozwoli ona nginx wystartować i obsłużyć weryfikację Let's Encrypt, zanim wystawimy certyfikat (zastąp n8n.twoja-domena.pl swoją domeną):

Kopiuj

# Konfiguracja wstępna (tylko HTTP) - pozwala nginx wystartować
# i obsłużyć weryfikację Let's Encrypt, zanim istnieje certyfikat.
server {
    listen 80;
    listen [::]:80;
    server_name n8n.twoja-domena.pl;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }
}
Enter fullscreen mode Exit fullscreen mode

Aktywuj konfigurację i sprawdź poprawność:

Kopiuj

# Aktywuj przez symlink
ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/

# Usuń domyślną stronę nginx (opcjonalnie)
rm -f /etc/nginx/sites-enabled/default

# Sprawdź składnię konfiguracji
nginx -t
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik:

Kopiuj

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Enter fullscreen mode Exit fullscreen mode

Krok 7: Certyfikat HTTPS - Let's Encrypt

KROK 7 Certbot automatycznie pobierze darmowy certyfikat SSL od Let's Encrypt i skonfiguruje jego automatyczne odnawianie.

Kopiuj

# Instalacja certbota z wtyczką nginx
apt-get install -y certbot python3-certbot-nginx

# Przeładuj nginx (musi działać na porcie 80 dla weryfikacji)
systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Pobierz certyfikat (zastąp domenę i email własnymi):

Kopiuj

certbot certonly --nginx \
  --non-interactive \
  --agree-tos \
  --email admin@twoja-domena.pl \
  -d n8n.twoja-domena.pl
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik po sukcesie:

Kopiuj

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/n8n.twoja-domena.pl/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/n8n.twoja-domena.pl/privkey.pem
This certificate expires on 2026-09-08.
These files will be updated when the certificate renews.
Enter fullscreen mode Exit fullscreen mode

Teraz, gdy certyfikat już istnieje, rozbuduj konfigurację nginx o pełny blok HTTPS - przekierowanie z HTTP na HTTPS, TLS, nagłówki bezpieczeństwa oraz przekazanie ruchu do n8n z obsługą WebSocketów. Otwórz plik ponownie:

Kopiuj

nano /etc/nginx/sites-available/n8n
Enter fullscreen mode Exit fullscreen mode

Zastąp całą zawartość pełną konfiguracją (ponownie podstaw swoją domenę):

Kopiuj

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# ─── HTTP --> przekieruj na HTTPS ───────────────────────────────────────
server {
    listen 80;
    listen [::]:80;
    server_name n8n.twoja-domena.pl;

    location /.well-known/acme-challenge/ {
        root /var/www/html;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

# ─── HTTPS ────────────────────────────────────────────────────────────
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name n8n.twoja-domena.pl;

    # Certyfikaty (wypełni certbot)
    ssl_certificate     /etc/letsencrypt/live/n8n.twoja-domena.pl/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.twoja-domena.pl/privkey.pem;

    # Bezpieczeństwo TLS
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers off;

    # Nagłówki bezpieczeństwa
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # Przekazanie do n8n
    location / {
        proxy_pass         http://127.0.0.1:5678;
        proxy_http_version 1.1;

        # WebSocket support (wymagany przez n8n)
        proxy_set_header   Upgrade           $http_upgrade;
        proxy_set_header   Connection        $connection_upgrade;

        # Nagłówki hosta i IP
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;

        # Timeouty i rozmiar
        proxy_read_timeout   86400s;    # 24h dla długich webhooków
        proxy_send_timeout   86400s;
        client_max_body_size 100m;      # max rozmiar pliku do uploadu
        proxy_buffering      off;       # wymagane przy SSE/webhookach
    }
}
Enter fullscreen mode Exit fullscreen mode

Sprawdź konfigurację i przeładuj nginx - teraz załaduje też blok HTTPS:

Kopiuj

nginx -t && systemctl reload nginx
Enter fullscreen mode Exit fullscreen mode

Sprawdź automatyczne odnawianie certyfikatu:

Kopiuj

# Symulacja odnawiania (dry-run) - sprawdza czy wszystko działa
certbot renew --dry-run
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik (skrócony):

Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/n8n.twoja-domena.pl.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Account registered.
Simulating renewal of an existing certificate for n8n.twoja-domena.pl

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations, all simulated renewals succeeded:
  /etc/letsencrypt/live/n8n.twoja-domena.pl/fullchain.pem (success)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Enter fullscreen mode Exit fullscreen mode

Kluczowe słowo to Congratulations, all simulated renewals succeeded. Jeśli widzisz błąd, sprawdź czy port 80 jest otwarty i czy nginx działa poprawnie.

Kopiuj

# Sprawdź timer odnowień (certbot dodaje go automatycznie)
systemctl status certbot.timer
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik:

● certbot.timer - Run certbot twice daily
     Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
     Active: active (waiting) since ...
    Trigger: Wed 2024-01-15 12:00:00 UTC; 3h 22min left
   Triggers: ● certbot.service
Enter fullscreen mode Exit fullscreen mode

Certbot automatycznie dodaje systemd timer do odnawiania certyfikatu dwa razy dziennie. Certyfikat jest odnawiany gdy zostaje mniej niż 30 dni ważności - w praktyce zawsze z dużym wyprzedzeniem. Nie musisz nic robić ręcznie. Upewnij się tylko, że timer ma status active (waiting).

Krok 8: Uruchomienie n8n

KROK 8 Masz wszystko skonfigurowane. Czas uruchomić n8n.

Kopiuj

# Przejdź do katalogu n8n
cd /opt/n8n

# Uruchom kontenery w tle (-d = detached)
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Pierwsze uruchomienie pobierze obrazy Docker (~500 MB), co może potrwać 2-5 minut. Obserwuj postęp:

Kopiuj

# Pobranie obrazów - widoczne przy pierwszym uruchomieniu:
# [+] Pulling 11/11
#  ✔ postgres Pulled   45.2s
#  ✔ n8n Pulled        87.3s
Enter fullscreen mode Exit fullscreen mode

Sprawdź status kontenerów:

Kopiuj

docker compose ps
Enter fullscreen mode Exit fullscreen mode

Oczekiwany wynik (obydwa kontenery muszą być Up, postgres healthy):

Kopiuj

NAME           IMAGE                          STATUS
n8n-postgres   postgres:16-alpine             Up (healthy)
n8n-app        docker.n8n.io/n8nio/n8n:latest Up
Enter fullscreen mode Exit fullscreen mode

Sprawdź logi n8n (w pierwszych sekundach zobaczysz migracje bazy danych):

Kopiuj

docker compose logs n8n --tail=30
Enter fullscreen mode Exit fullscreen mode

Szukaj linii:

Kopiuj

# To oznacza że n8n działa poprawnie:
Editor is now accessible via:
https://n8n.twoja-domena.pl
Enter fullscreen mode Exit fullscreen mode

Zweryfikuj że n8n odpowiada lokalnie:

Kopiuj

curl -s -o /dev/null -w "HTTP Status: %{http_code}\n" http://localhost:5678/healthz
# Oczekiwany wynik: HTTP Status: 200
Enter fullscreen mode Exit fullscreen mode

Krok 9: Pierwsze logowanie i konfiguracja konta

KROK 9 Otwórz w przeglądarce adres swojej subdomeny, np. https://n8n.twoja-domena.pl. Zobaczysz ekran zakładania konta administratora - to pierwsze i jedyne konto, które jest właścicielem całej instalacji.

Ekran pierwszego uruchomienia n8n - formularz rejestracji konta administratora z polami: email, imię, nazwisko, hasło

Pierwsze uruchomienie n8n - ekran zakładania konta właściciela (owner account). Podaj email i hasło, których będziesz używać do logowania.

Wypełnij formularz:

  • First name / Last name - Twoje imię i nazwisko
  • Email - adres email (używany do logowania)
  • Password - minimum 8 znaków, użyj silnego hasła (możesz wygenerować je w generatorze haseł Avast - bezpłatny, działa w przeglądarce bez rejestracji)

Po kliknięciu Next pojawi się ekran onboardingowy z pytaniami o Twój profil. Możesz go pominąć klikając Get started lub wypełnić - n8n dostosuje interfejs do Twojej roli.

Panel główny n8n po pierwszym zalogowaniu - widok pustej listy workflowów z przyciskiem Create workflow

Po zakończeniu onboardingu trafiasz do panelu głównego. Lista workflowów jest pusta - czas tworzyć pierwsze automatyzacje.

Krok 10: Aktywacja licencji Community Edition

KROK 10 n8n self-hosted działa bez licencji, ale warto aktywować darmową licencję Community Edition - odblokuje dodatkowe funkcje (m.in. historia wykonań, debugger, custom variables).

Wejdź w Settings --> Usage and plan i kliknij Get started for free. Zostaniesz poproszony o adres email - po podaniu go otrzymasz klucz licencyjny emailem.

Co daje Community Edition? Pełna historia wykonań, możliwość debugowania, zmienne środowiskowe (Variables), external secrets, community nodes. Wszystko bezpłatnie - wystarczy zarejestrować się swoim emailem.

Krok 11: Zaawansowana konfiguracja n8n

KROK 11 Poniżej najważniejsze zmienne środowiskowe, które warto ustawić w pliku .env. Po każdej zmianie uruchom docker compose up -d, żeby zastosować zmiany.

Bezpieczeństwo - klucz JWT i telemetria

Warto ustawić sekret do podpisywania tokenów JWT oraz wyłączyć telemetrię. Zanim wkleisz konfigurację, krótko co oznaczają te pojęcia:

JWT (JSON Web Token) to podpisany cyfrowo token, który n8n wystawia po zalogowaniu i którym rozpoznaje Cię przy kolejnych żądaniach - dzięki temu nie musisz wpisywać hasła za każdym razem. N8N_USER_MANAGEMENT_JWT_SECRET to tajny klucz, którym n8n podpisuje te tokeny. Ustawienie go na stałą, losową wartość sprawia, że sesje przeżywają restart kontenera; bez tego n8n losuje nowy sekret przy każdym starcie i wylogowuje wszystkich użytkowników.

Telemetria (zbieranie danych diagnostycznych) to anonimowe statystyki użycia, które n8n domyślnie wysyła do swoich twórców - na przykład które typy węzłów są używane, oraz sprawdzanie dostępności nowych wersji. Na własnym serwerze zwykle warto ją wyłączyć: ogranicza to ruch wychodzący i zostawia wszystkie dane wyłącznie u Ciebie.

Kopiuj

# Dodaj do pliku .env:

# Sekret do podpisywania tokenów JWT (wymagany przy włączonej autoryzacji)
N8N_USER_MANAGEMENT_JWT_SECRET=zmien_na_losowy_ciag_min_16_znakow

# Wyłącz diagnostykę i telemetrię (opcjonalne)
N8N_DIAGNOSTICS_ENABLED=false
N8N_VERSION_NOTIFICATIONS_ENABLED=false
Enter fullscreen mode Exit fullscreen mode

Uwaga: N8N_USER_MANAGEMENT_JWT_SECRET służy do podpisywania sesji JWT - nie steruje polityką zaproszeń. Tryb „tylko zaproszenia" włącza się w UI n8n: Settings → Users → Invite users (dostępne gdy skonfigurowane jest SMTP).

Limity wykonań i wydajność

Kopiuj

# Dodaj do sekcji environment w docker-compose.yml:

# Maksymalna liczba równoczesnych wykonań
- EXECUTIONS_PROCESS=main
- N8N_DEFAULT_BINARY_DATA_MODE=filesystem

# Przechowywanie plików tymczasowych (zamiast pamięci RAM)
- N8N_BINARY_DATA_STORAGE_PATH=/home/node/.n8n/binaryData

# Ograniczenie pamięci dla Node.js (dla serwera 2 GB RAM)
- NODE_OPTIONS=--max-old-space-size=512
Enter fullscreen mode Exit fullscreen mode

Powiadomienia email (opcjonalne)

Kopiuj

# Konfiguracja SMTP dla powiadomień o błędach:
N8N_EMAIL_MODE=smtp
N8N_SMTP_HOST=smtp.gmail.com
N8N_SMTP_PORT=587
N8N_SMTP_USER=twoj@gmail.com
N8N_SMTP_PASS=haslo-aplikacji-gmail
N8N_SMTP_SENDER=twoj@gmail.com

# Gdy SMTP jest skonfigurowane, n8n automatycznie wysyła alerty o błędach systemowych.
# Powiadomienia o błędach workflowów konfiguruje się przez n8n UI: Settings → Error Workflow.
Enter fullscreen mode Exit fullscreen mode

Po każdej zmianie w .env lub docker-compose.yml przeładuj kontenery:

Kopiuj

cd /opt/n8n
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Krok 12: Automatyczne kopie zapasowe

KROK 12 Dane n8n są w dwóch miejscach: baza PostgreSQL (workflow, credentials, historia wykonań) i wolumin n8n_data (ustawienia, pliki). Backup obu jest kluczowy.

Skrypt backup

Kopiuj

nano /opt/n8n/backup.sh
Enter fullscreen mode Exit fullscreen mode

Kopiuj

#!/bin/bash
# ============================================================
# Backup n8n - baza danych PostgreSQL + wolumeny
# ============================================================
set -euo pipefail

BACKUP_DIR="/opt/n8n/backups"
DATE=$(date +%Y%m%d_%H%M%S)
RETAIN_DAYS=14    # ile dni trzymać backupy

mkdir -p "$BACKUP_DIR"

echo "[$(date)] Backup n8n start..."

# 1. Backup bazy PostgreSQL
docker exec n8n-postgres \
  pg_dump -U n8n -d n8n --format=custom \
  > "$BACKUP_DIR/postgres_${DATE}.dump"

# 2. Backup wolumenu n8n (credentials, settings)
docker run --rm \
  -v n8n_n8n_data:/source:ro \
  -v "$BACKUP_DIR":/backup \
  alpine \
  tar czf "/backup/n8n_data_${DATE}.tar.gz" -C /source .

# 3. Usuń stare backupy
find "$BACKUP_DIR" -name "*.dump" -mtime +${RETAIN_DAYS} -delete
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +${RETAIN_DAYS} -delete

echo "[$(date)] Backup gotowy: postgres_${DATE}.dump + n8n_data_${DATE}.tar.gz"
ls -lh "$BACKUP_DIR" | tail -6
Enter fullscreen mode Exit fullscreen mode

Kopiuj

# Nadaj uprawnienia wykonania
chmod +x /opt/n8n/backup.sh

# Przetestuj ręcznie
/opt/n8n/backup.sh
Enter fullscreen mode Exit fullscreen mode

Automatyczny cron - backup każdej nocy o 3:00

Kopiuj

crontab -e
Enter fullscreen mode Exit fullscreen mode

Dodaj linię:

Kopiuj

0 3 * * * /opt/n8n/backup.sh >> /var/log/n8n-backup.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Przywracanie z backupu

Kopiuj

# Przywróć bazę PostgreSQL z pliku .dump
docker exec -i n8n-postgres \
  pg_restore -U n8n -d n8n --clean --if-exists \
  < /opt/n8n/backups/postgres_YYYYMMDD_HHMMSS.dump

# Przywróć wolumin n8n_data
docker run --rm \
  -v n8n_n8n_data:/target \
  -v /opt/n8n/backups:/backup \
  alpine \
  tar xzf /backup/n8n_data_YYYYMMDD_HHMMSS.tar.gz -C /target

# Zrestartuj n8n po przywróceniu
cd /opt/n8n && docker compose restart n8n
Enter fullscreen mode Exit fullscreen mode

Backup na tym samym serwerze co dane to proszenie się o poważne kłopoty. Jeśli serwer padnie, zostanie skasowany lub zhackowany - tracisz dane i backup jednocześnie. Skrypt powyżej to tylko pierwszy krok. Koniecznie skonfiguruj kopiowanie backupów na zewnętrzny serwer lub do chmury: S3, Backblaze B2, rclone na inny VPS. Dopiero wtedy masz prawdziwy backup.

Krok 13: Aktualizacja n8n

KROK 13 n8n jest aktywnie rozwijane - nowe wersje wychodzą co 1-2 tygodnie. Aktualizacja jest prosta, ale zawsze rób backup przed aktualizacją.

Kopiuj

cd /opt/n8n

# Krok 1: Backup przed aktualizacją
/opt/n8n/backup.sh

# Krok 2: Pobierz nowe obrazy
docker compose pull

# Krok 3: Zrestartuj kontenery z nowymi obrazami
docker compose up -d

# Krok 4: Sprawdź logi (migracje bazy mogą chwilę trwać)
docker compose logs n8n --tail=20 -f

# Krok 5: Sprawdź wersję
docker exec n8n-app n8n --version
Enter fullscreen mode Exit fullscreen mode

n8n automatycznie migruje schemat bazy danych przy aktualizacji. W logach zobaczysz wpisy o migracji - to normalne, poczekaj na zakończenie.

Sprawdzanie dostępnych wersji

Kopiuj

# Sprawdź aktualnie uruchomioną wersję
docker exec n8n-app n8n --version

# Sprawdź najnowszą dostępną wersję na Docker Hub
curl -s "https://registry.hub.docker.com/v2/repositories/n8nio/n8n/tags?page_size=5" \
  | python3 -c "import sys,json; [print(t['name']) for t in json.load(sys.stdin)['results'][:5]]"
Enter fullscreen mode Exit fullscreen mode

Krok 14: Monitoring i healthcheck

KROK 14 Skonfiguruj prosty monitoring, żeby wiedzieć od razu gdy n8n przestanie działać.

Sprawdzenie statusu jedną komendą

Kopiuj

# Szybki przegląd stanu całej instalacji
cd /opt/n8n
echo "=== Kontenery ==="
docker compose ps
echo ""
echo "=== Health n8n ==="
curl -s http://localhost:5678/healthz && echo " ✓ OK"
echo ""
echo "=== Użycie zasobów ==="
docker stats --no-stream n8n-app n8n-postgres
echo ""
echo "=== Rozmiar danych ==="
du -sh /var/lib/docker/volumes/n8n_n8n_data/_data 2>/dev/null
du -sh /var/lib/docker/volumes/n8n_postgres_data/_data 2>/dev/null
Enter fullscreen mode Exit fullscreen mode

Prosty skrypt alertów (ping co minutę)

Kopiuj

nano /opt/n8n/healthcheck.sh
Enter fullscreen mode Exit fullscreen mode

Kopiuj

#!/bin/bash
# Prosty healthcheck - restartuje n8n jeśli nie odpowiada
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5678/healthz)

if [ "$STATUS" != "200" ]; then
    echo "[$(date)] n8n nie odpowiada (status: $STATUS). Restartuję..."
    cd /opt/n8n && docker compose restart n8n
    echo "[$(date)] Restart wykonany."
fi
Enter fullscreen mode Exit fullscreen mode

Kopiuj

chmod +x /opt/n8n/healthcheck.sh

# Dodaj do cron - sprawdzaj co 5 minut
crontab -e
# Dodaj: */5 * * * * /opt/n8n/healthcheck.sh >> /var/log/n8n-health.log 2>&1
Enter fullscreen mode Exit fullscreen mode

Lepszy monitoring: Rozważ UptimeRobot (bezpłatny plan sprawdza co 5 minut) lub Better Stack - podaj adres https://n8n.twoja-domena.pl/healthz i dostaniesz powiadomienie emailem gdy serwer będzie niedostępny.

Troubleshooting - rozwiązywanie problemów

n8n nie startuje - błąd połączenia z bazą

Kopiuj

# Sprawdź logi n8n
docker compose logs n8n --tail=50

# Sprawdź czy PostgreSQL jest healthy
docker compose ps

# Jeśli postgres nie jest 'healthy', sprawdź jego logi
docker compose logs postgres --tail=30

# Sprawdź czy hasło w .env jest identyczne dla obu kontenerów
grep POSTGRES /opt/n8n/.env
Enter fullscreen mode Exit fullscreen mode

Najczęstsza przyczyna: różne hasła w zmiennych POSTGRES_PASSWORD (dla kontenera postgres) i DB_POSTGRESDB_PASSWORD (dla n8n). Muszą być identyczne.

Błąd certyfikatu / nginx nie startuje

Kopiuj

# Sprawdź logi nginx
journalctl -u nginx --since "5 minutes ago"

# Sprawdź czy certyfikat istnieje
ls -la /etc/letsencrypt/live/n8n.twoja-domena.pl/

# Sprawdź składnię konfiguracji nginx
nginx -t

# Jeśli certbot nie mógł wystawić certyfikatu - sprawdź DNS
nslookup n8n.twoja-domena.pl
# Musi zwrócić IP Twojego serwera
Enter fullscreen mode Exit fullscreen mode

Webhooki nie działają

Kopiuj

# Sprawdź wartość WEBHOOK_URL w .env
grep WEBHOOK_URL /opt/n8n/.env
# Musi być: WEBHOOK_URL=https://n8n.twoja-domena.pl

# Zrestartuj n8n po zmianie
cd /opt/n8n && docker compose up -d
Enter fullscreen mode Exit fullscreen mode

n8n używa za dużo pamięci

Kopiuj

# Sprawdź bieżące zużycie
docker stats n8n-app --no-stream

# Ogranicz pamięć dla Node.js (dodaj do .env)
NODE_OPTIONS=--max-old-space-size=512

# Włącz automatyczne czyszczenie starych wykonań
EXECUTIONS_DATA_PRUNE=true
EXECUTIONS_DATA_MAX_AGE=168   # 7 dni

# Zastosuj zmiany
cd /opt/n8n && docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Przydatne komendy do debugowania

Kopiuj

# Wejdź do kontenera n8n (bash)
docker exec -it n8n-app sh

# Wejdź do PostgreSQL
docker exec -it n8n-postgres psql -U n8n -d n8n

# Wylistuj tabele w bazie n8n
docker exec -it n8n-postgres psql -U n8n -d n8n -c "\dt"

# Sprawdź rozmiar bazy
docker exec -it n8n-postgres psql -U n8n -d n8n \
  -c "SELECT pg_size_pretty(pg_database_size('n8n'));"

# Wyczyść stare wykonania ręcznie
docker exec -it n8n-postgres psql -U n8n -d n8n \
  -c "DELETE FROM execution_entity WHERE \"stoppedAt\" < NOW() - INTERVAL '30 days';"
Enter fullscreen mode Exit fullscreen mode

Podsumowanie

Masz teraz w pełni działający n8n na własnym serwerze:

  • Serwer Ubuntu LTS z firewallem UFW
  • Docker + Docker Compose
  • n8n z PostgreSQL jako bazą danych
  • nginx jako reverse proxy z obsługą WebSocket
  • Certyfikat HTTPS (Let's Encrypt) z automatycznym odnowieniem
  • Automatyczne backupy co noc z 14-dniową retencją
  • Prosta procedura aktualizacji
  • Healthcheck co 5 minut z automatycznym restartem

Szkolenie n8n + AI: sztuczna inteligencja w automatyzacji firmy - termin gwarantowany

Chcesz budować automatyzacje n8n z AI pod okiem eksperta?

Szkolenie n8n + AI: sztuczna inteligencja w automatyzacji firmy - 2 dni warsztatów praktycznych, terminy gwarantowane, ocena uczestników 4.96/5.

Sprawdź terminy i zapisz się

Top comments (0)