n8n HTTPS, reverse proxy и WEBHOOK_URL: настройка без localhost в ссылках ¶
Обновлено: 2026-05-29
Если n8n работает в Docker за nginx, Caddy, Traefik или Cloudflare Tunnel, он может не знать свой публичный адрес. Внутри контейнера приложение видит порт 5678, а пользователи и внешние сервисы заходят на https://n8n.example.ru. Из-за этого в Webhook node, Telegram, OAuth и callback URL иногда появляются localhost, внутренний порт или неправильный протокол.
Главная переменная здесь — WEBHOOK_URL. Она говорит n8n, какой публичный адрес использовать для production webhooks и внешних callback-сценариев. Если её не задать, n8n собирает URL из протокола, host и порта, что за reverse proxy часто даёт неправильный результат.
Симптомы неправильного публичного URL
| Симптом | Вероятная причина | Где искать |
|---|---|---|
| Webhook URL показывает localhost | n8n не знает внешний домен | WEBHOOK_URL, N8N_HOST |
| Telegram не шлёт события | у бота зарегистрирован неправильный production URL | Bot API, активность workflow |
| OAuth redirect ведёт на http или внутренний порт | не настроен proxy/host | credentials, callback URL, headers proxy |
| ошибка secure cookie | HTTPS снаружи, HTTP внутри, не учтён proxy | cookie/proxy settings |
| Test URL работает, Production URL нет | workflow не активирован или внешний URL неверный | Webhooks, executions, activation |
Минимальный набор переменных
Для типовой Docker-сборки за reverse proxy используйте публичный домен в WEBHOOK_URL и настройте доверие к proxy. Значения ниже — пример, домен замените на свой.
WEBHOOK_URL=https://n8n.example.ru/
N8N_HOST=n8n.example.ru
N8N_PROTOCOL=https
N8N_PORT=5678
N8N_PROXY_HOPS=1
N8N_SECURE_COOKIE=true
Если перед n8n несколько proxy-слоёв, например Cloudflare → Caddy → n8n, число proxy hops может отличаться. Не ставьте случайные значения: сначала нарисуйте путь запроса и поймите, кто последний передаёт headers в n8n.
Какие headers должен передавать reverse proxy
Последний proxy перед n8n должен передавать исходный host, протокол и IP. Иначе приложение видит внутренний HTTP-запрос и строит ссылки неверно.
X-Forwarded-For: $proxy_add_x_forwarded_for
X-Forwarded-Host: $host
X-Forwarded-Proto: https
X-Real-IP: $remote_addrДля Caddy и Traefik часть этой логики обычно закрывается автоматически, но всё равно проверьте итоговый URL внутри n8n UI и реальный POST на production webhook.
Test URL и Production URL
В n8n важно не путать тестовый и production webhook. Test URL работает, пока вы слушаете запуск в редакторе. Production URL рассчитан на активный workflow. Для Telegram, ЮKassa, Tilda, amoCRM и других внешних сервисов почти всегда нужен production URL.
| URL | Когда использовать | Типовая ошибка |
|---|---|---|
| Test URL | разовая проверка в редакторе | оставить его в внешнем сервисе |
| Production URL | реальная интеграция | workflow не активирован |
| OAuth callback | credentials Google, Slack, CRM | скопирован до настройки домена |
Порядок диагностики
- Откройте Webhook node и посмотрите, какой production URL показывает n8n.
- Сравните его с доменом, который доступен из интернета.
- Отправьте
curl -X POST https://ваш-домен/webhook/...и проверьте executions. - Проверьте, активирован ли workflow.
- Проверьте reverse proxy headers и переменную
WEBHOOK_URL. - Перезапустите контейнер n8n после изменения env.
- Если речь об OAuth, пересоздайте или обновите credential callback в стороннем сервисе.
Фрагмент nginx-конфига
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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 X-Forwarded-Host $host;
}Этот фрагмент не заменяет полноценный конфиг SSL, firewall и Docker-сети, но показывает главную идею: n8n должен получать внешний host и протокол.
Частые ошибки
- Задали
WEBHOOK_URLбез завершающего слэша и не перезапустили контейнер. - Скопировали Test URL в Telegram или платёжную систему.
- Поменяли домен после создания OAuth credentials и не обновили redirect URL.
- Оставили
N8N_SECURE_COOKIE=falseкак постоянный фикс вместо настройки HTTPS. - Прокинули порт 5678 наружу и одновременно поставили reverse proxy — получилось два способа доступа.
Полезные страницы
- Диагностика Webhook в n8n
- Webhook не работает: причины и решения
- Production-развёртывание n8n
- Docker Compose для n8n
- Безопасность self-hosted n8n
Официальные источники
FAQ
WEBHOOK_URL меняет Test URL?
Главная практическая цель переменной — корректный внешний адрес для production webhook и callback-сценариев. Для тестового URL поведение может отличаться в зависимости от конфигурации и версии.
Можно ли использовать HTTP без HTTPS?
Для локальных тестов можно. Для Telegram, OAuth, платёжных уведомлений и публичных webhooks нужен HTTPS, иначе часть сервисов не примет endpoint или будет небезопасно передавать данные.
Нужно ли перезапускать n8n после изменения env?
Да. Переменные окружения читаются процессом при старте, поэтому после изменения compose или env-файла контейнер нужно пересоздать или перезапустить.
Операционный runbook для self-hosted ¶
Для темы «n8n HTTPS, reverse proxy и WEBHOOK_URL» важно разделять настройку и эксплуатацию. Настройка отвечает на вопрос “запустилось ли”, эксплуатация — “сможем ли мы восстановиться, обновиться и расследовать инцидент без потери credentials и execution history”.
Перед изменениями проверьте бэкап базы, значение N8N_ENCRYPTION_KEY, состояние volume, логи web-процесса и worker-процесса. Главный риск — поменять настройку только в одном контейнере, забыть про worker или потерять volume/encryption key.
| Слой | Что зафиксировать | Зачем |
|---|---|---|
| Вход | payload webhook/API с подписью, timestamp, event_id и исходным HTTP-статусом | позволяет повторить проблему без доступа к production-секретам |
| Контроль | restart_count, memory_usage, queue_depth, worker_concurrency, failed_executions | показывает деградацию раньше, чем пользователи начинают писать в поддержку |
| Безопасность | поменять настройку только в одном контейнере, забыть про worker или потерять volume/encryption key | снижает риск скрытых дублей, утечки данных и неконтролируемых write-действий |
| Готовность | есть тест на happy path, пустой вход, повтор и сбой внешнего сервиса для «n8n HTTPS, reverse proxy и WEBHOOK_URL» | делает статью пригодной для 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-план с командами и ответственным