Перейти к содержанию

n8n за Nginx, Traefik и Cloudflare Tunnel: HTTPS, webhooks и OAuth без localhost

Обновлено: 2026-05-29

Открыть мой план

Reverse proxy для n8n нужен не ради “красивого домена”, а чтобы внешние сервисы стабильно доставляли webhook, OAuth-провайдеры видели правильный redirect URL, а пользователи открывали редактор по HTTPS. Если n8n внутри Docker слушает 5678, а наружу выходит домен на 443, нельзя оставлять n8n гадать адрес самому: задайте публичный URL явно.

Эта инструкция разбирает три практичных варианта: Nginx, Traefik и Cloudflare Tunnel. Для VPS с публичным IP чаще всего берут Nginx или Traefik. Для домашнего сервера, QNAP, Raspberry Pi или офиса без белого IP удобнее Cloudflare Tunnel, потому что cloudflared сам устанавливает исходящее соединение к Cloudflare.

Быстрый выбор: Nginx, Traefik или Cloudflare Tunnel

ВариантКогда выбиратьЧто важно проверить
NginxОдин VPS, понятный конфиг, ручной контрольproxy_set_header X-Forwarded-Proto https, размер body, timeout
TraefikНесколько Docker-сервисов и автоматический Let’s Encryptlabels, network, router/service, entrypoints
Cloudflare TunnelНет публичного IP или нужен доступ без открытых портовpublished hostname, Zero Trust policies, корректный service URL

Обязательные переменные n8n

Минимальный набор для домена https://n8n.example.ru:

N8N_HOST=n8n.example.ru
N8N_PROTOCOL=https
N8N_PORT=5678
WEBHOOK_URL=https://n8n.example.ru/
N8N_PROXY_HOPS=1
N8N_EDITOR_BASE_URL=https://n8n.example.ru/
GENERIC_TIMEZONE=Europe/Moscow

WEBHOOK_URL особенно важен для production webhook. Если он пустой или указывает на localhost, Telegram, Tilda, ЮKassa, amoCRM и Bitrix24 будут получать неправильный адрес. После изменения env перезапустите контейнеры и откройте любую Webhook node: production URL должен начинаться с публичного домена.

Nginx: минимальный конфиг для n8n

server {
    listen 80;
    server_name n8n.example.ru;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name n8n.example.ru;

    ssl_certificate     /etc/letsencrypt/live/n8n.example.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.example.ru/privkey.pem;

    client_max_body_size 50m;

    location / {
        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-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }
}

Если n8n работает в Docker-сети, вместо 127.0.0.1:5678 используйте имя сервиса и общую сеть. Для больших файлов поднимите client_max_body_size, но не делайте его безлимитным: лучше ограничить размер входящих файлов на уровне бизнес-процесса.

Traefik: Docker labels без отдельного nginx.conf

services:
  n8n:
    image: n8nio/n8n:latest
    env_file: .env
    networks: [web]
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`n8n.example.ru`)
      - traefik.http.routers.n8n.entrypoints=websecure
      - traefik.http.routers.n8n.tls.certresolver=letsencrypt
      - traefik.http.services.n8n.loadbalancer.server.port=5678

networks:
  web:
    external: true

Traefik удобен, когда на одном сервере живут n8n, Supabase, MinIO, NocoDB и другие сервисы. Но labels сложнее отлаживать, чем один nginx-конфиг. Если домен открывает 404 Traefik, сначала проверьте, что контейнер подключён к той же Docker network, что и Traefik.

Cloudflare Tunnel: когда сервер не должен принимать входящие порты

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    command: tunnel --no-autoupdate run --token ${CLOUDFLARE_TUNNEL_TOKEN}
    restart: unless-stopped

  n8n:
    image: n8nio/n8n:latest
    env_file: .env
    restart: unless-stopped

В Cloudflare Zero Trust добавьте published application: hostname n8n.example.ru, service http://n8n:5678 или http://localhost:5678 в зависимости от сети контейнеров. Для редактора n8n можно включить Cloudflare Access, но production webhook для внешних сервисов не должен требовать интерактивный login, иначе webhooks перестанут доходить.

Smoke-test после настройки

  1. Откройте https://n8n.example.ru в браузере, проверьте отсутствие mixed content.
  2. Создайте Webhook node с методом POST и скопируйте production URL.
  3. Активируйте workflow и отправьте тест:
curl -i -X POST https://n8n.example.ru/webhook/proxy-smoke-test \
  -H 'Content-Type: application/json' \
  -d '{"source":"curl","check":"reverse-proxy"}'
  1. Проверьте execution в n8n: должен быть виден входящий JSON.
  2. Откройте credentials OAuth-сервиса и убедитесь, что redirect URL начинается с публичного домена.

Типовые ошибки

СимптомВероятная причинаЧто сделать
Webhook URL содержит localhostне задан WEBHOOK_URLдобавить env, перезапустить n8n
OAuth redirect mismatchпровайдер видит другой домен/протоколпроверить N8N_EDITOR_BASE_URL, WEBHOOK_URL, callback в кабинете сервиса
413 Payload Too Largeproxy режет размер запросаподнять лимит body и ограничить бизнес-логикой
502 Bad Gatewayproxy не видит контейнер n8nпроверить Docker network, port 5678, health контейнера
504 Gateway Timeoutworkflow отвечает слишком долговернуть быстрый ответ через Respond to Webhook, долгую работу вынести после ответа

Связанные инструкции

Production-чеклист для reverse proxy

Используйте этот блок как быстрый контроль перед публикацией workflow или изменением существующей автоматизации. Он не заменяет staging, но помогает поймать самые частые отказы заранее.

  • Перед запуском: проверить HTTPS, X-Forwarded-* headers, body size, timeout и WEBHOOK_URL.
  • Минимальный тест: вызвать production webhook извне и сверить URL в execution data.
  • Типовой отказ: n8n генерирует внутренний localhost URL вместо публичного домена.
  • Что логировать: входной payload без секретов, статус внешнего API, branch ошибки, execution id и владельца процесса.

Критерий готовности: сценарий проходит успешный путь, ошибочный путь и повтор события без дублей, потери данных и неконтролируемого падения execution.

Операционный runbook для self-hosted

Для темы «n8n за Nginx, Traefik и Cloudflare Tunnel» важно разделять настройку и эксплуатацию. Настройка отвечает на вопрос “запустилось ли”, эксплуатация — “сможем ли мы восстановиться, обновиться и расследовать инцидент без потери credentials и execution history”.

Перед изменениями проверьте бэкап базы, значение N8N_ENCRYPTION_KEY, состояние volume, логи web-процесса и worker-процесса. Главный риск — случайно расширить права credentials, сохранить секреты в логах или отдать действие без approval.

СлойЧто зафиксироватьЗачем
Входpayload webhook/API с подписью, timestamp, event_id и исходным HTTP-статусомпозволяет повторить проблему без доступа к production-секретам
Контрольrestart_count, memory_usage, queue_depth, worker_concurrency, failed_executionsпоказывает деградацию раньше, чем пользователи начинают писать в поддержку
Безопасностьслучайно расширить права credentials, сохранить секреты в логах или отдать действие без approvalснижает риск скрытых дублей, утечки данных и неконтролируемых write-действий
Готовностьесть тест на happy path, пустой вход, повтор и сбой внешнего сервиса для «n8n за Nginx, Traefik и Cloudflare Tunnel»делает статью пригодной для runbook, а не только для чтения

Пример безопасного входного контракта

docker compose ps
docker compose logs --tail=200 n8n
docker compose logs --tail=200 n8n-worker
printenv | grep -E 'N8N_|WEBHOOK_|DB_|QUEUE_'
# перед изменениями: backup базы + проверка N8N_ENCRYPTION_KEY

Критерий готовности

  • есть свежий backup базы и проверено значение N8N_ENCRYPTION_KEY
  • web, worker, queue и database используют согласованные переменные окружения
  • после изменения проверены логи, healthcheck и запуск критичных workflow
  • записан rollback-план с командами и ответственным