Команда инженеров · свой ЦОД в РФ · своё железо · своя панель · CloudStack + Linstor · MCP · база знаний по self-hosted
Сравнения · Обратный прокси

Обратный прокси для своего сервера: Caddy, nginx или HAProxy - и как мы вынесли S3-кластер за HAProxy

Как только на сервере появляется больше одного сервиса, встает вопрос единого входа: кто принимает 443, выдает TLS, маршрутизирует запросы и держит удар, когда одна нода отвалилась. В self-hosted мире на эту роль спорят трое - Caddy, nginx и HAProxy, - и их постоянно ставят в один ряд, хотя это три разные работы. Мы гоняем все три в проде: Caddy - в каждой карте маркетплейса, а HAProxy у нас стоит перед кластером Garage S3. Разберем, кто для чего, и покажем на своей живой схеме, где выигрывает именно балансировщик.

Сентябрь 2026 ~9 минут чтения Команда Fatmetal
Caddy vs nginx vs HAProxy Три инструмента, три задачи Живой кейс: S3 за HAProxy
Зачем нужен фронт

Один вход вместо зоопарка портов

Пока на сервере один сервис, можно жить и без прослойки. Но стоит добавить второй, третий, а потом вынести что-то на отдельные машины - и появляется набор задач, которые нельзя оставить на самих приложениях: принять внешний HTTPS на 443, выдать и продлить сертификат, разослать запросы по нужным бэкендам и не упасть целиком, если один из них умер.

Это и есть работа фронтального прокси. В self-hosted на нее претендуют трое, и выбор между ними - не вопрос вкуса, а вопрос того, какая из задач у вас главная: раздать сервис наружу с минимумом возни, обслужить сложную веб-логику или ровно распределить нагрузку по нескольким нодам и переживать их отказ.

Ключевая развилка

Это не три конкурента, а три специализации

Главная ошибка при выборе - думать, что Caddy, nginx и HAProxy решают одну задачу и надо просто взять лучший. Они выросли из разных потребностей. Caddy - веб-сервер, который сам получает и продлевает TLS-сертификаты; его конек - быстро и без ручного возни отдать сервис наружу по HTTPS. nginx - универсальный веб-сервер и обратный прокси с богатой HTTP-логикой: виртуальные хосты, редиректы, раздача статики, тонкая маршрутизация. HAProxy - специализированный балансировщик уровня L4/L7: его работа не отдавать страницы, а ровно распределить трафик по бэкендам, следить за их здоровьем и выкидывать мертвые.

Отсюда простое правило: выбираете не по бенчмаркам, а по тому, что у вас за задача. Вот как это ложится по осям, которые реально влияют на решение:

ОсьCaddynginxHAProxy
Что это по сутиВеб-сервер с авто-TLSУниверсальный веб-сервер и проксиСпециализированный L4/L7 балансировщик
Авто-HTTPS из коробкида, Let's Encrypt самчерез отдельный ACME-клиентсертификат подкладываете сами
Статика, vhosts, редиректыбазово естьэто его сильная сторонане его роль
Балансировка по нодампростаяесть, но как доп-функцияпрофильная задача
Health checks бэкендовограниченнобазовогибкие, с выбросом мертвых
Чистый L4 / TCP passthroughнетограниченнода, прозрачно
Где дефолтодин сервис наружу по HTTPSсайт со сложной веб-логикойнесколько нод за одним endpoint

Дальше - по каждому предметно, а в конце покажем нашу боевую схему, где ответ однозначно HAProxy.

Caddy

Caddy - когда надо просто отдать сервис по HTTPS

Caddy мы ставим в каждую карту маркетплейса, и причина одна: он снимает боль с сертификатов. Указываете домен - Caddy сам получает Let's Encrypt, сам продлевает, сам держит редирект с 80 на 443. Конфиг короткий и читаемый, для типового сценария reverse proxy на одно приложение это буквально несколько строк. Для клиента, который поднял себе один сервис и хочет открыть его наружу по нормальному HTTPS без ручной возни с certbot, Caddy - оптимальный дефолт.

Пределы у него ровно там, где начинается не его роль: сложная многосайтовая веб-логика или серьезная балансировка по многим нодам. Для одного-двух бэкендов он справится, но чем сложнее раскладка трафика, тем чаще хочется инструмент, заточенный именно под это.

nginx

nginx - универсал для сложной веб-логики

nginx - рабочая лошадь индустрии, и его сила в широте HTTP-возможностей. Виртуальные хосты, тонкие правила location, редиректы, раздача статики, кеширование, переписывание запросов - если фронт должен не просто пробросить трафик, а разложить его по сложным правилам и заодно отдавать файлы, nginx на своем месте. Зрелость и объем документации у него огромные, готовый рецепт находится почти под любую задачу.

Балансировку он тоже умеет, но как одну из многих функций, а не как профиль. Когда задача сводится к чистому распределению трафика по нескольким нодам с аккуратными проверками здоровья, его богатая HTTP-обвязка простаивает, а поведение под нагрузкой и наблюдаемость проще получить у специализированного балансировщика. Это и подводит к третьему инструменту.

HAProxy

HAProxy - когда нод несколько и они должны переживать отказ

HAProxy изначально сделан под одну задачу - балансировать. Он не отдает страницы и не заменяет веб-сервер, зато делает то, что у остальных идет доп-функцией: регулярно проверяет бэкенды, автоматически выкидывает недоступные, распределяет соединения по выбранному алгоритму и предсказуемо ведет себя под нагрузкой. Плюс встроенная статистика по состоянию бэкендов и лимитам соединений. Как только у вас не один сервер, а несколько нод за общим входом, и важно пережить отказ любой из них - это его территория.

Живой кейс Fatmetal

Как мы вынесли кластер Garage S3 за HAProxy

Теперь то, ради чего все и затевалось. У нас есть S3-хранилище на Garage, и это не одна машина, а кластер из нескольких API-нод. Клиенту нужен один публичный адрес и один HTTPS endpoint, а запросы должны уходить только на живые ноды. Классическая задача под балансировщик - и здесь мы взяли именно HAProxy, а не nginx. Ниже - почему и как, схема переносимая на любой размер кластера (три ноды, N нод - меняется только список бэкендов).

Почему не nginx. S3-клиенты подписывают запросы по AWS Signature V4, и подпись чувствительна к Host, URI, query string и части заголовков. Фронт обязан быть максимально прозрачным: не переписывать путь, query и Host, не добавлять лишнюю HTTP-логику. Богатая веб-обвязка nginx тут не нужна, а лишний риск что-то незаметно преобразовать в запросе - есть. Правило простое: балансировщик балансирует трафик, а не преобразует S3 API.

Алгоритм - leastconn. Объект в S3 может грузиться долго и держать соединение открытым. Round-robin этого не учитывает, а leastconn отправляет новый запрос на ноду с наименьшим числом активных соединений - под тяжелые upload и download это точнее. Каждая нода под проверкой health check, недоступная автоматически выпадает из ротации:

backend garage_nodes
    mode http
    balance leastconn
    option httpchk GET /health   # endpoint сверяем с версией Garage
    server garage1 10.0.0.11:3900 check
    server garage2 10.0.0.12:3900 check
    server garage3 10.0.0.13:3900 check
    # нод больше - просто добавляете строку server на каждую

TLS - терминируем на HAProxy. HAProxy принимает HTTPS на 443, завершает TLS и ходит на ноды по внутренней сети. Это дает централизованное управление сертификатами и удобные HTTP health checks. Альтернатива - L4 TCP passthrough, когда HAProxy вообще не разбирает HTTP и TLS завершается на самих нодах: максимально прозрачно для SigV4, но сертификаты и HTTPS тогда живут на каждом бэкенде, а проверки здоровья на уровне приложения становятся менее удобными. По умолчанию мы выбираем термination на HAProxy.

Длинные timeout. S3-передачи живут дольше обычных веб-запросов, поэтому короткие web-дефолты опасны - балансировщик может оборвать корректную загрузку большого объекта на середине. Значения ниже - безопасная отправная точка, а не универсальная настройка: их подбирают под максимальный размер объектов и скорость клиентов.

frontend garage_s3
    bind *:443 ssl crt /etc/haproxy/certs/s3.pem
    mode http
    default_backend garage_nodes

timeout connect 5s
timeout client  1h
timeout server  1h

Сам фронт не должен стать точкой отказа. Несколько нод Garage переживают потерю любой из них - но один HAProxy впереди сводит всю отказоустойчивость на нет: умер он, умер весь endpoint. Поэтому в проде мы ставим не один, а два HAProxy с общим VIP через Keepalived (либо, где позволяет сеть, BGP/ECMP). Отказ одной фронт-ноды не должен делать S3 недоступным.

i

Важно, что делает и чего не делает балансировщик. HAProxy решает узкую задачу: определить, может ли нода сейчас принять запрос, и направить трафик на живую. Внутреннюю репликацию, размещение и согласование данных полностью держит сам Garage - фронт в это не вмешивается.

Итог: что бы взяли мы

Развилка не в том, кто лучше, а в том, какая задача главная. Caddy - если надо отдать один сервис наружу по HTTPS с минимумом возни: авто-TLS из коробки, короткий конфиг, наш дефолт в картах маркетплейса. nginx - если фронт должен разложить трафик по сложным правилам, обслужить виртуальные хосты и раздать статику. HAProxy - если у вас несколько нод за одним входом и важно пережить отказ любой: health checks, leastconn, прозрачное проксирование и предсказуемость под нагрузкой. Наш кластер Garage S3 стоит именно за HAProxy - и в проде это два HAProxy с общим VIP, чтобы сам фронт не стал точкой отказа. Нужен сервер под такой фронт или объектное хранилище на нашей S3 - поднимем и поможем со схемой.

Из той же серии операторских сравнений - OpenClaw против Hermes Agent, на чем мы держим свою контент-фабрику. Схема Garage S3 за HAProxy - наша боевая production-конфигурация (обобщена до N нод, внутренние адреса заменены примерными). Caddy и nginx мы разворачиваем на живых серверах Fatmetal, HAProxy стоит перед нашим S3-кластером. Заметили неточность - напишите, поправим в течение дня.

Материал подготовлен на живой инфраструктуре Fatmetal (сентябрь 2026): Caddy в картах маркетплейса, HAProxy перед кластером Garage S3. Обновляется по мере изменений схемы и новых версий инструментов.