Знакът на КАГАМИ КАГАМИ
kagami.bg/academy · lesson · machine-readable viewVERIFIED 2026-10-01 · UPDATED 2026-10-01
IDENTITY
module
n8n-01 · Installation and first workflow
series
n8n · lesson 1 of 10
level
Beginner
duration
about 1 h
prerequisites
Docker with Compose v2 on the machine (on Windows: Docker Desktop with the WSL2 backend, project folder inside the WSL filesystem)
trust_label
VERIFIED 2026-10-01 (against official n8n documentation, the n8n 2.0 breaking-changes page, the n8n GitHub release list and the live Frankfurter API) · UPDATED 2026-10-01 · NOT TESTED end to end (no Docker daemon available during the check; compose file parsed as valid YAML only)
versions
n8n 2.41.4 (stable, pinned via env) · PostgreSQL 18 · Docker Compose v2 · Frankfurter API v1 (deprecated but kept available; v2 returns a different shape)
language
human view: bg · english edition: /en/academy/n8n/ (lesson 1)
previous / next
n8n Cheat Sheet / n8n 02 · Webhook and HTTP Request nodes
PURPOSE

Install a self-hosted n8n on a single machine with Docker Compose and PostgreSQL, keep secrets in an .env file, publish the editor to loopback only, then build a first workflow: Manual Trigger, HTTP Request (public exchange-rate API), Edit Fields (format a log line with an expression), Convert to File, Read/Write Files from Disk (append to a file). Learn the editor, the difference between manual execution and publishing, and how to read a failed execution.

KEY CONCEPTS
COMMANDS / PATHS
CHECKLIST
NEXT MODULE

n8n 02 · Webhook and HTTP Request nodes · receive data from outside systems and call REST APIs · offer: Quick experiment (kagami.bg/stalbata/)

SOURCES
TAGS
n8ndocker-composepostgresworkflowautomationhttp-requestexpressionsself-hosting
ПРОВЕРЕНО · 01.10.2026 ОБНОВЕНО · 01.10.2026

n8n: инсталация с Docker и първият ти workflow

От нулата до работеща автоматизация. Поставяме n8n на твоя компютър с Docker Compose и собствена база Postgres, разглеждаме интерфейса и правим първия си работен процес: взема курса евро/долар от публично API и го записва ред по ред във файл.

⏱ около 1 ч Начинаещ n8n · Обучение 1/10 Docker · n8n 2.x · workflow
n8n · Postgres в Docker🔒 локално Публично API за курсове (Frankfurter)🌐 глобален
🔄
ОБНОВЕНО · 01.10.2026 — какво
Версията е n8n 2.x, не 1.x. Закачаме конкретна версия (2.41.4, текущата стабилна към 01.10.2026) през файл .env вместо latest, а образът е docker.n8n.io/n8nio/n8n. Compose файлът е преработен: махнат е остарелият ред version:; махната е основната автентикация (N8N_BASIC_AUTH_* не съществува в днешния n8n — при първо отваряне си правиш собственически акаунт); паролата на базата и ключът за криптиране не са в текста, а се генерират; Postgres е в същия проект (версия 18, с PGDATA), а не на друга машина, и няма публикуван порт; редакторът е достъпен само от 127.0.0.1. Махнати са N8N_HOST, WEBHOOK_URL, N8N_METRICS и настройките за изчистване на изпълнения (те не трябват за локален старт; изчистването е включено по подразбиране). Интерфейсът е описан по днешния вид: „Activate“ е заменено с Publish (n8n пише промените автоматично, няма нужда от Ctrl+S); бутонът е Execute Workflow, а на отделен нод — Execute step; панелът с нодове се отваря с N. Практическият пример е променен: вместо USD/BGN курсът е EUR/USD и EUR/GBP (България е в еврозоната от 01.01.2026), с актуален адрес на API-то (api.frankfurter.dev); добавен е нодът Convert to File, защото записът на файл иска двоични данни; файлът се пише в /home/node/.n8n-files, защото от n8n 2.0 файловите нодове по подразбиране имат достъп само до тази папка (споделената папка /data/shared е махната). Премахнати са справките за отделни сървъри в частна мрежа, обратният прокси и настройката на достъпа до Postgres отвън; уебхукът е тема на Обучение 2.
⚠️
Какво не сме пускали сами
При проверката нямахме Docker на разположение. Compose файлът е сверен с официалните документи и е синтактично валиден, но не е пускан от край до край — затова няма етикет „ТЕСТВАНО“. Заявката към API-то за курсове е пусната наживо на 01.10.2026 и връща показания по-долу вид. Имената на полетата в нодовете са по документацията; при друга версия на n8n етикетите в интерфейса може да се различават леко.

01Какво ще научиш

02Преди да започнеш

💡
Бележка за SQLite
Ако пуснеш n8n без база, той ползва вградената SQLite. Това е за опити. Документацията препоръчва Postgres за всичко, което работи денонощно или има повече потребители и работни процеси — затова започваме директно с него.

03Стъпки

  1. Какво ще построим

    Два контейнера в един проект: n8n (редакторът и двигателят) и Postgres (там n8n пази работните процеси, достъпите и историята). После — работен процес от пет нода. Защо контейнери? Защото всяка програма идва с всичко нужно, не пречи на другите и се маха с една команда.

    НодВидКакво прави
    Manual TriggerтригерСтартира процеса, когато натиснеш „Execute Workflow“
    HTTP RequestдействиеВзема курсовете от публично API
    Edit FieldsданниПодрежда един ред за журнала
    Convert to FileданниПревръща текста във файл (двоични данни)
    Read/Write Files from DiskдействиеДописва реда към файл
  2. Папка и файл с тайните

    Тайните (парола на базата, ключ за криптиране) не се пишат в compose файла. Държим ги в .env — Compose го чете сам. Генерираме ги на място, за да няма две инсталации с една и съща „тайна“.

    bash · ~/n8n-lab/.env
    mkdir -p ~/n8n-lab && cd ~/n8n-lab
    
    cat > .env <<EOF
    N8N_VERSION=2.41.4
    POSTGRES_USER=n8n
    POSTGRES_PASSWORD=$(openssl rand -hex 24)
    POSTGRES_DB=n8n
    N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
    TZ=Europe/Sofia
    EOF
    
    chmod 600 .env
    ✅
    Запази ключа извън стека
    N8N_ENCRYPTION_KEY шифрова всички достъпи, които ще запишеш в n8n. Ако го загубиш, след възстановяване от копие достъпите не могат да се разшифроват. Препиши го в мениджъра на пароли (cat .env го показва). Числото 2.41.4 е текущата стабилна версия към 01.10.2026 — виж „Обновяване“ по-долу.
  3. Файлът compose.yaml

    Един файл описва целия стек. Правилата в него: версията е закачена (не latest), данните са в именувани томове, редакторът е достъпен само от твоята машина (127.0.0.1), а n8n чака Postgres да е „здрав“, преди да стартира.

    yaml · ~/n8n-lab/compose.yaml
    name: n8n-lab
    
    services:
      postgres:
        image: postgres:18
        restart: unless-stopped
        environment:
          POSTGRES_USER: ${POSTGRES_USER}
          POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
          POSTGRES_DB: ${POSTGRES_DB}
          PGDATA: /var/lib/postgresql/data
        volumes:
          - db_data:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
          interval: 5s
          timeout: 5s
          retries: 10
    
      n8n:
        image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
        restart: unless-stopped
        depends_on:
          postgres:
            condition: service_healthy
        environment:
          TZ: ${TZ}
          GENERIC_TIMEZONE: ${TZ}
          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}
          N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
          N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS: "true"
        ports:
          - "127.0.0.1:5678:5678"
        volumes:
          - n8n_data:/home/node/.n8n
    
    volumes:
      db_data:
      n8n_data:
    💡
    Защо точно така
    PGDATA — Postgres 18 смени мястото на данните по подразбиране; без този ред базата се връща празна. 127.0.0.1 — портът не се вижда от другите в мрежата ти; Postgres изобщо няма публикуван порт, n8n го намира по името postgres. TZ и GENERIC_TIMEZONE — по подразбиране n8n работи във времева зона America/New_York; без тях часовете в изразите и графиците ще са американски.

    Провери, че файлът е четим (Compose замества променливите и показва резултата — тайните също, затова не го пращай никому):

    bash
    docker compose config --quiet && echo "compose: OK"
  4. Стартирай и провери

    bash
    cd ~/n8n-lab
    docker compose up -d
    docker compose ps

    Първия път се теглят образите — нужни са минути и интернет. После docker compose ps трябва да покаже postgres като healthy, а n8n като running. Проверка дали n8n отговаря:

    bash
    curl -sf http://localhost:5678/healthz && echo " n8n е жив"

    Ако нещо не стои, виж логовете: docker compose logs -f n8n (изход с Ctrl+C).

  5. Първо влизане

    Отвори http://localhost:5678 в браузъра. При първо отваряне n8n те кара да създадеш собственически акаунт (имейл, име, парола) — друга „основна автентикация“ няма. Акаунтът е локален, в твоята база.

    Създай нов работен процес: бутонът за създаване горе вляво в страничното меню → Workflow. Празното платно ти предлага Add first step…

  6. Обиколка на интерфейса

    ЕлементКакво прави
    WorkflowsСписък на твоите работни процеси; публикуваните са отбелязани със знак
    CredentialsЗапазени достъпи (ключове, пароли, OAuth) — шифровани с ключа от .env
    ExecutionsИстория на изпълненията на процеса — успешни и грешки; може да се филтрира по статус
    Платно (canvas)Тук строиш процеса; двоен клик върху нод го отваря
    Add node / NОтваря панела за търсене и добавяне на нод
    Execute WorkflowИзпълнява целия процес (Ctrl/Cmd+Enter), без да го публикуваш
    Execute stepИзпълнява само избрания нод
    Pin / PЗапазва изхода на нод за тестове — само за разработка
    PublishПуска процеса „на живо“ — виж по-долу
    Settings (на нод)Always Output Data, Execute Once, Retry On Fail, On Error, бележки
    ✅
    Запазването е автоматично
    n8n записва промените сам (за няколко секунди). Няма бутон „Save“, който да забравиш. „Publish“ е друго нещо: то пуска конкретна версия в производство — но само ако процесът има тригер, който се задейства сам (график, уебхук). Процес само с Manual Trigger се пуска от редактора и няма какво да публикуваш.

    За история: старият бутон „Activate“ вече е „Publish“, а нодът „Start“ е премахнат от n8n 2.0 — заменен с Manual Trigger.

  7. Първи нод: Manual Trigger

    Натисни Add first step… (или N) → търси Manual Trigger → добави. Този нод стартира процеса при натискане на Execute Workflow.

    💡
    Тригер и действие
    Тригерът започва процеса, действието върши нещо. Ръчният тригер е идеален за тест; в производство го заменяш с график или уебхук (Обучение 7 и 2).
  8. HTTP Request: вземи курса

    Натисни + след тригера → HTTP Request. Задай:

    ПолеСтойност
    MethodGET
    URLhttps://api.frankfurter.dev/v1/latest?base=EUR&symbols=USD,GBP
    AuthenticationNone (публично API, без ключ)

    Натисни Execute step. В изхода трябва да видиш обект като този (датата и числата ще са различни):

    json · изход на HTTP Request
    {"amount":1.0,"base":"EUR","date":"2026-09-30","rates":{"GBP":0.85463,"USD":1.1355}}

    След като имаш данните, натисни Pin (P) в изхода: n8n ще ползва запомнените данни при следващите тестове и няма да вика API-то всеки път. Това работи само за разработка и само ако изходът не е двоичен файл. Ако искаш свежи данни — Unpin.

    ⚠️
    Версията на API-то
    Използваме /v1/: отговорът има обект rates, удобен за първи урок. Авторите на API-то са го обявили за остаряло в полза на /v2/, но казват, че v1 остава достъпно за неопределено време; v2 връща списък с друга форма. Ако някога смениш на v2, изразите по-долу трябва да се променят.
  9. Edit Fields: подреди ред за журнала

    Добави нод Edit Fields (Set) след HTTP Request. Режим Manual Mapping → добави поле с име logLine. Задръж курсора над стойността и избери Expression, после постави:

    израз · стойност на logLine
    {{ $now.toFormat('yyyy-MM-dd HH:mm') + ' | EUR/USD: ' + $json.rates.USD + ' | EUR/GBP: ' + $json.rates.GBP + '\n' }}

    Какво значи това. Каквото е в {{ }}, е JavaScript. $now е сегашният момент, .toFormat(…) го оформя като текст, $json са данните от предишния нод. '\n' в края е нов ред — без него следващият запис ще залепне към предишния. Натисни Execute step — полето logLine трябва да покаже един ред текст.

  10. Convert to File и запис на файла

    Нодът за запис работи с двоични данни (файл), а при нас има текст. Затова първо добави Convert to File → Operation: Convert to Text File → Text Input Field: logLine. После добави Read/Write Files from Disk → Operation: Write File to Disk:

    ПолеСтойност
    File Path and Name/home/node/.n8n-files/eur_rates_log.txt
    Input Binary Fieldполето с файла от предния нод — по подразбиране data (виж изхода на Convert to File и сложи същото име)
    Options → Appendвключено (дописва, не презаписва)
    ⚠️
    Защо точно тази папка
    От n8n 2.0 променливата N8N_RESTRICT_FILE_ACCESS_TO е по подразбиране ~/.n8n-files: файловите нодове могат да пишат само там. Пътят е вътре в контейнера, не на твоята машина. Файлът оцелява при рестарт на контейнера, но се губи при docker compose down — за трайно място на файловете трябва отделен том (отделна тема). Преди първото изпълнение подготви папката:
    bash
    docker compose exec n8n mkdir -p /home/node/.n8n-files

    ⚠️ Не сме проверили дали n8n сам създава тази папка — командата е безобидна и гарантира, че я има.

  11. Изпълни целия процес и провери

    Натисни Execute Workflow (или Ctrl/Cmd+Enter). Всеки нод трябва да стане зелен. Провери файла от терминала:

    bash
    docker compose exec n8n cat /home/node/.n8n-files/eur_rates_log.txt
    # Трябва да видиш нещо като:
    # 2026-10-01 14:32 | EUR/USD: 1.1355 | EUR/GBP: 0.85463

    Изпълни още веднъж — във файла трябва да се появи втори ред. Това показва, че „Append“ работи.

  12. Преименувай нодовете и дай име на процеса

    Добра практика: избери нод и натисни F2 (или десен бутон → Rename) и му дай описателно име, за да разбираш процеса след месеци:

    • Manual Trigger → „Ръчен старт“
    • HTTP Request → „Вземи курс EUR“
    • Edit Fields → „Подреди ред за журнала“
    • Convert to File → „Текст във файл“
    • Read/Write Files from Disk → „Запиши в журнала“

    Дай име и на самия процес, например „Курс EUR — дневен журнал“ (n8n го записва автоматично).

  13. Когато нещо се счупи: история на изпълненията

    Нарочно счупи процеса: в HTTP Request смени symbols=USD,GBP с symbols=XXX (несъществуваща валута). API-то отговаря с грешка 404, а нодът се проваля, защото успех за него е само отговор от клас 2xx. Изпълни процеса — нодът става червен. После отвори Executions горе, избери последното изпълнение (филтър Status → Failed) и виж кой нод е паднал и защо. Върни symbols=USD,GBP.

    По подразбиране n8n изчиства стари изпълнения след 336 часа (14 дни) или когато са над 10 000 — така базата не расте безкрайно.

  14. Всекидневни команди, копие и обновяване

    bash · от ~/n8n-lab
    docker compose up -d          # стартирай всичко
    docker compose ps             # състояние
    docker compose logs -f n8n    # логове на n8n (Ctrl+C за изход)
    docker compose restart n8n    # рестарт само на n8n
    docker compose down           # спри; данните остават в томовете

    Копие на данните. Две части: базата и ключът за криптиране (той е във .env — копирай и този файл на сигурно място).

    bash · копие
    mkdir -p backups
    docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB"' > backups/n8n-db-$(date +%Y%m%d).sql
    
    docker compose exec n8n n8n export:workflow --backup --output=/home/node/.n8n/backups/
    docker compose cp n8n:/home/node/.n8n/backups ./backups/workflows

    Обновяване. Сменяш числото N8N_VERSION в .env по текущите издания на n8n, после:

    bash
    docker compose pull
    docker compose up -d
    ⚠️
    Преди всяко обновяване — копие
    Прегледай бележките към изданията за несъвместими промени. Postgres не се надгражда със смяна на числото: скок между основни версии не отваря старите данни — първо pg_dump и официалният наръчник на PostgreSQL.
  15. Чести грешки

    ❌
    n8n не стартира — връзка към Postgres
    Healthcheck-ът на Postgres още не е минал. Изчакай половин минута, виж docker compose logs postgres | tail -20, после docker compose restart n8n. Ако си сменял потребителя или паролата във .env след първото пускане, базата пази старите — върни стойностите (docker compose down -v трие всички томове, само в тестова среда!).
    ❌
    Записът на файл дава грешка за достъп или за липсваща папка
    Пътят трябва да е в /home/node/.n8n-files/ (виж стъпката за запис) и папката да съществува. Пътят е в контейнера; n8n вижда само своята файлова система.
    ❌
    В полето излиза [object Object]
    Опитваш се да покажеш цял обект като текст. Вземи конкретното поле: {{ $json.rates.USD }}, не {{ $json.rates }}. Ако искаш целия обект като текст — {{ JSON.stringify($json.rates) }}.
    ❌
    localhost:5678 не се отваря
    Първо docker compose ps — работи ли контейнерът? После curl -sf http://localhost:5678/healthz. На Windows, ако работи в Ubuntu, но не в браузъра, в PowerShell пусни wsl --shutdown и стартирай Docker Desktop наново.
    🔐
    Не отваряй стека към интернет „така“
    Всичко е вързано към 127.0.0.1 нарочно. За достъп отвън ти трябват HTTPS, обратен прокси и отделна работа по сигурността.

04Проверка

Чеклист

Тест

1. Как се влиза в n8n 2.x за първи път?

2. Кой нод започва процес, който пускаш ръчно от редактора?

3. Защо записът на файл иска първо Convert to File?

4. Какво става, ако загубиш N8N_ENCRYPTION_KEY?

05Какво следва

06Източници

  1. n8n: инсталиране с Docker Compose — Compose v2, бележката за WSL, секцията за Postgres и PGDATA; още: n8n-hosting: Compose с Postgres.
  2. n8n 2.0: несъвместими промени — публикуване, достъп до файлове, премахнатият нод „Start“.
  3. Запазване и публикуване · Създаване и пускане на работни процеси · бързи клавиши · pin и тестови данни.
  4. Нодове: HTTP Request · Edit Fields (Set) · Convert to File · Read/Write Files from Disk.
  5. Променливи за средата: изпълнения · сигурност · часова зона; копия и възстановяване.
  6. n8n: справочник за изразите — $now, $json.
  7. n8n: издания в GitHub — текуща стабилна 2.41.4 към 01.10.2026.
  8. Frankfurter 🌐 глобален — публичното API за валутни курсове.