Caddy написан на Go, вышел в 2015 году и сделал одну вещь, которую не умеет Nginx из коробки: автоматически получает и продлевает SSL-сертификаты через Let's Encrypt без каких-либо дополнительных инструментов. Конфиг для простого сайта занимает 3 строки. Reverse proxy - одну.
Установка Caddy на Ubuntu
Официальный репозиторий Caddy для Ubuntu:
apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
tee /etc/apt/sources.list.d/caddy-stable.list
apt update
apt install caddy
После установки Caddy запускается автоматически через systemd. Проверьте:
systemctl status caddy
caddy version
Конфигурационный файл находится по адресу /etc/caddy/Caddyfile. Caddy хранит полученные сертификаты в /var/lib/caddy/.local/share/caddy/.

Синтаксис Caddyfile: сайт в три строки
Вот полная конфигурация для статического сайта с автоматическим SSL:
example.com {
root * /var/www/html
file_server
}
Три строки делают следующее:
example.com- Caddy слушает входящие запросы для этого доменаroot * /var/www/html- корневая директория для файловfile_server- включает раздачу статических файлов
Caddy при первом запуске автоматически получит сертификат от Let's Encrypt, настроит HTTPS на 443-м порту и добавит редирект с HTTP. Никаких дополнительных команд не нужно.
Применить конфиг:
systemctl reload caddy
Или проверить синтаксис перед применением:
caddy validate --config /etc/caddy/Caddyfile
Как работает автоматический Let's Encrypt
При первом запросе к example.com Caddy:
Проверяет, есть ли сертификат в хранилище (
/var/lib/caddy/)Если нет - обращается к Let's Encrypt ACME API
Проходит HTTP-01 challenge: Let's Encrypt проверяет, что сервер отвечает по
http://example.com/.well-known/acme-challenge/Получает сертификат и сохраняет его локально
Автоматически продлевает за 30 дней до истечения
Caddy обслуживает ACME challenge самостоятельно, порт 80 должен быть доступен. Certbot, cron-задачи, systemd-таймеры - всё это не нужно.
Для тестирования без получения реального сертификата используйте staging Let's Encrypt:
caddy run --config /etc/caddy/Caddyfile --environ
Или в Caddyfile:
{
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
example.com {
root * /var/www/html
file_server
}
Reverse proxy одной строкой
Проксировать запросы на локальный порт:
api.example.com {
reverse_proxy localhost:8080
}
Caddy получит сертификат для api.example.com и передаёт все запросы на localhost:8080. Заголовки X-Forwarded-For, X-Forwarded-Proto, X-Real-IP Caddy добавляет автоматически.
Несколько приложений на разных доменах:
app.example.com {
reverse_proxy localhost:3000
}
api.example.com {
reverse_proxy localhost:5000
}
static.example.com {
root * /var/www/static
file_server
}
Каждый блок - отдельный виртуальный хост с собственным SSL-сертификатом. Certbot для трёх доменов потребует три вызова команды. В Caddy - просто три блока.
Расширенная конфигурация reverse proxy
Если нужно добавить заголовки, настроить таймауты или балансировку:
app.example.com {
reverse_proxy localhost:3000 {
header_up X-Custom-Header "value"
transport http {
dial_timeout 5s
response_header_timeout 30s
}
}
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
}
Балансировка между несколькими бэкендами:
app.example.com {
reverse_proxy localhost:3001 localhost:3002 localhost:3003 {
lb_policy least_conn
}
}
Caddy поддерживает least_conn, round_robin, ip_hash, random и другие алгоритмы балансировки.
Статический файл-сервер с кешированием
assets.example.com {
root * /var/www/assets
file_server {
browse
}
header Cache-Control "public, max-age=86400"
encode gzip zstd
}
encode gzip zstd - Caddy сжимает ответы автоматически. file_server browse - добавляет листинг директорий.
Сравнение с Nginx: когда что выбрать
Caddy выбирайте когда:
Нужен быстрый старт без глубокого знания конфигурации
SSL должен работать из коробки без Certbot и cron
Один сервер, несколько сайтов, минимальное обслуживание
Команда небольшая и нет выделенного DevOps
Nginx выбирайте когда:
Нужен тонкий контроль над буферами, таймаутами, кешированием
Высокие нагрузки: десятки тысяч запросов в секунду
Статическая раздача файлов при максимальной производительности
Есть опыт и существующие конфиги на Nginx
Нужны возможности Nginx Plus (активные healthcheck, расширенное логирование)
Конкретные цифры: Nginx обрабатывает статические файлы быстрее Caddy примерно на 10-20% при высоком RPS, потому что написан на C и оптимизирован под IO. Разница ощутима при 50 000+ запросов в секунду. На типичных VPS с 1-4 vCPU эта разница незначительна.
Caddy потребляет больше памяти из-за Go runtime: около 30-50 МБ против 5-10 МБ у Nginx в базовой конфигурации.
Логирование
По умолчанию Caddy пишет логи в systemd journal. Посмотреть:
journalctl -u caddy --since "1 hour ago"
Настроить JSON-логи в файл:
{
log {
output file /var/log/caddy/access.log {
roll_size 10mb
roll_keep 10
}
format json
}
}
example.com {
reverse_proxy localhost:3000
}
Глобальная секция { } в начале Caddyfile - настройки уровня сервера. Ротация логов встроена в Caddy.

Перезагрузка без downtime
Caddy поддерживает graceful reload: новый конфиг применяется без прерывания текущих соединений:
caddy reload --config /etc/caddy/Caddyfile
Через systemd:
systemctl reload caddy
Отличие от Nginx: nginx -s reload тоже graceful, но Caddy при reload может автоматически получить новые сертификаты если появились новые домены.
Итог
Caddy подходит для большинства типичных задач VPS: проксировать несколько приложений, раздавать статику, завершать SSL. Конфигурация читается с первого взгляда. Автоматический SSL без сторонних инструментов - реальное преимущество по сравнению с Nginx + Certbot. Если Nginx уже настроен и работает, менять его смысла нет. Для нового проекта с нуля Caddy экономит время.
