Blog JSystems - uwalniamy wiedzę!

Szukaj

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.

DostawcaProduktRAM / CPU / DyskCena/mies.Uwagi
HetznerCX224 GB / 2 vCPU / 40 GB~6 EURPolecany - świetny stosunek ceny do wydajności
ContaboVPS S8 GB / 4 vCPU / 50 GB~7 EURDużo zasobów za mało pieniędzy
OVHcloudVPS Starter2 GB / 1 vCPU / 20 GB~4 EURMinimum - tylko dla małych instalacji
DigitalOceanDroplet Basic2 GB / 1 vCPU / 50 GB~12 USDDobry 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:

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)

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

nslookup n8n.twoja-domena.pl
# Powinno zwrócić IP Twojego serwera
💡 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

apt-get update && apt-get upgrade -y

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

# 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

Oczekiwany wynik:

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere
⚠️ 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:

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

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

# Zrestartuj SSH
systemctl restart sshd

Krok 3: Instalacja Dockera i Docker Compose

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

# 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

Oczekiwany wynik:

Docker version 29.0.3, build 4f9b861
Docker Compose version v2.34.0
n8n dashboard po zalogowaniu - widok interfejsu z zakładkami Workflows, Credentials, Executions
Tak wygląda n8n po poprawnej instalacji i pierwszym zalogowaniu - panel główny z listą workflowów.
💡 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.
# Utwórz katalog
mkdir -p /opt/n8n

# Przejdź do katalogu
cd /opt/n8n

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

nano /opt/n8n/.env

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

# ===================================================
# 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 24
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

Wygeneruj bezpieczny klucz szyfrowania:

openssl rand -hex 24
# Skopiuj wynik i wklej jako wartość N8N_ENCRYPTION_KEY w pliku .env
⚠️ 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ń.

nano /opt/n8n/docker-compose.yml

Wklej poniższy plik konfiguracyjny:

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:

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).

# Instalacja nginx
apt-get install -y nginx

# Sprawdź status
systemctl status nginx

Utwórz konfigurację wirtualnego hosta dla n8n:

nano /etc/nginx/sites-available/n8n

Wklej poniższą konfigurację (zastąp n8n.twoja-domena.pl swoją domeną):

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;
    listen [::]:443 ssl;
    http2 on;
    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
    }
}

Aktywuj konfigurację i sprawdź poprawność:

# 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

Oczekiwany wynik:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
⚠️ Jeśli nginx -t zwraca błąd o brakujących plikach certyfikatu - to normalne na tym etapie. Certbot doda certyfikaty w następnym kroku. Na razie nginx nie startuje na 443, ale na 80 działa.

Krok 7: Certyfikat HTTPS - Let's Encrypt

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

# 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

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

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

Oczekiwany wynik po sukcesie:

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.

Teraz przeładuj nginx - tym razem załaduje też konfigurację HTTPS:

nginx -t && systemctl reload nginx

Sprawdź automatyczne odnawianie certyfikatu:

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

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)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.

# Sprawdź timer odnowień (certbot dodaje go automatycznie)
systemctl status certbot.timer

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
💡 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.

# Przejdź do katalogu n8n
cd /opt/n8n

# Uruchom kontenery w tle (-d = detached)
docker compose up -d

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

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

Sprawdź status kontenerów:

docker compose ps

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

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

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

docker compose logs n8n --tail=30

Szukaj linii:

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

Zweryfikuj że n8n odpowiada lokalnie:

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

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ę:

# 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

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ść

# 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

Powiadomienia email (opcjonalne)

# 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.

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

cd /opt/n8n
docker compose up -d

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

nano /opt/n8n/backup.sh
#!/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_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
# Nadaj uprawnienia wykonania
chmod +x /opt/n8n/backup.sh

# Przetestuj ręcznie
/opt/n8n/backup.sh

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

crontab -e

Dodaj linię:

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

Przywracanie z backupu

# 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_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
⚠️ 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ą.

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

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

Sprawdzanie dostępnych wersji

# 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]]"

Krok 14: Monitoring i healthcheck

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

Sprawdzenie statusu jedną komendą

# 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

Prosty skrypt alertów (ping co minutę)

nano /opt/n8n/healthcheck.sh
#!/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
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
💡 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ą

# 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

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

# 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

Webhooki nie działają

# 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

n8n używa za dużo pamięci

# 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

Przydatne komendy do debugowania

# 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';"

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

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ę -->
Szkolenie n8n + AI: sztuczna inteligencja w automatyzacji firmy – termin gwarantowany

Najczęściej zadawane pytania

Ile kosztuje własny serwer do n8n?
Najtańsze opcje zaczynają się od około 4-12 euro miesięcznie. Hetzner CX22 (4 GB RAM, 2 vCPU, 40 GB) kosztuje ok. 6 euro, Contabo VPS S (8 GB RAM) ok. 7 euro. Do podstawowego użytku wystarczy 2 GB RAM, ale zalecamy 4 GB dla komfortu pracy.
Czy n8n self-hosted jest bezpłatny?
Tak - n8n Community Edition (self-hosted) jest bezpłatny i open-source. Płacisz tylko za serwer VPS. Wersja cloud (n8n.cloud) jest płatna - od 20 dolarów miesięcznie.
Co zrobić gdy n8n nie startuje po docker compose up?
Sprawdź logi: docker compose logs n8n. Najczęstsze przyczyny: błędne hasło do PostgreSQL (musi być identyczne w obu miejscach w docker-compose.yml), brak praw do wolumenu, zajęty port 5678. Sprawdź też czy PostgreSQL jest healthy przed startem n8n: docker compose ps.
Jak bezpiecznie zaktualizować n8n?
Przed aktualizacją wykonaj backup bazy danych: docker exec n8n-postgres-1 pg_dump -U n8n n8n > backup.sql. Następnie: docker compose pull && docker compose up -d. n8n automatycznie migruje schemat bazy danych.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...