opened image

Caddy: веб-сервер с автоматическим SSL и минимальной конфигурацией

 

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:

  1. Проверяет, есть ли сертификат в хранилище (/var/lib/caddy/)

  2. Если нет - обращается к Let's Encrypt ACME API

  3. Проходит HTTP-01 challenge: Let's Encrypt проверяет, что сервер отвечает по http://example.com/.well-known/acme-challenge/

  4. Получает сертификат и сохраняет его локально

  5. Автоматически продлевает за 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 экономит время.