Удельта

Пошаговая инструкция · Самостоятельная установка

Как установить n8n на Ubuntu: PostgreSQL, HTTPS и рабочие сценарии

Пошаговая инструкция для самостоятельной установки. Установим n8n понятными шагами: отдельно подготовим секреты, запустим приложение, создадим владельца и проверим webhook. Затем проверим исполнитель кода и сохраним комплект резервной копии.

Первый workflow автоматизации: события, обработка и результат соединены в последовательность с контролем доступа

Что понадобится #

Установим n8n 2.42.3, PostgreSQL 17 и отдельный task runner — исполнитель JavaScript/Python из узла Code. Это один сервер без распределённой очереди. ИИ-помощник и его отдельная инфраструктура для первого webhook не нужны.

Подготовьте Ubuntu 26.04 LTS, Docker Engine, Compose v2 и Nginx по общей инструкции. Команды здесь выполняются в SSH-терминале сервера от пользователя с sudo. При ошибке остановитесь и проверьте её причину в разделе диагностики. В браузере будете работать со своего компьютера.

Создайте A-запись своего домена на IP сервера. Заменяйте automation.example.com вашим доменом во всех файлах и командах. До создания владельца ограничьте внешний TCP 443 своим IP в firewall провайдера; TCP 80 оставьте доступным для сертификата. Порты 5678, 5679 и 5432 наружу не открывайте. Подготовьте SMTP-реквизиты и отдельное место для копий.

Настройка внешнего доступа использует обратный прокси Nginx и Certbot для Nginx. Приложение остаётся доступным на локальном порту; снаружи открыт его HTTPS-домен.

Шаг 1. Создайте каталог данных #

n8n_data хранит файлы экземпляра даже при внешней PostgreSQL. Образ n8n работает с UID 1000, поэтому назначим каталогу этого владельца. Следующие команды выполняйте из ~/services/n8n.

Подготовить постоянные файлы
mkdir -p ~/services/n8n/n8n_data
cd ~/services/n8n
sudo chown 1000:1000 n8n_data

Каталог создан без ошибки. При новом входе по SSH сначала выполните cd ~/services/n8n.

Шаг 2. Создайте три разных секрета #

Пароль базы, ключ шифрования подключений и токен runner выполняют разные задачи. Сохраним случайные значения в .env; запускайте эту команду только на новой установке.

Сохранить секреты
umask 077
printf 'POSTGRES_PASSWORD=%s\nN8N_ENCRYPTION_KEY=%s\nN8N_RUNNERS_AUTH_TOKEN=%s\n' "$(openssl rand -hex 24)" "$(openssl rand -hex 32)" "$(openssl rand -hex 32)" > .env
chmod 600 .env

В .env заполнены три параметра. Не публикуйте файл; потеря исходного N8N_ENCRYPTION_KEY мешает восстановить подключения.

Шаг 3. Укажите публичный адрес #

Откройте nano .env и добавьте строки ниже после секретов. Замените домен своим. Europe/Moscow — пример часового пояса; выберите свой. WEBHOOK_URL формирует адреса для внешних вызовов, N8N_PROXY_HOPS=1 соответствует одному прокси Nginx.

Публичные параметры для .env
N8N_HOST=automation.example.com
N8N_PROTOCOL=https
N8N_EDITOR_BASE_URL=https://automation.example.com/
WEBHOOK_URL=https://automation.example.com/
N8N_PROXY_HOPS=1
GENERIC_TIMEZONE=Europe/Moscow
TZ=Europe/Moscow

В nano сохраните Ctrl+O, Enter, Ctrl+X. Публичные адреса используют https и настоящий домен, а секреты сохранились.

Шаг 4. Создайте файл запуска #

Выполните nano compose.yaml и вставьте файл ниже. PostgreSQL хранит данные в pgdata; runner получает отдельный токен и выполняет код вне основного контейнера. Версии n8n и runners должны совпадать.

compose.yaml
services:
  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set database password}
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U n8n -d n8n']
      interval: 10s
      timeout: 5s
      retries: 10
  n8n:
    image: n8nio/n8n:2.42.3
    restart: unless-stopped
    env_file: .env
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}
      N8N_RUNNERS_MODE: external
      N8N_RUNNERS_BROKER_LISTEN_ADDRESS: 0.0.0.0
    ports:
      - '127.0.0.1:5678:5678'
    volumes:
      - ./n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
  runners:
    image: n8nio/runners:2.42.3
    restart: unless-stopped
    environment:
      N8N_RUNNERS_AUTH_TOKEN: ${N8N_RUNNERS_AUTH_TOKEN}
      N8N_RUNNERS_TASK_BROKER_URI: http://n8n:5679
    depends_on:
      - n8n
volumes:
  pgdata:

Сохраните Ctrl+O, Enter, Ctrl+X. Внешний доступ есть только к локальному 5678 через Nginx; порт брокера runner не опубликован.

Шаг 5. Проверьте Compose #

Проверка помогает обнаружить ошибки YAML и пустые переменные до первого запуска.

Проверить настройки
docker compose config --quiet

При успехе нет вывода. Если есть ошибка, исправьте файл и повторите проверку.

Шаг 6. Скачайте образы #

Docker загрузит готовое приложение, исполнителя и PostgreSQL выбранных версий.

Загрузить образы
docker compose pull

Загрузка завершилась без ошибок для трёх сервисов.

Шаг 7. Запустите сервисы #

При первом запуске база создаёт своё хранилище, затем n8n готовит таблицы. -d оставляет процессы работать в фоне.

Запустить n8n
docker compose up -d

Контейнеры созданы. Дайте первому запуску минуту, затем проверяйте приложение.

Шаг 8. Проверьте локальный ответ #

Проверим n8n без домена и сертификата, чтобы возможную ошибку искать в правильной части установки.

Проверить здоровье n8n
curl --fail http://127.0.0.1:5678/healthz

Запрос завершился без ошибки HTTP. Если сервис ещё запускается, подождите и повторите; при постоянной ошибке смотрите журналы n8n и postgres.

Шаг 9. Сохраните сайт Nginx #

Установите Nginx и Certbot по подготовке Ubuntu, если ещё не установили. Откройте sudo nano /etc/nginx/sites-available/n8n и вставьте файл ниже. Замените все домены своими. Nginx передаёт приложению домен, адрес клиента и протокол; Upgrade и Connection сохраняют WebSocket. До получения сертификата условие $scheme блокирует обычные HTTP-запросы кодом 403, чтобы вход не происходил без шифрования. В этой схеме один внешний прокси, поэтому N8N_PROXY_HOPS=1 сохраняется.

Файл /etc/nginx/sites-available/n8n
map $http_upgrade $n8n_connection_upgrade {
    default upgrade;
    "" close;
}

server {
    listen 80;
    server_name automation.example.com;
    client_max_body_size 100m;
    location / {
        if ($scheme = http) { return 403; }
        proxy_pass http://127.0.0.1:5678;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $n8n_connection_upgrade;
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }
}

Сохраните Ctrl+O, Enter, Ctrl+X. В файле пока нет путей к сертификатам: Nginx сможет проверить его до выпуска HTTPS.

Шаг 10. Подключите сайт и проверьте HTTP #

Ссылка подключает сохранённый сайт. nginx -t проверяет все настройки сервера; && разрешает перечитать их только при успешной проверке. curl проверяет ответ для вашего домена. При ошибке остановитесь, исправьте указанную строку и повторите проверку.

Подключите сайт и проверьте HTTP
sudo ln -sfn /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/n8n
sudo nginx -t && sudo systemctl reload nginx
curl -I http://automation.example.com/

Ожидается successful от nginx -t и HTTP 403 для обычного запроса: до HTTPS это намеренная блокировка. DNS должен указывать на сервер, TCP 80/443 — быть доступен у провайдера. Ничего не вводите в форму входа по HTTP.

Шаг 11. Получите сертификат и включите HTTPS #

Каждое имя из команды должно указывать на этот сервер. Certbot проверит домены, сам добавит сертификат в сайт Nginx и включит перенаправление HTTP → HTTPS. Укажите свою почту при запросе и подтвердите условия Let’s Encrypt. Это отдельное действие после успешной проверки HTTP.

Получите сертификат и включите HTTPS
sudo /snap/bin/certbot --nginx -d automation.example.com --redirect

Certbot сообщил об успешной установке. Откройте HTTPS-адрес со своего компьютера: браузер не должен предупреждать о сертификате. Для закрытой панели используйте разрешённый IP. При ошибке исправьте DNS, в том числе AAAA, либо доступ к TCP 80; не повторяйте запросы выпуска подряд.

Шаг 12. Проверьте продление сертификата #

Certbot из snap создаёт службу автоматического продления. Dry-run выполняет пробное продление: настоящие сертификаты не заменяются. Затем проверьте, что таймер планирует следующий запуск. Сохраняйте доступ к TCP 80 для следующих проверок домена.

Проверьте продление сертификата
sudo /snap/bin/certbot renew --dry-run
systemctl list-timers --all 'snap.certbot.renew*'

Пробное продление успешно, у таймера есть следующий запуск. Если тест не прошёл, проверьте /var/log/letsencrypt/letsencrypt.log; сначала исправьте причину. После этого можно создавать учётную запись и приглашать пользователей.

Шаг 13. Создайте владельца экземпляра #

В браузере заполните первое приглашение создать владельца: личная почта и отдельный длинный пароль. В настройках безопасности включите двухфакторный вход и сохраните коды восстановления.

Вы вошли в редактор от своего имени. После этого можно снять временное ограничение 443: вебхуки должны быть доступны вызывающим системам. Встроенную авторизацию не отключайте.

Шаг 14. Подключите почту для восстановления #

В SSH откройте nano .env. Добавьте N8N_EMAIL_MODE=smtp и заполните N8N_SMTP_HOST, N8N_SMTP_PORT, N8N_SMTP_USER, N8N_SMTP_PASS, N8N_SMTP_SENDER данными своего почтового сервиса. Каждый параметр пишите с новой строки. TLS-настройки выбирайте по требованиям провайдера.

Второй блок — шаблон строк для .env. Замените smtp.example.com, your-login, your-smtp-password и sender@example.com настоящими реквизитами. Порт 587 — пример: используйте порт и режим TLS вашего провайдера. Не оставляйте значения примера.

Заполнить параметры SMTP
nano .env
Шаблон SMTP-параметров для .env
N8N_EMAIL_MODE=smtp
N8N_SMTP_HOST=smtp.example.com
N8N_SMTP_PORT=587
N8N_SMTP_USER=your-login
N8N_SMTP_PASS=your-smtp-password
N8N_SMTP_SENDER=sender@example.com

Сохраните Ctrl+O, Enter, Ctrl+X. Отправитель — ваш разрешённый почтовый адрес, пароль не попал в историю команд.

Шаг 15. Примените почтовые настройки #

Пересоздание n8n перечитает .env; база и runner не требуют удаления.

Применить .env
docker compose up -d --force-recreate n8n

Панель вернулась. Проверьте письмо восстановления пароля или приглашение на свой адрес; ссылка должна вести на ваш HTTPS-домен.

Шаг 16. Создайте проверочный webhook #

В браузере создайте workflow из Webhook и Respond to Webhook. Webhook — адрес, на который другая система отправит событие. Выберите POST, путь installation-check и режим ответа через Respond to Webhook; в последнем задайте узнаваемый текст. В Webhook выберите Basic Auth, создайте credential webhook-reader и отдельный пароль.

Сценарий соединяет оба узла, реквизиты webhook сохранены в credential. Пока вызывайте только Test URL при включённом ожидании теста.

Шаг 17. Проверьте тестовый адрес #

Запустите ожидание в Webhook и скопируйте его Test URL. В SSH выполните команду ниже, заменив URL_FROM_EDITOR целым адресом из редактора. curl запросит пароль webhook-reader: при вводе он не отображается.

Вызвать Test URL из редактора
curl --fail --user webhook-reader --request POST --header 'Content-Type: application/json' --data '{"event":"installation-check","value":1}' 'URL_FROM_EDITOR'

Редактор получил вымышленное событие, а curl показал заданный ответ. При 404 проверьте, что Webhook ещё ждёт тестовый запрос.

Шаг 18. Опубликуйте и проверьте постоянный адрес #

Сохраните и опубликуйте workflow. Production URL работает без ожидания теста. Ниже используется ваш домен; пароль вводится по запросу curl.

Вызвать Production URL
curl --fail --user webhook-reader --request POST --header 'Content-Type: application/json' --data '{"event":"installation-check","value":1}' https://automation.example.com/webhook/installation-check

Ответ пришёл без режима ожидания в редакторе, выполнение появилось в истории. Если URL содержит localhost, исправьте WEBHOOK_URL, затем пересоздайте n8n.

Шаг 19. Проверьте внешний исполнитель кода #

Чтобы проверить runner отдельно от webhook, создайте тестовый workflow с Manual Trigger и Code. В JavaScript-режиме Code вставьте строку ниже и запустите узел. Это безвредный пример, который возвращает одну запись.

Код для узла Code
return [{ json: { installation: 'ok' } }];

Вывод узла содержит installation: ok. При ожидании или ошибке соединения проверьте журнал runners, совпадение токена и версий образов.

Шаг 20. Подготовьте копию #

Выключите проверочный workflow и дождитесь завершения активных запусков. В SSH создайте отдельный каталог каждой копии; следующие два шага выполняйте в той же сессии.

Создать каталог копии
umask 077
n8n_backup="$HOME/backups/n8n/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$n8n_backup"

Каталог создан. Время остановки согласуйте с владельцами интеграций: запросы в этот период не обработаются.

Шаг 21. Скопируйте базу #

Остановите n8n и runner, затем выгрузите PostgreSQL. Так во время копирования приложение не добавляет новые записи.

Остановить записи и создать дамп
docker compose stop n8n runners
docker compose exec -T postgres pg_dump -U n8n -d n8n -Fc > "$n8n_backup/database.dump"

pg_dump завершился без ошибки и дамп не пуст. База продолжает работать, панель временно недоступна.

Шаг 22. Сохраните файлы и верните n8n #

Файлы, .env с ключом шифрования и Compose нужны вместе с базой. sudo позволяет прочитать каталог, принадлежащий UID 1000.

Сохранить файлы и возобновить работу
sudo tar -czf "$n8n_backup/files.tar.gz" .env compose.yaml n8n_data
docker compose start n8n runners

Панель и тест Code работают. Перенесите защищённую копию вне сервера. На отдельной установке того же тега проверьте восстановление базы, файлов и исходного ключа с выключенными рабочими workflow.

Если шаг не работает и как обновлять #

Из ~/services/n8n проверьте docker compose ps и docker compose logs --tail=100 n8n runners postgres. Если интерфейс работает, а Code нет, сверяйте версию runners, токен и http://n8n:5679. Ошибка прав на n8n_data требует проверки владельца 1000:1000. Изменение POSTGRES_PASSWORD в .env не меняет пароль уже созданной базы.

Перед обновлением испытайте копию и новый стабильный тег на отдельном сервере. Меняйте версии n8n и runners одновременно. После запуска проверьте вход, Code и production webhook. Если новая версия мигрировала базу, откат требует прежнего образа, прежнего дампа и согласованных файлов. Экспорт workflow в JSON помогает переносу, но не заменяет полную копию.

Настройки внешнего доступа храните вместе с копией приложения: /etc/nginx/sites-available/n8n и /etc/letsencrypt содержат сайт и сертификаты с закрытыми ключами. Архивируйте их с sudo в закрытое хранилище. После восстановления подключите сайт через sites-enabled, выполните sudo nginx -t, затем перечитайте Nginx. Для ошибки 502 сначала проверьте локальное приложение и /var/log/nginx/error.log; для сертификата — /var/log/letsencrypt/letsencrypt.log и таймер продления.

Обсудить установку и настройку

Материал был полезен?

Сообщить об ошибке или задать вопрос редакции

Сообщение увидит редакция. Не указывайте пароли и личные данные. Текст удаляется через 180 дней.

О материале

ИнфраструктураРуководствоЗадача: установитьУровень: практикаn8n

Последнее обновление:

Обсуждение

Комментарии проходят подтверждение адреса и проверку редакцией.