Caddy — современный веб-сервер, главная особенность которого — автоматический HTTPS: сертификаты Let's Encrypt выпускаются и продлеваются сами, без certbot, cron-задач и ручной настройки TLS. Конфигурация сайта со статикой или reverse proxy умещается в три строки Caddyfile, а HTTP-запросы сразу перенаправляются на HTTPS. Для небольших проектов на VPS caddy server — самый короткий путь от чистой системы до работающего сайта с валидным сертификатом. Разберём установку Caddy на Ubuntu, синтаксис Caddyfile и типовые сценарии: статика, проксирование и PHP.
Чем Caddy отличается от Nginx и Apache
Caddy написан на Go, распространяется как один бинарный файл и включает встроенный ACME-клиент — тот самый механизм, которому классические веб-серверы требуют внешнюю утилиту вроде certbot (как это делается с Nginx, мы разбирали в статье про SSL-сертификат Let's Encrypt).
| Возможность | Caddy | Nginx |
|---|---|---|
| HTTPS-сертификат | Автоматически, встроенный ACME-клиент | Отдельно через certbot |
| Продление сертификата | Автоматически, без cron | Таймер/cron certbot |
| Редирект HTTP → HTTPS | Включён по умолчанию | Настраивается вручную |
| HTTP/2 | Включён по умолчанию | Включается в конфиге |
| Формат конфига | Caddyfile (минималистичный) | Блоки nginx.conf |
| Экосистема и примеры | Меньше готовых рецептов | Огромная база знаний |
Nginx остаётся стандартом для высоконагруженных проектов и сложных конфигураций — его настройку мы описывали в статье «Установка Nginx на Ubuntu». Caddy же выигрывает там, где важна скорость запуска и минимум обслуживания: личные сайты, пет-проекты, панели, API небольших сервисов.
Что понадобится
- VPS с Ubuntu 22.04/24.04 (подойдёт и Debian) и root-доступом или sudo;
- домен с A-записью, указывающей на IP сервера. Без корректной DNS-записи Let's Encrypt не выпустит сертификат — как привязать домен, пошагово описано в статье «Привязка домена к VPS»;
- открытые порты 80 и 443: они нужны и для работы сайта, и для проверки владения доменом при выпуске сертификата.
Если на сервере уже работает другой веб-сервер, остановите его перед запуском Caddy, иначе порты будут заняты:
sudo systemctl stop nginx 2>/dev/null; sudo systemctl disable nginx 2>/dev/null
Установка Caddy на Ubuntu
Ставим из официального репозитория проекта — так Caddy будет обновляться вместе с системой через apt:
# зависимости для подключения стороннего репозитория
sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
# GPG-ключ репозитория Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | \
sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
# сам репозиторий
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | \
sudo tee /etc/apt/sources.list.d/caddy-stable.list
# установка
sudo apt update
sudo apt install -y caddy
Проверяем, что сервис запустился:
systemctl status caddy
caddy version
Пакет сразу регистрирует systemd-сервис: Caddy запущен, стартует при загрузке системы и уже слушает порт 80. Если открыть IP сервера в браузере, увидите стандартную страницу-заглушку. Осталось открыть порты в файрволе, если используется ufw:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Caddyfile: минимальная конфигурация с HTTPS
Конфигурация лежит в /etc/caddy/Caddyfile. Откройте файл любым редактором:
sudo nano /etc/caddy/Caddyfile
Замените содержимое на минимальный конфиг для статического сайта (подставьте свой домен):
example.com {
root * /var/www/example.com
file_server
encode gzip zstd
}
Построчно:
example.com { ... }— блок сайта. Само наличие домена в качестве адреса включает автоматический HTTPS: Caddy выпустит сертификат Let's Encrypt для example.com и настроит редирект с HTTP;root * /var/www/example.com— каталог с файлами сайта;file_server— включает раздачу статических файлов;encode gzip zstd— сжатие ответов.
Создадим каталог и тестовую страницу:
sudo mkdir -p /var/www/example.com
echo '<h1>Caddy works!</h1>' | sudo tee /var/www/example.com/index.html
sudo chown -R caddy:caddy /var/www/example.com
Проверяем синтаксис и применяем конфигурацию без остановки сервера:
caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Через несколько секунд откройте https://example.com — сайт отвечает по HTTPS с валидным сертификатом, а http:// автоматически перенаправляется на https://. Ни одной команды для TLS вы не выполняли: выпуск занял у Caddy считанные секунды, продление тоже пройдёт без вашего участия. О том, как наполнить такой сайт реальным содержимым, — в статье «Статичный сайт на VPS».
Если выпуск не сработал, смотрите журнал — причина почти всегда в DNS или закрытых портах:
journalctl -u caddy --no-pager -n 50
Caddy как reverse proxy
Второй по популярности сценарий — проксирование запросов к приложению на Node.js, Python, Go или к Docker-контейнеру. Вся настройка — одна директива:
app.example.com {
reverse_proxy 127.0.0.1:3000
}
Caddy принимает HTTPS-запросы, терминирует TLS и передаёт трафик приложению на локальный порт 3000, автоматически подставляя заголовки X-Forwarded-For и X-Forwarded-Proto. Несколько сайтов описываются отдельными блоками в одном Caddyfile:
example.com {
root * /var/www/example.com
file_server
}
api.example.com {
reverse_proxy 127.0.0.1:8080
}
app.example.com {
reverse_proxy 127.0.0.1:3000
}
Для каждого домена Caddy выпустит собственный сертификат — при условии, что A-записи всех доменов указывают на сервер. Можно распределять нагрузку на несколько бэкендов, просто перечислив их:
api.example.com {
reverse_proxy 127.0.0.1:8080 127.0.0.1:8081
}
Общая теория проксирования — зачем нужны заголовки и как то же самое делается в Nginx — разобрана в статье «Nginx как reverse proxy».
PHP-сайт на Caddy
Caddy работает с PHP через PHP-FPM. Устанавливаем:
sudo apt install -y php8.3-fpm
Конфигурация сайта с PHP отличается одной директивой php_fastcgi:
example.com {
root * /var/www/example.com
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
}
Директива сама обрабатывает правила перезаписи в стиле try_files, передачу скриптов в FPM и индексный index.php — то, что в Nginx занимает отдельный блок location. Проверьте версию PHP в системе (php-fpm8.3 -v) и при необходимости поправьте путь к сокету.
Полезные директивы Caddyfile
Несколько часто используемых возможностей:
example.com {
root * /var/www/example.com
file_server
encode gzip zstd
# свои страницы ошибок
handle_errors {
rewrite * /error.html
file_server
}
# заголовки безопасности
header {
Strict-Transport-Security "max-age=31536000;"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
}
# логи доступа в файл
log {
output file /var/log/caddy/example.com.log
}
# редирект с www на основной домен
}
www.example.com {
redir https://example.com{uri} permanent
}
Все изменения применяются командой sudo systemctl reload caddy — без разрыва текущих соединений. Полный список директив есть в официальной документации Caddy; для большинства сайтов хватает приведённого набора.
Обслуживание и диагностика
Основные команды на каждый день:
# статус и логи
systemctl status caddy
journalctl -u caddy -f
# проверить конфиг перед применением
caddy validate --config /etc/caddy/Caddyfile
# отформатировать Caddyfile по стандарту
caddy fmt --overwrite /etc/caddy/Caddyfile
# применить изменения без даунтайма
sudo systemctl reload caddy
Сертификаты и служебные данные Caddy хранит в /var/lib/caddy/.local/share/caddy — при переносе сервера на другой VPS этот каталог стоит забрать вместе с Caddyfile, тогда повторный выпуск сертификатов не понадобится. Обновляется Caddy обычным sudo apt upgrade, поскольку установлен из репозитория.
Частые вопросы
Нужен ли certbot при использовании Caddy?
Нет, в этом и смысл Caddy: ACME-клиент встроен в сам веб-сервер. Caddy выпускает сертификат Let's Encrypt при первом запуске сайта и продлевает его автоматически задолго до истечения срока. Никаких cron-задач, таймеров и внешних утилит не требуется.
Почему Caddy не выпускает сертификат?
В большинстве случаев причин три: A-запись домена не указывает на IP сервера, порты 80/443 закрыты файрволом или заняты другим веб-сервером. Проверьте DNS командой dig +short example.com, откройте порты в ufw и убедитесь, что Nginx или Apache остановлены. Подробности всегда есть в журнале: journalctl -u caddy -n 50.
Можно ли запустить Caddy на VPS без выделенного IPv4?
Для автоматического выпуска сертификата Let's Encrypt должен достучаться до вашего сервера по портам 80 и 443 — нужен либо выделенный IPv4, либо проброс этих портов на ваш сервер. На NAT VPS с пробросом произвольных портов сайт можно опубликовать на нестандартном порту, но автоматический выпуск сертификата по HTTP-проверке в такой схеме не сработает — потребуется DNS-проверка. Для публичного сайта проще взять обычный VPS с выделенным IP.
Caddy или Nginx — что выбрать?
Caddy — когда нужно быстро поднять сайт или прокси с HTTPS и минимально его обслуживать. Nginx — когда важны тонкая настройка, кеширование, огромная база готовых конфигов и рецептов под любое приложение. Оба сервера надёжны; для типичного проекта на VPS решает не производительность, а то, сколько времени вы готовы тратить на конфигурацию.
Как перенести сайт с Nginx на Caddy?
Остановите Nginx (sudo systemctl disable --now nginx), опишите сайты в /etc/caddy/Caddyfile — блок root + file_server для статики, reverse_proxy вместо proxy_pass, php_fastcgi вместо fastcgi-блоков — и перезапустите Caddy. Сертификаты переносить не нужно: Caddy выпустит свои автоматически. Начните с одного некритичного сайта, убедитесь, что всё работает, затем переносите остальные.
Caddy плюс быстрый VPS — рабочий сайт с HTTPS уже через пять минут после заказа. На Cheap-Host сервер выдаётся за 45–60 секунд: тариф Start за 450 ₽/мес (6 vCPU, 8 ГБ RAM, 96 ГБ NVMe, KVM, Москва) с запасом хватит и для статики, и для нескольких проксируемых приложений. Заказать VPS — на cheap-host.onl.