Установка n8n с Docker Compose на VPS

7 мин чтения·Matthieu|

Разверните n8n 2.x с Docker Compose и PostgreSQL на VPS. Готовая к продакшену конфигурация с фиксированными версиями, бэкапом ключа шифрования, health check и лимитами ресурсов.

Это руководство устанавливает n8n 2.12.3 с Docker Compose и PostgreSQL на VPS. Рабочий экземпляр n8n будет готов примерно за 15 минут. Конфигурация использует продакшен-настройки с самого начала: фиксированные версии образов, зашифрованные учетные данные, порт привязан только к localhost, health check на обоих контейнерах и лимиты ресурсов Docker. Reverse proxy и SSL здесь не рассматриваются. Это описано в .

Что нужно перед установкой n8n?

Нужен VPS на Debian 12 или Ubuntu 24.04 с минимум 4 ГБ оперативной памяти. Docker и Docker Compose (плагин docker compose, а не старый бинарник docker-compose) должны быть установлены. Если Docker ещё не настроен, сначала пройдите Docker Compose для мультисервисных VPS-деплоев.

Проверьте, что Docker Compose доступен:

docker compose version

Ожидаемый вывод:

Docker Compose version v2.x.x

Если команда выдает docker: 'compose' is not a docker command, у вас старый standalone-бинарник. Установите плагин Docker Compose из официального репозитория Docker.

Также нужен не-root пользователь с доступом sudo. Все команды в этом руководстве выполняются от имени этого пользователя, не от root.

Почему PostgreSQL, а не SQLite для n8n?

PostgreSQL обрабатывает конкурентные соединения, поддерживает WAL для восстановления после сбоев и работает с pg_dump для горячих бэкапов, пока n8n запущен. SQLite блокирует весь файл базы данных при каждой записи. При конкурентном выполнении вебхуков это вызывает таймауты и повреждение данных. Нельзя безопасно сделать бэкап базы SQLite, пока n8n работает, без риска получить повреждённую копию. Для всего, кроме локального тестирования, PostgreSQL — правильный выбор.

Свойство SQLite PostgreSQL
Конкурентная запись Блокировка на запись Полный MVCC
Горячие бэкапы Небезопасно при работе pg_dump в любой момент
Восстановление после сбоя Ручной replay журнала Автоматический WAL replay
Масштабирование Один процесс Пул соединений
Переменная окружения n8n DB_TYPE=sqlite DB_TYPE=postgresdb

Как установить n8n с Docker Compose на VPS?

Создай директорию проекта, напиши файл .env с секретами, напиши docker-compose.yml, запусти стек и убедись, что всё работает. Каждый шаг включает проверку.

Создание директории проекта

mkdir -p ~/n8n && cd ~/n8n

Создание файла .env

Все секреты хранятся в файле .env. Никогда не прописывай пароли или ключи напрямую в docker-compose.yml.

Сгенерируй надёжный пароль базы данных и ключ шифрования n8n:

echo "POSTGRES_PASSWORD=$(openssl rand -base64 32)" >> .env
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)" >> .env

Теперь добавь остальные переменные:

cat >> .env << 'EOF'
# PostgreSQL
POSTGRES_USER=n8n
POSTGRES_DB=n8n

# n8n
N8N_VERSION=2.12.3
N8N_HOST=localhost
N8N_PORT=5678
N8N_PROTOCOL=http
N8N_DIAGNOSTICS_ENABLED=false
GENERIC_TIMEZONE=UTC
EOF

Ограничь права доступа к файлу. Только твой пользователь должен иметь возможность его читать:

chmod 600 .env

Проверка:

ls -la .env

Ты должен увидеть -rw-------. Никто другой на сервере не сможет прочитать пароль базы данных или ключ шифрования.

Как сгенерировать и сохранить ключ шифрования n8n?

N8N_ENCRYPTION_KEY был сгенерирован выше командой openssl rand -hex 32. Это создаёт случайный ключ размером 32 байта (64 шестнадцатеричных символа). n8n использует этот ключ для шифрования всех сохранённых учётных данных: API-ключей, OAuth-токенов, паролей баз данных в рабочих процессах. Если потеряешь этот ключ, все сохранённые учётные данные станут навсегда нечитаемыми. Механизма восстановления нет.

Сделай бэкап ключа шифрования прямо сейчас. Скопируй его в менеджер паролей или оффлайн-хранилище:

grep N8N_ENCRYPTION_KEY .env

Сохрани вывод в безопасном месте за пределами этого сервера. Сделай это до того, как добавишь первые учётные данные в n8n.

Справочник переменных окружения

Переменная Назначение Пример значения
POSTGRES_USER Имя суперпользователя PostgreSQL n8n
POSTGRES_PASSWORD Пароль суперпользователя PostgreSQL (сгенерирован, 32+ символов)
POSTGRES_DB Имя базы данных n8n
N8N_VERSION Фиксированный тег образа n8n 2.12.3
N8N_ENCRYPTION_KEY Шифрует сохранённые учётные данные (сгенерирован, 64 hex-символа)
N8N_HOST Хост для интерфейса n8n localhost
N8N_PORT Порт для интерфейса n8n 5678
N8N_PROTOCOL HTTP или HTTPS http
N8N_DIAGNOSTICS_ENABLED Отправка телеметрии в n8n false
GENERIC_TIMEZONE Часовой пояс для cron-триггеров UTC

Написание docker-compose.yml

cat > docker-compose.yml << 'COMPOSE'
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: "1.0"
    security_opt:
      - no-new-privileges:true
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  n8n:
    image: docker.n8n.io/n8nio/n8n:${N8N_VERSION}
    restart: unless-stopped
    environment:
      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_HOST: ${N8N_HOST}
      N8N_PORT: ${N8N_PORT}
      N8N_PROTOCOL: ${N8N_PROTOCOL}
      N8N_DIAGNOSTICS_ENABLED: ${N8N_DIAGNOSTICS_ENABLED}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
    ports:
      - "127.0.0.1:5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://localhost:5678/healthz || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 30s
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: "2.0"
    security_opt:
      - no-new-privileges:true
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  postgres_data:
  n8n_data:
COMPOSE

Несколько моментов, на которые стоит обратить внимание:

Нет ключа version:. Docker Compose V2 его игнорирует. Все конкурирующие туториалы до сих пор пишут version: '3.7' или version: '3.8'. Спецификация Compose пометила это поле как устаревшее. Его наличие вызывает предупреждение в текущих версиях Docker.

Порт привязан к 127.0.0.1. Строка "127.0.0.1:5678:5678" ограничивает n8n только localhost. Это требование безопасности, а не предпочтение. Маппинг портов Docker полностью обходит iptables и правила UFW. Если написать 5678:5678 без префикса 127.0.0.1, n8n будет доступен из интернета, даже если фаервол блокирует порт 5678. Reverse proxy на той же машине будет перенаправлять трафик на localhost:5678 после настройки.

security_opt: no-new-privileges:true запрещает процессам внутри контейнера получать дополнительные привилегии через setuid- или setgid-бинарники. Это мера глубокой защиты от атак на выход из контейнера.

Ротация логов. Блок logging ограничивает JSON-лог каждого контейнера тремя файлами по 10 МБ (максимум 30 МБ на сервис). Без этого логи Docker растут, пока не заполнят диск. На VPS с ограниченным хранилищем это важно.

Health check на обоих сервисах. PostgreSQL использует pg_isready. n8n использует свой эндпоинт /healthz. Условие depends_on гарантирует, что n8n запустится только после того, как PostgreSQL пройдёт health check.

Лимиты ресурсов. PostgreSQL получает 512 МБ RAM и 1 CPU. n8n получает 2 ГБ RAM и 2 CPU. Эти значения хорошо работают на VPS с 4-8 ГБ. Корректируй под размер сервера и сложность рабочих процессов.

Именованные тома. И postgres_data, и n8n_data — это именованные тома, управляемые Docker. Docker автоматически управляет владением и правами внутри тома. Не нужно создавать директории на хосте или исправлять права вручную.

restart: unless-stopped вместо restart: always. Оба перезапускают контейнер после сбоя, но unless-stopped учитывает ручные команды docker compose stop. При restart: always вручную остановленный контейнер перезапустится, если Docker-демон перезагрузится (например, после обновления системы).

Запуск стека

cd ~/n8n
docker compose up -d

Следи за логами при первом запуске:

docker compose logs -f

Дождись, пока n8n выведет строку с n8n ready on. Нажми Ctrl+C, чтобы выйти из просмотра логов.

Проверка установки

Убедись, что оба контейнера запущены и здоровы:

docker compose ps

Ожидаемый вывод:

NAME       IMAGE                                  ...  STATUS                    PORTS
n8n-n8n-1       docker.n8n.io/n8nio/n8n:2.12.3   ...  Up X minutes (healthy)    127.0.0.1:5678->5678/tcp
n8n-postgres-1  postgres:16-alpine                ...  Up X minutes (healthy)

Обрати внимание: оба контейнера показывают (healthy) в колонке STATUS. Это подтверждает, что health check проходят. Если видишь (health: starting), подожди 30 секунд и проверь снова.

Протестируй API n8n с сервера:

curl -s http://localhost:5678/healthz

Ожидаемый вывод:

{"status":"ok"}

Убедись, что порт слушает только на localhost, а не на всех интерфейсах:

ss -tlnp | grep 5678

В выводе должно быть 127.0.0.1:5678. Если видишь 0.0.0.0:5678, привязка порта неправильная. Останови стек, исправь строку ports в docker-compose.yml и перезапусти.

Как создать аккаунт владельца n8n?

Открой SSH-туннель с локальной машины, чтобы получить доступ к n8n через браузер:

ssh -L 5678:127.0.0.1:5678 your-user@your-server-ip

Открой http://localhost:5678 в браузере. n8n покажет экран первоначальной настройки. Создай аккаунт владельца с надёжным паролем. Этот аккаунт имеет полный административный доступ к n8n.

После создания аккаунта закрой SSH-туннель. Не оставляй порт 5678 в туннеле дольше, чем нужно. Настрой reverse proxy с SSL для повседневного доступа. См. .

Как проверить, что n8n работает правильно?

После создания аккаунта и закрытия SSH-туннеля выполни последнюю серию проверок с сервера.

Проверь состояние контейнеров:

docker compose ps --format "table {{.Name}}\t{{.Status}}"

Оба сервиса должны показывать (healthy).

Проверь логи n8n на ошибки:

docker compose logs n8n --tail 20

Ищи строки ERROR. Чистый запуск показывает сообщения о миграции базы данных, а затем n8n ready on.

Проверь логи PostgreSQL:

docker compose logs postgres --tail 10

Должно быть database system is ready to accept connections.

Проверь использование диска Docker-томами:

docker system df -v | grep -E "n8n|postgres"

Это покажет, сколько места занимают n8n и PostgreSQL. Проверяй это периодически на VPS с ограниченным хранилищем.

Что-то пошло не так?

Контейнер сразу останавливается. Проверь логи командой docker compose logs n8n. Частые причины: отсутствует файл .env, неправильный пароль PostgreSQL, или ключ шифрования содержит спецсимволы, ломающие shell-подстановку. Перегенерируй .env, если нужно.

Ошибки прав доступа. Контейнер n8n работает от UID 1000. Если переключаешься с именованных томов на bind mount, убедись, что директория на хосте принадлежит UID 1000: sudo chown -R 1000:1000 ./n8n_data.

Health check не проходит. При первом запуске n8n нужно 20-30 секунд для выполнения миграций базы данных. Если health check не проходит, проверь docker compose logs n8n на ошибки миграции. Параметр start_period: 30s даёт n8n время до начала проверок.

Не удаётся подключиться к n8n. Порт привязан к localhost. Доступ с другой машины невозможен без SSH-туннеля или reverse proxy. Так и задумано.

Потерял ключ шифрования. Если N8N_ENCRYPTION_KEY утерян и в n8n сохранены учётные данные — они потеряны навсегда. Восстановление невозможно. Именно поэтому существует шаг резервного копирования.

Что делать после установки n8n?

Эта установка даёт рабочий экземпляр n8n, доступный только с самого сервера. Для продакшена нужны ещё три вещи:

  1. Reverse proxy с SSL. Настрой Nginx или Caddy перед n8n с TLS-сертификатом. Это даст HTTPS-доступ с доменным именем. См. .

  2. Бэкапы. Настрой автоматическое резервное копирование базы PostgreSQL и ключа шифрования n8n. См. .

  3. Обновления. Чтобы обновить n8n, измени N8N_VERSION в .env на новую версию и выполни docker compose up -d. Docker скачает новый образ и пересоздаст контейнер. Всегда читай заметки о релизе n8n перед обновлением.

Общее руководство по вариантам автоматизации рабочих процессов на VPS — см. .

Основы Docker Compose и управление несколькими сервисами — см. Docker Compose для мультисервисных VPS-деплоев.


Copyright 2026 Virtua.Cloud. Все права защищены.

Готовы попробовать?

Разверните свой сервер за секунды. Linux, Windows или FreeBSD.

Смотреть тарифы VPS