Перейти к основному содержимому
Вернуться в категорию

Настройка веб-сервера Caddy: автоматический HTTPS и обратный прокси

Установка веб-сервера Caddy, настройка Caddyfile, автоматический SSL от Let's Encrypt, обратный прокси, хостинг статических сайтов, интеграция PHP-FPM и настройки производительности.

Время чтения: 14 мин DevOps и автоматизация
caddyвеб-серверhttpssslобратный проксиlet's encryptdevops

Содержание

Настройка веб-сервера Caddy: автоматический HTTPS и обратный прокси

Caddy — современный веб-сервер, выделяющийся автоматическим управлением HTTPS-сертификатами. Благодаря интеграции с Let's Encrypt он автоматически получает, обновляет и настраивает SSL-сертификаты.

Что такое Caddy?

Отличительные особенности Caddy:

  • Автоматический HTTPS: Управление сертификатами через Let's Encrypt полностью автоматическое
  • Простая конфигурация: Синтаксис Caddyfile легко читается
  • HTTP/2 и HTTP/3: Включены по умолчанию
  • Обратный прокси: Встроенная балансировка нагрузки и проверки работоспособности
  • Перезагрузка без простоя: Нет прерываний при изменении конфигурации

Caddy требует привилегий root для использования портов 80 и 443. Это автоматически управляется при запуске как systemd-сервис.

Установка Caddy

Установка через apt (Ubuntu/Debian)

hljs bash
# Добавить GPG-ключ и репозиторий Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
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

# Установить Caddy
sudo apt update
sudo apt install caddy -y

# Проверить статус сервиса
sudo systemctl status caddy

Установка бинарного файла

hljs bash
# Загрузить последнюю версию
VERSION=$(curl -s https://api.github.com/repos/caddyserver/caddy/releases/latest | grep tag_name | cut -d '"' -f 4)
curl -L "https://github.com/caddyserver/caddy/releases/download/${VERSION}/caddy_${VERSION#v}_linux_amd64.tar.gz" -o caddy.tar.gz

# Распаковать и установить
tar -xzf caddy.tar.gz
sudo mv caddy /usr/local/bin/
sudo chmod +x /usr/local/bin/caddy

# Проверить версию
caddy version

Пользовательская сборка с xcaddy

hljs bash
# Установить xcaddy
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

# Собрать с дополнительными модулями
xcaddy build \
  --with github.com/caddy-dns/cloudflare \
  --with github.com/greenpau/caddy-security

Синтаксис Caddyfile

Базовая структура

hljs caddyfile
# Один сайт
example.com {
    root * /var/www/html
    file_server
}

# Несколько сайтов
example.com {
    respond "Привет, example.com!"
}

api.example.com {
    reverse_proxy localhost:3000
}

Глобальные параметры

hljs caddyfile
# Глобальные настройки в начале Caddyfile
{
    # Порт Admin API
    admin localhost:2019

    # Email (для Let's Encrypt)
    email admin@example.com

    # ACME-сервер (staging для тестирования)
    # acme_ca https://acme-staging-v02.api.letsencrypt.org/directory

    # HTTP-порт
    http_port 80

    # HTTPS-порт
    https_port 443

    # Формат логов
    log {
        output file /var/log/caddy/access.log
        format json
    }
}

Автоматический HTTPS

Caddy автоматически получает сертификат Let's Encrypt для вашего домена:

hljs caddyfile
# Просто напишите доменное имя — HTTPS автоматически!
example.com {
    root * /var/www/html
    file_server
    encode gzip
}

# Перенаправление www
www.example.com {
    redir https://example.com{uri} permanent
}

# Wildcard-сертификат (требует DNS-challenge)
*.example.com {
    tls {
        dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    }
    @api host api.example.com
    handle @api {
        reverse_proxy localhost:3000
    }
}

Caddy автоматически обновляет сертификаты. Ручное вмешательство не требуется. Сертификаты хранятся в ~/.local/share/caddy/ или /var/lib/caddy/.

Конфигурация обратного прокси

Простой обратный прокси

hljs caddyfile
app.example.com {
    reverse_proxy localhost:3000
}

# Несколько upstream (балансировка нагрузки)
api.example.com {
    reverse_proxy {
        to localhost:3001 localhost:3002 localhost:3003
        lb_policy round_robin
        health_uri /health
        health_interval 30s
        health_timeout 5s
    }
}

Расширенный обратный прокси

hljs caddyfile
app.example.com {
    reverse_proxy localhost:3000 {
        # Передача заголовков
        header_up Host {upstream_hostport}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}

        # Тайм-ауты
        transport http {
            dial_timeout 5s
            response_header_timeout 30s
        }

        # Повторные попытки
        lb_retries 3
        lb_try_duration 5s
    }

    # Заголовки безопасности
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
        -Server
    }
}

Раздача статических файлов

hljs caddyfile
static.example.com {
    root * /var/www/static
    file_server {
        # Листинг директорий
        browse
        # Скрыть скрытые файлы
        hide .git .env
    }
    encode gzip zstd

    # Заголовки кэша
    header /assets/* Cache-Control "public, max-age=31536000, immutable"
    header /*.html Cache-Control "no-cache"

    # Страницы ошибок
    handle_errors {
        rewrite * /errors/{err.status_code}.html
        file_server
    }
}

# SPA (Single Page Application)
app.example.com {
    root * /var/www/app
    encode gzip
    try_files {path} /index.html
    file_server
}

Интеграция PHP-FPM

hljs caddyfile
php.example.com {
    root * /var/www/php
    encode gzip

    # Перенаправить PHP-файлы в PHP-FPM
    php_fastcgi unix//run/php/php8.2-fpm.sock

    # Или через TCP
    # php_fastcgi localhost:9000

    file_server

    # Для WordPress
    @notStatic {
        not path /wp-content/* /wp-includes/*
        not file
    }
    rewrite @notStatic /index.php
}

Caddy с Docker

hljs yaml
# docker-compose.yml
services:
  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"  # HTTP/3
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
      - ./html:/var/www/html:ro
    environment:
      - CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}

  app:
    build: ./app
    expose:
      - "3000"

volumes:
  caddy_data:
  caddy_config:
hljs caddyfile
# Docker Caddyfile
example.com {
    reverse_proxy app:3000
}

Управление через API

Caddy поддерживает динамическую конфигурацию через REST API:

hljs bash
# Просмотреть текущую конфигурацию
curl http://localhost:2019/config/

# Обновить конфигурацию
curl -X POST http://localhost:2019/load \
  -H "Content-Type: application/json" \
  -d @caddy.json

# Перезагрузить Caddy (без простоя)
caddy reload --config /etc/caddy/Caddyfile

# Проверить конфигурацию
caddy validate --config /etc/caddy/Caddyfile

# Форматировать Caddyfile
caddy fmt --overwrite /etc/caddy/Caddyfile

Настройки производительности

hljs caddyfile
{
    servers {
        max_header_size 1MB
        timeouts {
            read_body 10s
            read_header 10s
            write 30s
            idle 2m
        }
    }
}

example.com {
    # Сжатие
    encode {
        gzip 6
        zstd
        minimum_length 1024
    }

    reverse_proxy localhost:3000
}

Заключение

Caddy отвечает современным требованиям к веб-серверам с автоматическим управлением HTTPS и простой конфигурацией. Он требует значительно меньше настроек по сравнению с Nginx или Apache, предлагая при этом все функции, необходимые для production-окружений. Это идеальный выбор для тех, кто хочет автоматизировать управление сертификатами Let's Encrypt.