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

7 мин чтения·Matthieu·n8ndocker-composepostgresqlself-hostingworkflow-automation|

Разверните 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 с помощью reverse proxy Nginx, TLS и заголовков безопасности.

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

Нужен VPS на Debian 12 или Ubuntu 24.04 с минимум 4 ГБ оперативной памяти. Docker и Docker Compose (плагин docker compose, а не старый бинарник docker-compose) должны быть установлены. Если Docker ещё не настроен, сначала пройдите [-> docker-compose-multi-service-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 выведет строку с Editor is now accessible via:. Нажми 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 с помощью reverse proxy Nginx, TLS и заголовков безопасности.

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

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

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

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

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

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

docker compose logs n8n --tail 20

Ищи строки ERROR. Чистый запуск показывает сообщения о миграции базы данных, а затем Editor is now accessible via:.

Проверь логи 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-доступ с доменным именем. См. Защита n8n с помощью reverse proxy Nginx, TLS и заголовков безопасности.

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

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

Общее руководство по вариантам автоматизации рабочих процессов на VPS, см. Автоматизация рабочих процессов на VPS с n8n: самостоятельный хостинг.

Основы Docker Compose и управление несколькими сервисами, см. [-> docker-compose-multi-service-vps].