Три полных docker-compose-стека, уже отрендеренные и готовые к копированию: топология официального репозитория n8n-io/n8n-hosting (образ n8n:stable, Postgres 16, Redis 7), целевая версия — n8n 2.x. Берите тот, что подходит вашему серверу, или откройте его в конструкторе на шаге 2 — там каждое число (конкурентность, лимиты heap, размер пула) подгоняется под вашу реальную нагрузку. Все цифры на странице — из документации n8n, официального бенчмарка n8n или замеров сообщества; источник указан рядом с каждой.
Для лёгкой и средней автоматизации на небольшом VPS: один контейнер n8n на образе stable, Postgres 16 в роли базы (в n8n 2.x поддержку MySQL убрали; серверная БД — только Postgres) и Caddy с автоматическими TLS-сертификатами — по замерам сообщества (~860 МБ стек в простое плюс 40-50 МБ на каждое параллельное лёгкое выполнение) комфортный минимум для одного инстанса — около 2 ГБ. N8N_SECURE_COOKIE (классический фикс «не могу залогиниться за прокси») и N8N_PROXY_HOPS (корректные IP клиентов) уже прописаны. Если у вас десяток воркфлоу на расписаниях и вебхуках — это весь стек.
# n8n 2.x · SINGLE mode · sized for 300 runs/day (peak ≈10 concurrent)
# Generated by the n8n Server Sizing Calculator · topology follows n8n-io/n8n-hosting
name: n8n
services:
n8n:
image: docker.n8n.io/n8nio/n8n:stable
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678" # proxy handles the public side
env_file: .env
volumes:
- n8n_data:/home/node/.n8n
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" } # unrotated logs are the classic disk-killer
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=change-me
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
retries: 5
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" } # unrotated logs are the classic disk-killer
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" }
volumes:
n8n_data:
pg_data:
caddy_data:
caddy_config:
# Production hardening: move task runners to a sidecar (external mode) —
# n8n docs → Hosting → Configuration → Task runners (image: n8nio/runners:stable)
Полный стек queue-режима — основной инстанс, Redis, воркеры, обработчики вебхуков — на случай, когда постоянная параллельная нагрузка перерастает один инстанс. Он нужен, когда узкое место — конкурентность, а не скорость: в собственном бенчмарке n8n то же железо с 4 ГБ выросло с 15 до 72 req/s после смены режима, но загрузка бинарных файлов в queue-режиме стала только хуже и чисто отработала лишь на 32 ГБ — такие нагрузки лечит RAM, а не дополнительные воркеры. Две ловушки уже обезврежены в файле: N8N_CONCURRENCY_PRODUCTION_LIMIT в queue-режиме подменяет --concurrency каждого воркера (3 воркера с лимитом 10 = 30 параллельных), а DB_POSTGRESDB_POOL_SIZE поднят с дефолтных 2; OFFLOAD_MANUAL_EXECUTIONS_TO_WORKERS закомментирован (официальный шаблон его включает), чтобы ручные тестовые запуски оставались на основном инстансе, где их видно.
# n8n 2.x · QUEUE mode · main + 2 workers + Redis + Postgres
# Generated by the n8n Server Sizing Calculator · topology follows n8n-io/n8n-hosting
name: n8n
services:
n8n-main:
image: docker.n8n.io/n8nio/n8n:stable
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678" # proxy handles the public side
env_file: .env
volumes:
- n8n_data:/home/node/.n8n
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" } # unrotated logs are the classic disk-killer
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
n8n-worker:
image: docker.n8n.io/n8nio/n8n:stable
restart: unless-stopped
command: worker --concurrency=10
env_file: .env
deploy:
replicas: 2
volumes:
- n8n_data:/home/node/.n8n
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" } # unrotated logs are the classic disk-killer
depends_on:
- n8n-main
redis:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --maxmemory 128mb --maxmemory-policy noeviction
volumes:
- redis_data:/data
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" } # unrotated logs are the classic disk-killer
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
- POSTGRES_DB=n8n
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=change-me
volumes:
- pg_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n"]
interval: 10s
retries: 5
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" } # unrotated logs are the classic disk-killer
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
logging:
driver: json-file
options: { max-size: "10m", max-file: "3" }
volumes:
n8n_data:
redis_data:
pg_data:
caddy_data:
caddy_config:
# Notes:
# · every service shares one .env → same N8N_ENCRYPTION_KEY (mandatory in queue mode)
# · binary data in 2.x queue mode lives in Postgres (filesystem unsupported; S3 = Enterprise license)
# · scale workers: docker compose up -d --scale n8n-worker=3
Для AI-agent-воркфлоу — один инстанс на сервере с 8 ГБ: это подтверждённый сообществом минимум, серверы с 512 МБ падают на нодах AI Agent. GPU не нужен: вызовы моделей выполняются на API провайдера, так что единственная важная характеристика — RAM. В этом compose heap Node.js ограничен через NODE_OPTIONS=--max-old-space-size плюс N8N_RUNNERS_MAX_OLD_SPACE_SIZE на уровне ~50-75% RAM — слишком прожорливый воркфлоу падает предсказуемо, а не кладёт весь сервер.
Топология — как в примере 1; AI-специфика живёт в .env: лимиты heap и конкурентности ниже посчитаны под 8 ГБ.
# ── n8n 2.x · generated by n8n Server Sizing Calculator ── # Sized for: 300 runs/day · peak concurrency ≈10 · SINGLE mode # ── network ── N8N_HOST=n8n.example.com WEBHOOK_URL=https://n8n.example.com/ N8N_PROTOCOL=https N8N_PROXY_HOPS=1 # trust one reverse proxy in front (X-Forwarded-For) GENERIC_TIMEZONE=UTC N8N_ENCRYPTION_KEY=change-me-openssl-rand-hex-24 # ── execution history (drives DB size — 4,200 runs ≈ 1 GB) ── EXECUTIONS_DATA_PRUNE=true EXECUTIONS_DATA_MAX_AGE=336 EXECUTIONS_DATA_PRUNE_MAX_COUNT=10000 # High volume? Stop storing successful runs: # EXECUTIONS_DATA_SAVE_ON_SUCCESS=none # ── memory ── # Heap: Node's default old-space can lag your RAM — pin it to ~60% of the box NODE_OPTIONS=--max-old-space-size=4915 # 2.x: task runners are always on (N8N_RUNNERS_ENABLED is deprecated — don't set it). # For production, run runners as a sidecar (external mode) — see docs: hosting/configuration/task-runners N8N_RUNNERS_MAX_OLD_SPACE_SIZE=1229 # ── database ── DB_TYPE=postgresdb DB_POSTGRESDB_HOST=postgres DB_POSTGRESDB_DATABASE=n8n DB_POSTGRESDB_USER=n8n DB_POSTGRESDB_PASSWORD=change-me DB_POSTGRESDB_POOL_SIZE=12 # default is only 2 # ── single-mode guard against RAM storms ── N8N_CONCURRENCY_PRODUCTION_LIMIT=10
Эти три файла закрывают типовые случаи — под ваш конкретный откройте конструктор на шаге 2 и сгенерируйте compose и .env под ваши выполнения в день, конкурентность и RAM.
Собрать мой compose →| Переменная | Что делает |
|---|---|
| EXECUTIONS_MODE | regular (по умолчанию) или queue. Для queue нужны Redis и минимум один контейнер-воркер; режим умножает конкурентность, а не скорость отдельного запуска. |
| N8N_CONCURRENCY_PRODUCTION_LIMIT | Ограничивает число параллельных production-выполнений. Ловушка: в queue-режиме подменяет --concurrency каждого воркера — 3 воркера с лимитом 10 = 30 параллельных. Дефолт воркера 10; n8n рекомендует не ниже 5. |
| DB_POSTGRESDB_POOL_SIZE | Число соединений с Postgres на инстанс. По умолчанию 2 — для queue-режима мало; документация n8n советует поднять. |
| NODE_OPTIONS=--max-old-space-size | Потолок heap Node.js в МБ. Ставьте ~50-75% RAM контейнера — тогда нехватка памяти проявляется предсказуемо, а не случайными OOM-kill. |
| N8N_RUNNERS_MAX_OLD_SPACE_SIZE | Тот же потолок heap для task runners — в n8n 2.x они включены по умолчанию (N8N_RUNNERS_ENABLED объявлена устаревшей), так что без этой переменной лимит основного процесса — только полдела. |
| EXECUTIONS_DATA_MAX_AGE | Срок хранения выполнений: по умолчанию чистятся через 14 дней (при EXECUTIONS_DATA_PRUNE=true). При ~0.25 МБ на выполнение именно это держит диск в норме. |
| N8N_SECURE_COOKIE | Классический фикс «не пускает за прокси»: если TLS терминируется на прокси и n8n видит голый HTTP, auth-cookie не устанавливается. Не отключайте её вслепую на публичном сервере. |
| N8N_PROXY_HOPS | Число обратных прокси перед n8n. Должно совпадать с цепочкой (один Caddy = 1), иначе ломаются IP клиентов и rate limiting. |
| N8N_ENCRYPTION_KEY | Шифрует сохранённые креденшалы. Зафиксируйте в .env и сделайте бэкап — потеряете ключ, и все сохранённые доступы не восстановить. |
| WEBHOOK_URL | Публичный базовый URL для вебхуков. Без него n8n за прокси раздаёт внутренние адреса, до которых внешние сервисы не достучатся. |
Да — на этой странице их три, отрендеренные тем же генератором, что и наш конструктор, по топологии официального репозитория n8n-io/n8n-hosting (1.7k звёзд): минимальный одиночный стек с Postgres и Caddy, queue-режим с Redis и воркерами для постоянной параллельной нагрузки и AI-вариант с лимитами heap для серверов с 8 ГБ. Копируйте как есть.
Источник: n8n-io/n8n-hosting (официальный репозиторий)
Большинство инцидентов закрывают пять групп: конкурентность (N8N_CONCURRENCY_PRODUCTION_LIMIT — по документации n8n, в queue-режиме подменяет --concurrency каждого воркера, дефолт 10, итог = лимит × число воркеров), пул базы (DB_POSTGRESDB_POOL_SIZE по умолчанию 2 — для queue поднимайте), лимиты heap (NODE_OPTIONS на 50-75% RAM), настройки прокси (N8N_SECURE_COOKIE при неверной настройке ломает логин, N8N_PROXY_HOPS — IP клиентов) и 14-дневная очистка выполнений.
Источник: docs.n8n.io (справочник use-environment-variables; control-concurrency)
Почти нет. В собственном бенчмарке масштабируемости n8n переход одиночного режима с 4 ГБ на 32 ГБ дал лишь ~8% пропускной способности. А перевод той же машины с 4 ГБ в queue-режим поднял её с 15 до 72 req/s при 0% ошибок. Железо покупает запас конкурентности и работу с бинарными файлами, а не скорость — скорость даёт архитектура.
Источник: blog.n8n.io — бенчмарк масштабируемости n8n
Сначала посчитайте память, потом ограничьте конкурентность. По замерам сообщества Docker-стек в простое занимает около 860 МБ, каждое параллельное лёгкое выполнение добавляет примерно 40-50 МБ (тяжёлая работа с данными — 200-500 МБ). Выставьте N8N_CONCURRENCY_PRODUCTION_LIMIT по тому, что покрывает ваша RAM, ограничьте heap Node.js и переходите на queue-режим, когда постоянная параллельная нагрузка перерастает один инстанс.
Источник: Замеры памяти сообщества; бенчмарк масштабируемости n8n
Лучшего бренда нет — решает сайзинг. По замерам сообщества стек в простое занимает около 860 МБ плюс 40-50 МБ на каждое параллельное лёгкое выполнение, так что комфортный минимум для одного инстанса — примерно 2 ГБ; AI-agent-воркфлоу требуют 8 ГБ (подтверждено сообществом — серверы с 512 МБ падают на нодах AI Agent). GPU не даёт ничего: LLM-вызовы выполняются на API провайдера.
Источник: Отчёты сообщества n8n (замеры памяти; минимум RAM для AI Agent)
Немного, если настроить две вещи. Выполнение занимает в среднем ~0.25 МБ, и по умолчанию n8n удаляет их через 14 дней (EXECUTIONS_DATA_MAX_AGE, по документации n8n) — 1000 запусков в день дают примерно 3.5 ГБ в окне хранения. Настоящий убийца диска — неротируемые логи Docker: пропишите в compose json-file с max-size 10m и max-file 3.
Источник: docs.n8n.io (manage-execution-data); документация Docker по логированию