// DevOps

Устанавливаем n8n на FastPanel с Docker Compose: Понятное руководство

Опубликовано 22.09.2026

В этом руководстве ставим n8n на сервер с панелью FastPanel через Docker Compose. Сам n8n работает в контейнерах вместе с PostgreSQL, Redis и отдельным воркером, а FastPanel отвечает за домен, сертификат и обратный прокси. Конфигурация повторяет официальный пример n8n withPostgresAndWorker из репозитория n8n-hosting — с поправками под FastPanel. Установка без панели, за HAProxy, описана в статье «Устанавливаем n8n в Docker с HAProxy».

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

  • Сервер с установленной FastPanel и Docker с плагином docker compose.
  • Домен или поддомен для n8n, например n8n.example.com, с A-записью на сервер.
  • Доступ по SSH.

Воркер и Redis нужны, когда процессов много и они долгие: основной процесс n8n принимает веб-хуки и показывает редактор, а выполнение уходит воркерам. Для небольшой установки хватит одного контейнера n8n с PostgreSQL. Как устроен режим очереди, разобрано в статье «n8n: Часть 5 — Масштабирование».


Шаг 1: Подготовка сервера

bash
sudo mkdir -p /opt/n8n_stack
cd /opt/n8n_stack

Шаг 2: Файлы конфигурации

Понадобятся три файла: docker-compose.yml, .env и init-data.sh.

2.1. .env

env
N8N_VERSION=2.40.5
N8N_DOMAIN=n8n.example.com

# администратор PostgreSQL
POSTGRES_USER=postgres_admin
POSTGRES_PASSWORD=замените-на-длинный-пароль
POSTGRES_DB=n8n

# отдельный пользователь базы для n8n
POSTGRES_NON_ROOT_USER=n8n_user
POSTGRES_NON_ROOT_PASSWORD=замените-на-другой-пароль

# openssl rand -hex 32 — для каждого из двух ключей
ENCRYPTION_KEY=замените
RUNNERS_AUTH_TOKEN=замените

ENCRYPTION_KEY шифрует учётные данные (credentials) в базе n8n. Сгенерируйте его один раз и храните отдельно от сервера: без него резервная копия базы бесполезна. RUNNERS_AUTH_TOKEN — общий секрет n8n и контейнеров task runners, которые выполняют код узла Code.

2.2. docker-compose.yml

Строка version: в начале файла не нужна: современный Docker Compose её игнорирует.

yaml
volumes:
  db_storage:
  n8n_storage:
  redis_storage:

x-shared: &shared
  restart: always
  image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
  environment:
    - DB_TYPE=postgresdb
    - DB_POSTGRESDB_HOST=postgres
    - DB_POSTGRESDB_PORT=5432
    - DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
    - DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
    - DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
    - EXECUTIONS_MODE=queue
    - QUEUE_BULL_REDIS_HOST=redis
    - QUEUE_HEALTH_CHECK_ACTIVE=true
    - N8N_ENCRYPTION_KEY=${ENCRYPTION_KEY}
    - N8N_RUNNERS_MODE=external
    - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
    - N8N_RUNNERS_BROKER_LISTEN_ADDRESS=0.0.0.0
    - OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS=true
    - N8N_HOST=${N8N_DOMAIN}
    - N8N_PROTOCOL=https
    - WEBHOOK_URL=https://${N8N_DOMAIN}/
    - N8N_PROXY_HOPS=1
    - GENERIC_TIMEZONE=Europe/Moscow
    - TZ=Europe/Moscow
  volumes:
    - n8n_storage:/home/node/.n8n
  depends_on:
    redis:
      condition: service_healthy
    postgres:
      condition: service_healthy

x-runner: &runner
  restart: always
  image: n8nio/runners:${N8N_VERSION}

services:
  postgres:
    image: postgres:18
    restart: always
    environment:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - POSTGRES_DB
      - POSTGRES_NON_ROOT_USER
      - POSTGRES_NON_ROOT_PASSWORD
      - PGDATA=/var/lib/postgresql/data
    volumes:
      - db_storage:/var/lib/postgresql/data
      - ./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -h localhost -U ${POSTGRES_USER} -d ${POSTGRES_DB}']
      interval: 5s
      timeout: 5s
      retries: 10

  redis:
    image: redis:7-alpine
    restart: always
    volumes:
      - redis_storage:/data
    healthcheck:
      test: ['CMD', 'redis-cli', 'ping']
      interval: 5s
      timeout: 5s
      retries: 10

  n8n:
    <<: *shared
    ports:
      - "127.0.0.1:5678:5678"   # наружу n8n публикует FastPanel

  n8n-runner:
    <<: *runner
    environment:
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
      - N8N_RUNNERS_TASK_BROKER_URI=http://n8n:5679
    depends_on:
      - n8n

  n8n-worker:
    <<: *shared
    command: worker
    depends_on:
      - n8n

  n8n-worker-runner:
    <<: *runner
    environment:
      - N8N_RUNNERS_AUTH_TOKEN=${RUNNERS_AUTH_TOKEN}
      - N8N_RUNNERS_TASK_BROKER_URI=http://n8n-worker:5679
    depends_on:
      - n8n-worker

Что изменилось по сравнению со старыми инструкциями:

  • Версии. Образ n8n ветки 2.x вместо 1.91, PostgreSQL 18 вместо 11 — поддержка PostgreSQL 11 закончилась в 2023 году, а 18-я поддерживается до ноября 2030 года. Строка PGDATA нужна, чтобы Postgres 18 хранил данные в подключённом томе. Если у вас уже работает старая версия, просто поменять тег нельзя: сначала pg_dumpall, затем восстановление в новую версию.
  • Режим очереди включается явно: EXECUTIONS_MODE=queue и QUEUE_BULL_REDIS_HOST=redis. Без этих строк воркер не получает задач, а Redis простаивает.
  • Task runners. С n8n 2.0 код узла Code выполняется в отдельных контейнерах n8nio/runners: у основного процесса и у каждого воркера — свой.
  • Своего healthcheck.js больше нет: у n8n есть встроенная проверка /healthz, а у воркера она включается переменной QUEUE_HEALTH_CHECK_ACTIVE=true.

2.3. init-data.sh

Скрипт выполняется один раз при первом запуске PostgreSQL и создаёт отдельного пользователя для n8n:

bash
#!/bin/bash
set -e;

if [ -n "${POSTGRES_NON_ROOT_USER:-}" ] && [ -n "${POSTGRES_NON_ROOT_PASSWORD:-}" ]; then
	psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
		CREATE USER ${POSTGRES_NON_ROOT_USER} WITH PASSWORD '${POSTGRES_NON_ROOT_PASSWORD}';
		GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_NON_ROOT_USER};
		GRANT CREATE ON SCHEMA public TO ${POSTGRES_NON_ROOT_USER};
	EOSQL
else
	echo "SETUP INFO: No Environment variables given!"
fi
bash
chmod +x init-data.sh

Строка GRANT CREATE ON SCHEMA public обязательна: начиная с PostgreSQL 15 обычный пользователь не может создавать таблицы в схеме public без явного разрешения.


Шаг 3: Запуск

bash
cd /opt/n8n_stack
docker compose up -d
docker compose ps

Все сервисы должны перейти в состояние running, а postgres и redis — в healthy. Проверить сам n8n можно так:

bash
curl -sf http://127.0.0.1:5678/healthz && echo OK

Шаг 4: Настройка FastPanel

  1. В FastPanel откройте Сайты → Добавить сайт и укажите домен из .env.
  2. В настройках сайта включите обратный прокси на адрес http://127.0.0.1:5678.
  3. Выпустите сертификат Let’s Encrypt для домена и включите перенаправление с HTTP на HTTPS.
  4. Добавьте поддержку WebSocket — редактор n8n держит постоянное соединение с сервером. Если панель не добавила её сама, пропишите в дополнительных директивах nginx для этого прокси:
nginx
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;

Подробнее о возможностях панели — в статье «Панели управления хостингом: Часть 4 — FASTPANEL».


Шаг 5: Первый вход

Откройте https://n8n.example.com. n8n предложит создать учётную запись владельца — сделайте это сразу, пока адрес не нашли посторонние. Логина и пароля в переменных окружения больше нет: поддержку basic auth убрали в n8n 1.0.

После входа проверьте узел Webhook: адрес веб-хука должен начинаться с https://n8n.example.com/.

Резервное копирование и обновление

  • Копировать: дамп базы (docker compose exec postgres pg_dump -U postgres_admin n8n > n8n.sql), том n8n_storage и ключ шифрования из .env.
  • Обновлять: сделайте копию, поменяйте N8N_VERSION в .env на новую версию и выполните docker compose pull && docker compose up -d. Основной процесс, воркеры и runners должны работать на одной версии.

// Reviews

Отзывы по теме

// Contact

Нужна помощь?

Свяжись со мной и я помогу решить проблему

Написать в Telegram

Отвечаю в течение рабочего дня (03:00–13:00 GMT)

Или оставьте заявку здесь:

Подтвердите, что вы не бот.

Написать и получить быстрый ответ