SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-28

n8n przechodzi w tryb offline na VPS: przyczyny i naprawa

Diagnozowanie n8n w trybie offline. Dowiedz się, jak odróżnić błędy WebSocket, pętle restartu kontenera, błędy OOM Kill oraz problemy z harmonogramem w środowisku Docker.

Dlaczego n8n przechodzi w tryb offline: cztery awarie, jeden objaw

„n8n przechodzi w tryb offline” to jedno zdanie opisujące cztery różne awarie, z których każda wymaga innego rozwiązania. Edytor wyświetla komunikat o utracie połączenia, mimo że kontener działa poprawnie. Kontener restartuje się samoczynnie. Jądro systemu przerywa proces Node.js z powodu zbyt dużego zużycia pamięci. Albo z samym procesem wszystko jest w porządku, a aktywny workflow po prostu nigdy się nie uruchamia. Zmiana niewłaściwego ustawienia spowoduje stratę całego weekendu na rozwiązywanie problemu, którego w rzeczywistości nie było.

Dlatego przed przystąpieniem do jakichkolwiek zmian w konfiguracji należy ustalić, z którą awarią mamy do czynienia. n8n działa jako pojedynczy proces Node.js, zazwyczaj wewnątrz jednego kontenera Docker, za reverse proxy, które dokonuje terminacji TLS (transport layer security). Każda z tych warstw może ulec awarii w specyficzny dla siebie sposób, a przeglądarka zgłasza je wszystkie za pomocą tego samego komunikatu.

Diagnozowanie w tej kolejności

Wykonaj poniższe polecenia na serwerze VPS (virtual private server) i odczytaj wartości wyświetlone przez własną maszynę. Nie porównuj ich z liczbami z wątków na forach. Istotne są wartości opisujące Twój serwer, a nie cudzy.

docker ps -a --filter name=n8n
docker logs --tail 200 --timestamps n8n
docker inspect n8n | grep -iE 'Status|Running|RestartCount|OOMKilled|ExitCode'
docker stats --no-stream

Kolumna STATUS z polecenia docker ps -a informuje, jak długo kontener znajduje się w bieżącym stanie. Porównaj tę wartość z momentem wystąpienia problemu. Jeśli kontener działał na długo przed pojawieniem się komunikatu o błędzie, oznacza to, że n8n nie uległo awarii. Uszkodzeniu uległo połączenie między przeglądarką a backendem, co dotyczy ścieżki websocket opisanej w następnej sekcji.

RestartCount określa, ile razy Docker restartował ten kontener. Zapisz tę liczbę, odczekaj minutę i odczytaj ją ponownie. Liczba rosnąca w trakcie obserwacji oznacza pętlę restartów, a wiersze dziennika bezpośrednio przed każdym restartem zawierają przyczynę.

OOMKilled to flaga logiczna (true lub false). Wartość true oznacza, że jądro Linux zabiło proces z powodu przekroczenia limitu pamięci – własnego limitu kontenera lub limitu całej maszyny. To pole odróżnia przerwanie z powodu braku pamięci od każdego innego rodzaju zakończenia procesu, dlatego należy je sprawdzić przed wysuwaniem hipotez.

ExitCode zawiera kod, z którym kontener ostatnio zakończył działanie. Nie ma potrzeby zapamiętywania znaczenia każdego kodu. Odczytaj swój kod, a następnie sprawdź końcówkę docker logs z tego samego znacznika czasu. Dopiero połączenie końcówki dziennika z flagą braku pamięci wskazuje na przyczynę; poleganie na jednym z tych elementów może prowadzić do błędnych wniosków.

docker stats pokazuje bieżące zużycie pamięci w odniesieniu do obowiązującego limitu. Uruchom to polecenie w drugim terminalu, wywołaj przepływ pracy powodujący błąd i obserwuj zmiany wartości w momencie wystąpienia awarii.


Komunikat o utracie połączenia zazwyczaj wskazuje na problem z reverse proxy

Edytor n8n utrzymuje jedno długotrwałe połączenie typu push z backendem, aby przesyłać postęp wykonywania zadań bezpośrednio na obszar roboczy. Domyślnie połączenie to jest realizowane przez WebSocket, co wybiera N8N_PUSH_BACKEND, a jego domyślna wartość to websocket. Połączenie WebSocket rozpoczyna się jako zwykłe żądanie HTTP zawierające nagłówki Connection: Upgrade oraz Upgrade: websocket. Serwer odpowiada 101 Switching Protocols i od tego momentu obie strony korzystają z tego samego gniazda TCP w obu kierunkach.

Dwie przyczyny powodują przerwanie tego procesu i obie leżą po stronie proxy, a nie n8n. Proxy komunikuje się z backendem za pomocą HTTP/1.0 lub usuwa nagłówki upgrade, przez co proces aktualizacji połączenia nigdy nie następuje, a edytor próbuje łączyć się w nieskończoność. Alternatywnie, aktualizacja przebiega pomyślnie, ale proxy zamyka gniazdo z powodu braku aktywności, ponieważ WebSocket bez przesyłanych komunikatów wygląda jak bezczynne połączenie. W obu przypadkach kontener działa poprawnie. Wyświetlany baner to informacja z przeglądarki o utracie kanału komunikacji.

Przed wprowadzeniem jakichkolwiek zmian należy potwierdzić to w przeglądarce. Otwórz narzędzia deweloperskie, przejdź do karty Network, przefiltruj wyniki pod kątem WS i odśwież edytor. Żądanie push powinno otrzymać status 101 Switching Protocols i pozostać otwarte. Żądanie push, które zwraca zwykły kod statusu lub pojawia się ponownie co kilka sekund, wskazuje na problem z konfiguracją proxy.

Ustawienia nginx utrzymujące połączenie z edytorem

nginx nie przekazuje nagłówka upgrade, dopóki nie zostanie o to poproszony. proxy_pass domyślnie komunikuje się z backendem przy użyciu HTTP/1.0, a Connection oraz Upgrade to nagłówki typu hop-by-hop, które nginx usuwa podczas przetwarzania żądania. Należy je przywrócić. Blok map umieszcza się w kontekście http, a nie wewnątrz server. Jeśli poniższa konfiguracja bloku serwera jest niejasna, szczegółowe omówienie dyrektyw bloku serwera nginx wyjaśnia działanie każdej z nich.

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
server {
    listen 443 ssl;
    http2 on;
    server_name n8n.example.com;

    location / {
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        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;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }
}

proxy_read_timeout to linia, o której często zapominają użytkownicy. Jej wartość domyślna wynosi 60 sekund i dotyczy również zestawionego połączenia WebSocket, dlatego karta edytora pozostawiona otwarta na nieaktywnej instancji traci połączenie około minutę po ostatniej przesłanej wiadomości. Zwiększenie tej wartości eliminuje komunikat o błędzie pojawiający się po powrocie do otwartej karty.

sudo nginx -t && sudo systemctl reload nginx
sudo nginx -T | grep -iE 'proxy_http_version|upgrade|proxy_read_timeout'

nginx -T wyświetla pełną aktywną konfigurację zamiast zawartości pojedynczego pliku, co pozwala potwierdzić, czy wprowadzone zmiany zostały wczytane. Konfiguracja znajdująca się w pliku, który nie jest uwzględniony przez żadną dyrektywę include, jest przyczyną, dla której poprawna poprawka wydaje się nie przynosić efektu.

Następnie należy poinformować n8n, że znajduje się za proxy, ponieważ aplikacja buduje adresy URL na podstawie tych wartości.

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

N8N_PROXY_HOPS domyślnie przyjmuje wartość 0, co oznacza, że n8n traktuje adres połączenia jako adres klienta i ignoruje X-Forwarded-For. Należy ustawić tę wartość na liczbę serwerów proxy znajdujących się przed kontenerem. Według stanu na sierpień 2026, N8N_WEBHOOK_URL jest aktualną nazwą zmiennej, a starsza nazwa WEBHOOK_URL nadal działa, choć przy starcie generuje ostrzeżenie o wycofaniu wsparcia.

Traefik przekazuje WebSocket, a następnie przerywa połączenie przez timeout

Traefik przekazuje żądanie upgrade do WebSocket bez konieczności stosowania middleware czy dodatkowych etykiet, więc użytkownik Traefik widzący ten komunikat zazwyczaj napotyka limit czasu, a nie brakujący nagłówek. Parametry konfiguracyjne znajdują się w entryPoint. Według stanu na sierpień 2026 w Traefik v3, wartość idleTimeout domyślnie wynosi 180 sekund, a readTimeout domyślnie 60 sekund.

entryPoints:
  websecure:
    address: ":443"
    transport:
      respondingTimeouts:
        readTimeout: 0
        idleTimeout: 3600s

Caddy obsługuje upgrade automatycznie w reverse_proxy i nie wymaga w tym celu żadnej dyrektywy. Jeśli zmiana proxy jest niemożliwa, ponieważ zarządza nim inny podmiot, należy przełączyć kanał push na N8N_PUSH_BACKEND=sse. SSE (server-sent events) to standardowa odpowiedź HTTP utrzymywana jako otwarta, więc działa ona przez proxy odrzucające upgrade, choć agresywny limit czasu bezczynności (idle timeout) nadal może ją przerwać. Wybór samego proxy to odrębna decyzja, a porównanie nginx, Caddy i Traefik omawia koszty operacyjne każdego z tych rozwiązań.

Gdy kontener faktycznie się restartuje

Jeśli RestartCount rośnie, kontener ulega awarii, a Docker go restartuje. Porównaj znaczniki czasu w dzienniku z momentami restartów i sprawdź, co wydarzyło się bezpośrednio przed nimi. Cztery przyczyny odpowiadają za niemal wszystkie przypadki: błąd konfiguracji uniemożliwiający start, baza danych, do której n8n nie ma dostępu, awaria w trakcie działania oraz przerwanie procesu przez mechanizm ochrony pamięci.

Zacznij od wolumenu, ponieważ uprawnienia są najczęstszą przyczyną problemów. Oficjalny obraz działa jako użytkownik bez uprawnień node i przechowuje dane w /home/node/.n8n. Montowanie typu bind mount utworzone przez root nie jest zapisywalne dla tego użytkownika, więc proces kończy się przy każdym starcie, a polityka restartu ukrywa ten fakt w pętli.

docker compose config
docker run --rm -it --entrypoint sh docker.n8n.io/n8nio/n8n -c 'id'
docker exec n8n ls -ld /home/node/.n8n

Wolumen nazwany całkowicie eliminuje ten problem, ponieważ Docker tworzy go z odpowiednimi uprawnieniami właściciela. Jeśli wymagane jest użycie bind mount, wykonaj chown na katalogu hosta, przypisując go do numerycznego identyfikatora użytkownika wyświetlonego przez pierwsze polecenie. Mapowanie własności między hostem a kontenerem warto zrozumieć raz, a wyjaśnienie PUID i PGID opisuje, w jaki sposób te obrazy decydują o tym, kto ma prawo zapisu do plików.

Zabicie procesu przez Out of Memory przypominające awarię

Istnieją dwa oddzielne limity pamięci dla procesu n8n, które skutkują różnymi błędami. Limit grupy kontrolnej (cgroup) kontenera jest wymuszany przez jądro systemu: po jego przekroczeniu proces jest natychmiast zabijany bez możliwości zapisu jakichkolwiek danych, a OOMKilled przyjmuje wartość true. Limit sterty V8 jest wymuszany wewnątrz Node.js: po jego przekroczeniu Node zgłasza błąd sterty wraz ze śladem stosu i kończy działanie samodzielnie, więc OOMKilled przyjmuje wartość false. Z poziomu przeglądarki oba te zdarzenia wyglądają identycznie. W docker inspect różni je tylko jedno pole.

Ustaw limit sterty Node poniżej limitu kontenera. Jeśli limit sterty jest wyższy z obu, V8 kontynuuje alokację pamięci nawet po momencie, w którym interweniuje jądro systemu. W rezultacie mechanizm odśmiecania (garbage collector) nigdy nie osiąga własnego limitu, a użytkownik zawsze otrzymuje surowszy błąd bez dostępu do dziennika zdarzeń.

services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: unless-stopped
    environment:
      - NODE_OPTIONS=--max-old-space-size=<MiB, below the container limit>
    deploy:
      resources:
        limits:
          memory: <your container limit>

Wybierz obie wartości w oparciu o rzeczywiste zasoby VPS, pozostawiając margines dla bazy danych, proxy oraz systemu operacyjnego. docker stats --no-stream wyświetla bieżące zużycie obok obowiązującego limitu, co pozwala sprawdzić, czy zdefiniowany limit został poprawnie zastosowany przez Docker. W jaki sposób stosowane są limity pamięci w Compose zawiera informacje o tym, który klucz ma pierwszeństwo w przypadku ustawienia kilku z nich.

Dane wykonania to zasób, który nieustannie rośnie

Pojedyncze wykonanie przechowuje dane wyjściowe każdego węzła w trakcie trwania procesu, a n8n następnie zapisuje te dane. Wynikają z tego dwie konsekwencje. Szczytowe zużycie pamięci podczas jednego uruchomienia jest determinowane przez największą partię danych, która przez nie przechodzi. Zatem workflow przetwarzający dziesięć tysięcy wierszy jednocześnie różni się od tego samego workflowu przetwarzającego dwieście wierszy w jednym cyklu. Ponadto zapisana kopia danych rośnie, dopóki nie zostanie usunięta.

Mechanizm czyszczenia (pruning) rozwiązuje drugi problem. Od sierpnia 2026 r. domyślnie włączone jest czyszczenie, z EXECUTIONS_DATA_MAX_AGE ustawionym na 336 godzin (14 dni) oraz EXECUTIONS_DATA_PRUNE_MAX_COUNT na 10000. Są to wartości wystarczające dla małego serwera VPS z bazą SQLite, gdzie jeden plik przechowuje wszystkie dane, a ten sam proces, który obsługuje edytor, musi je również odczytywać i zapisywać.

environment:
  - EXECUTIONS_DATA_PRUNE=true
  - EXECUTIONS_DATA_MAX_AGE=72
  - EXECUTIONS_DATA_PRUNE_MAX_COUNT=1000
  - EXECUTIONS_DATA_SAVE_ON_SUCCESS=none
  - EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=false

EXECUTIONS_DATA_SAVE_ON_SUCCESS=none to ustawienie agresywne. Zachowuje ono nieudane wykonania w celach debugowania, a usuwa te zakończone sukcesem. Należy podjąć tę decyzję świadomie, ponieważ workflow, który wygenerował błędne dane wyjściowe bez zgłoszenia błędu, nie pozostawi żadnych informacji do analizy. Proces czyszczenia najpierw oznacza wiersze jako usunięte, a usuwa je w późniejszym przebiegu. Ponadto SQLite ponownie wykorzystuje zwolnione strony zamiast zwracać je systemowi, więc rozmiar pliku na dysku nie zmniejszy się natychmiast po zmianie ustawień.

Aby ograniczyć szczytowe zużycie zasobów zamiast całkowitej liczby zapisanych danych, należy przesyłać mniej danych w jednym uruchomieniu. Należy dzielić duże zadania na pod-workflowy zwracające niewielkie wyniki do procesu nadrzędnego, stosować grupowanie za pomocą węzła Loop Over Items oraz unikać przechowywania całych zbiorów danych w węźle Code.

Pliki binarne nie powinny być przetwarzane w pamięci operacyjnej

N8N_DEFAULT_BINARY_DATA_MODE domyślnie przyjmuje wartość default, co powoduje przechowywanie danych binarnych w pamięci uruchomionego procesu. Każdy plik pobrany przez węzeł oraz każda kopia przekazana do kolejnego węzła pozostaje w pamięci aż do zakończenia działania procesu. Jeden przepływ pracy pobierający kilka dużych załączników może spowodować przekroczenie limitu pamięci, do którego standardowe operacje na JSON nigdy by nie doprowadziły. Dlatego awarie występują w powiązaniu z konkretnym przepływem pracy, a nie w określonych odstępach czasu.

environment:
  - N8N_DEFAULT_BINARY_DATA_MODE=filesystem

Przy użyciu filesystem dane binarne są zapisywane w lokalizacji N8N_BINARY_DATA_STORAGE_PATH, która domyślnie znajduje się wewnątrz folderu użytkownika n8n, a tym samym na tym samym wolumenie co pozostałe dane. Przed przełączeniem należy sprawdzić, czy wolumen dysponuje wystarczającą ilością miejsca. Parametr N8N_PAYLOAD_SIZE_MAX określa maksymalny rozmiar przychodzącego ładunku webhooka w MiB (mebibajtach) i domyślnie wynosi 16. Zwiększenie tej wartości pozwala na obsługę większych żądań, co wiąże się z akceptacją wyższego zużycia pamięci RAM.

Wszystkie pozostałe procesy współdzielące serwer rywalizują o tę samą pamięć RAM. Jeśli błędy OOM (Out of Memory) zaczęły występować po dodaniu kontenera z bazą danych, uruchomienie bazy danych w Dockerze lub bezpośrednio na hoście jest kompromisem, na który należy się zdecydować.

Polityka restartu i przywracanie działania po restarcie

Kontener bez zdefiniowanej polityki restartu pozostaje wyłączony po zakończeniu pracy oraz po restarcie hosta. Opcja restart: unless-stopped przywraca go w obu przypadkach, jednocześnie respektując kontenery zatrzymane ręcznie. Opcja restart: always restartuje również kontenery zatrzymane celowo, gdy tylko usługa Docker zostanie uruchomiona ponownie.

Aplikacja n8n udostępnia punkt końcowy stanu zdrowia (health endpoint), określony przez N8N_ENDPOINT_HEALTH, którego domyślną wartością jest healthz. Należy sprawdzić go najpierw z poziomu hosta, aby upewnić się, że ścieżka jest poprawna dla danej instancji.

curl -fsS http://127.0.0.1:5678/healthz
docker exec n8n which wget curl
sudo systemctl is-enabled docker

Sam mechanizm healthcheck nie powoduje restartu. Compose oznacza kontener jako niezdrowy (unhealthy) i na tym kończy działanie, dlatego healthcheck wymaga polityki restartu lub zewnętrznego monitora, aby przyniósł jakikolwiek efekt. Artykuły Tworzenie działającego mechanizmu healthcheck oraz automatyczne uruchamianie stosu po restarcie omawiają oba te zagadnienia.

Przepływ pracy, który nie uruchamia się mimo poprawnego działania n8n

W tym przypadku nie pojawia się żaden komunikat o błędzie ani restart. Kontener działa, edytor jest dostępny, a oczekiwane uruchomienie nie pojawia się na liście wykonań. Za większość takich sytuacji odpowiadają cztery przyczyny.

  • Przepływ pracy nie jest aktywny. Wyzwalacz Schedule Trigger działa tylko w ścieżce produkcyjnej, więc testowanie go w edytorze nie powoduje zaplanowania żadnych zadań.
  • Strefa czasowa jest nieprawidłowa. GENERIC_TIMEZONE domyślnie używa America/New_York, więc harmonogram ustawiony na 09:00 uruchomi się o 09:00 w tej strefie, dopóki nie ustawisz GENERIC_TIMEZONE oraz TZ na własne wartości.
  • Przestoje nie są nadrabiane. Wyzwalacze są rejestrowane podczas startu n8n, więc harmonogram, który przypadał w czasie restartu kontenera, nie zostanie uruchomiony z opóźnieniem. Kolejne uruchomienie nastąpi w najbliższym terminie po starcie.
  • Przepływ pracy został automatycznie dezaktywowany. N8N_WORKFLOW_AUTODEACTIVATION_ENABLED jest domyślnie wyłączone, a gdy jest włączone, przepływ pracy, który ciągle ulega awarii, zostaje wycofany z publikacji, po czym wygląda dokładnie tak, jakby nikt go nigdy nie aktywował.

Otwórz listę wykonań i przefiltruj ją według danego przepływu pracy. Wpis, który zakończył się niepowodzeniem, oznacza problem z samym przepływem. Jeśli wystąpił błąd 429 w odniesieniu do innej usługi hostowanej na tym samym serwerze, limit dotyczy tej usługi, a nie n8n, a przewodnik dotyczący błędu 429 w SearXNG pokazuje, jak odróżnić własny mechanizm ograniczania liczby żądań od blokad nakładanych przez zewnętrzne silniki na adres IP serwera. Brak jakiegokolwiek wpisu oznacza problem z wyzwalaczem, co wymaga sprawdzenia czterech powyższych przyczyn.

Co zmienić w pierwszej kolejności

  1. Przed edycją jakiegokolwiek pliku zapoznaj się z STATUS, RestartCount oraz OOMKilled dla własnego kontenera.
  2. Jeśli kontener nie uległ awarii, popraw nagłówki aktualizacji proxy oraz limit czasu bezczynności (idle timeout).
  3. Jeśli OOMKilled ma wartość true, ustaw wybrany przez siebie limit kontenera, umieść górny limit sterty Node poniżej tej wartości i przełącz dane binarne na filesystem.
  4. Jeśli nic nie zadziałało, sprawdź, czy workflow jest aktywny oraz czy strefa czasowa instancji jest zgodna z Twoją.

Większość z tych ustawień konfiguruje się jednorazowo po poprawnym zainstalowaniu oprogramowania. Jeśli dopiero przygotowujesz instalację, instrukcja n8n w Dockerze z HTTPS stanowi podstawę, w której należy zastosować te ustawienia.

FAQ

Dlaczego edytor n8n wyświetla komunikat o utracie połączenia, mimo że kontener działa?

Edytor utrzymuje otwarte połączenie WebSocket w celu przesyłania postępu wykonywania zadań. Jeśli reverse proxy nie przekazuje nagłówków Connection: Upgrade oraz Upgrade: websocket lub nie korzysta z protokołu HTTP/1.1 w komunikacji upstream, proces aktualizacji połączenia nie kończy się, a przeglądarka próbuje łączyć się w nieskończoność, podczas gdy n8n działa poprawnie. W nginx wymagane jest użycie proxy_http_version 1.1 oraz obu linii proxy_set_header, a także ustawienie proxy_read_timeout na wartość wyższą niż domyślne 60 sekund, aby nie przerywać połączenia w nieaktywnych kartach. Należy sprawdzić aktualną konfigurację za pomocą sudo nginx -T, a nie plik, który był edytowany.

Jak odróżnić błąd typu out of memory od zwykłej awarii?

Należy wykonać docker inspect n8n | grep -iE 'OOMKilled|ExitCode|RestartCount' i sprawdzić flagę OOMKilled. Wartość True oznacza, że jądro systemu zabiło proces z powodu przekroczenia limitu pamięci; w dzienniku kontenera nie będzie przydatnych informacji, ponieważ proces nie zdążył ich zapisać. Wartość False, przy jednoczesnym błędzie sterty i śladzie stosu na końcu docker logs, oznacza, że Node.js osiągnął własny limit sterty V8 i zakończył działanie samodzielnie. Należy ustawić NODE_OPTIONS=--max-old-space-size na wartość poniżej limitu kontenera, aby wywołać drugi rodzaj błędu, który pozostawia ślady w logach.

Czy usuwanie danych wykonania natychmiast zwalnia miejsce na dysku?

Nie. EXECUTIONS_DATA_PRUNE oznacza stare wykonania jako przeznaczone do usunięcia, a późniejszy proces usuwa je zgodnie z harmonogramem określonym w EXECUTIONS_DATA_PRUNE_HARD_DELETE_INTERVAL. W przypadku SQLite plik bazy danych ponownie wykorzystuje zwolnione strony zamiast zwracać je do systemu plików, więc rozmiar pliku na dysku pozostaje niezmieniony przez pewien czas po usunięciu wierszy. Należy ustawić EXECUTIONS_DATA_MAX_AGE oraz EXECUTIONS_DATA_PRUNE_MAX_COUNT na wartości odpowiednie dla danego serwera i sprawdzić zajętość miejsca następnego dnia, a nie natychmiast.

Dlaczego zaplanowany workflow nie uruchomił się podczas restartu n8n?

n8n rejestruje wyzwalacze w momencie uruchomienia procesu i nie wykonuje ponownie harmonogramów, których termin minął w czasie przestoju. Pętla restartów powoduje więc ciszę, a nie serię zaległych uruchomień; kolejne wykonanie nastąpi w najbliższym terminie po starcie. Jeśli wymagane jest zapewnienie ciągłości uruchomień, należy wywoływać workflow z zewnętrznego źródła poprzez webhook, przenosząc logikę ponawiania poza n8n.

Czy healthcheck zrestartuje n8n, gdy przestanie odpowiadać?

Nie samodzielnie. Healthcheck w Compose jedynie oznacza kontener jako zdrowy lub niezdrowy. Restartowanie jest zadaniem polityki restartu, więc restart: unless-stopped przywraca kontener po jego wyjściu, a także po restarcie hosta, o ile usługa Docker jest włączona. Należy to potwierdzić za pomocą sudo systemctl is-enabled docker. Aby reagować konkretnie na stan niezdrowy, wymagany jest zewnętrzny obserwator działający poza Dockerem, który odczytuje status i restartuje usługę.