Spec-Zone.ru › Caddy

Концепции Caddyfile

Этот документ поможет вам подробно изучить HTTP Caddyfile.

  1. Структура
    • Блоки
    • Директивы
    • Токены и кавычки
  2. Глобальные параметры
  3. Адреса
  4. Сопоставители
  5. Плейсхолдеры
  6. Сниппеты
  7. Именованные маршруты
  8. Комментарии
  9. Переменные окружения

Структура

Структуру Caddyfile можно описать визуально:

Caddyfile structure

Основные моменты:

  • Необязательный блок глобальных параметров может быть первым элементом в файле.

  • Сниппеты или именованные маршруты могут быть необязательно указаны далее.

  • В противном случае, первая строка Caddyfile всегда содержит адрес(а) сайта для обработки.

  • Все директивы и сопоставители должны находиться в блоке сайта. Глобальной области видимости или наследования между блоками сайтов нет.

  • Если существует только один блок сайта, его фигурные скобки { } необязательны.

Caddyfile состоит как минимум из одного или нескольких блоков сайта, которые всегда начинаются с одного или нескольких адресов сайта. Любые директивы, расположенные перед адресом, будут непонятны парсеру.

Блоки

Открытие и закрытие блока осуществляется с помощью фигурных скобок:

... {
	...
}
  • Открывающая фигурная скобка { должна быть в конце строки и предваряться пробелом.

  • Закрывающая фигурная скобка } должна быть на отдельной строке.

Когда существует только один блок сайта, фигурные скобки (и отступы) необязательны. Это удобно для быстрого определения одного сайта, например так:

localhostreverse_proxy /api/* localhost:9001
file_server

эквивалентно:

localhost {
	reverse_proxy /api/* localhost:9001
	file_server
}

когда у вас только один блок сайта; это вопрос предпочтения.

Для настройки нескольких сайтов с помощью одного Caddyfile, вы должны использовать фигурные скобки вокруг каждого блока для разделения их конфигураций:

example1.com {
	root * /www/example.com
	file_server
}
example2.com {
	reverse_proxy localhost:9000
}

Если запрос соответствует нескольким блокам сайта, выбирается блок сайта с наиболее конкретным сопоставляющим адресом. Запросы не каскадируются в другие блоки сайтов.

Директивы

Директивы — это функциональные ключевые слова, которые настраивают способ предоставления сайта. Они должны появляться внутри блоков сайта. Например, полная конфигурация файлового сервера может выглядеть так:

localhost {
	file_server
}

Или обратный прокси:

localhost {
	reverse_proxy localhost:9000
}

В этих примерах file_server и reverse_proxy являются директивами. Директивы — это первое слово в строке в блоке сайта.

Во втором примере localhost:9000 является аргументом, поскольку он появляется в той же строке после директивы.

Иногда директивы могут открывать свои собственные блоки. Поддирективы появляются в начале каждой строки внутри блоков директивы:

localhost {
	reverse_proxy localhost:9000 localhost:9001 {
		lb_policy first
	}
}

Здесь lb_policy является поддирективой для reverse_proxy (она устанавливает политику балансировки нагрузки между бэкендами).

Если не указано иное в документации, директивы нельзя использовать внутри других блоков директивы. Например, basic_auth нельзя использовать внутри file_server, так как файловый сервер не знает, как выполнять аутентификацию; но вы можете использовать директивы внутри route, handle и handle_path блоков, так как они специально разработаны для группирования директив.

Обратите внимание, что при адаптации HTTP Caddyfile, директивы HTTP обработчика сортируются в соответствии с определенным порядком по умолчанию, за исключением блока route, поэтому порядок появления директив не имеет значения, кроме блоков route.

Токены и кавычки

Caddyfile лексически разлагается на токены перед разбором. Пробелы в Caddyfile значимы, поскольку токены разделяются пробелами.

Часто директивы ожидают определенное количество аргументов; если значение одного аргумента содержит пробелы, оно будет лексически разложено на два отдельных токена:

directive abc def

Это может вызвать проблемы и привести к ошибкам или непредсказуемому поведению.

Если abc def должно быть значением одного аргумента, оно должно быть заключено в кавычки:

directive "abc def"

Кавычки можно экранировать, если вам нужно использовать кавычки в заключенных в кавычки токенах:

directive "\"abc def\""

Чтобы избежать экранирования кавычек, вы можете использовать обратные кавычки ` ` для заключения токенов; например:

directive `{"foo": "bar"}`

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

directive "first line
	second line"

Поддерживаются также heredocs:

example.com {
	respond <<HTML		<html>
		  <head><title>Foo</title></head>
		  <body>Foo</body>
		</html>
HTML 200
}

Открывающая маркер heredoc должна начинаться с <<, за которым следует любой текст (рекомендуются заглавные буквы). Закрывающая маркер heredoc должна быть тем же текстом (в примере выше, HTML). Открывающий маркер можно экранировать с помощью \<<, чтобы предотвратить разбор heredoc, если это необходимо.

Закрывающая маркер может быть отступом, что приводит к удалению этого отступа из каждой строки текста (вдохновлено PHP), что удобно для читаемости внутри блоков, при этом обеспечивается полный контроль над пробелами в тексте токена. Конечная новая строка также удаляется, но может быть сохранена путем добавления дополнительной пустой строки перед закрывающим маркером.

Дополнительные токены могут следовать за закрывающим маркером в качестве аргументов для директивы (например, в примере выше, код состояния 200).

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

Caddyfile может необязательно начинаться со специального блока без ключей, называемого блоком глобальных параметров:

{
	...
}

Если он присутствует, он должен быть первым блоком в конфигурации.

Он используется для установки параметров, которые применяются глобально или не к какому-либо конкретному сайту. Внутри него можно устанавливать только глобальные параметры; вы не можете использовать обычные директивы сайта.

Например, для включения глобального параметра debug, который обычно используется для создания подробных журналов для отладки:

{
	debug
}

Прочитайте страницу Глобальных параметров для получения дополнительной информации.

Адреса

Адрес всегда находится в верхней части блока сайта и обычно является первым элементом в Caddyfile.

Примеры допустимых адресов:

Адрес Эффект
example.com HTTPS с управляемым общедоступным сертификатом
*.example.com HTTPS с управляемым поддерживающим дикий символ общедоступным сертификатом
localhost HTTPS с управляемым локальным сертификатом
http:// HTTP для всех случаев, влияющий на http_port
https:// HTTPS для всех случаев, влияющий на https_port
http://example.com HTTP явно с сопоставителем Host
example.com:443 HTTPS из-за соответствия параметру по умолчанию https_port
:443 HTTPS для всех случаев из-за соответствия параметру по умолчанию https_port
:8080 HTTP на нестандартном порту, без сопоставителя Host
localhost:8080 HTTPS на нестандартном порту, из-за наличия допустимого домена
https://example.com:443 HTTPS, но и https:// и :443 избыточны
127.0.0.1 HTTPS с локальным сертификатом IP-адреса
http://127.0.0.1 HTTP с сопоставителем IP-адреса Host (отклоняет localhost)

Автоматический HTTPS включен, если адрес сайта содержит имя хоста или IP-адрес. Однако это поведение чисто неявное, поэтому оно никогда не переопределяет явную конфигурацию.

Например, если адрес сайта http://example.com, автоматический HTTPS не активируется, потому что схема явно http://.

По адресу Caddy может потенциально определить схему, хост и порт вашего сайта. Если адрес не содержит порт, Caddy выберет порт, соответствующий схеме, если он указан, или по умолчанию будет использоваться порт 443.

Если вы указываете имя хоста, будут обрабатываться только запросы с соответствующим заголовком Host. Другими словами, если адрес сайта localhost, то Caddy не будет обрабатывать запросы на 127.0.0.1.

Дикие символы (*) могут быть использованы, но только для представления ровно одного метки имени хоста. Например, *.example.com соответствует foo.example.com, но не foo.bar.example.com, и * соответствует localhost, но не example.com. Смотрите патерн с дикими символами для сертификатов для практического примера.

Для обработки всех хостов опустите часть хоста адреса, например, просто https://. Это полезно при использовании On-Demand TLS, когда вы не знаете домены заранее.

Если несколько сайтов используют одно и то же определение, вы можете перечислить их все вместе, разделяя пробелами и запятыми (необходимо как минимум один пробел). Следующие три примера эквивалентны:

# Comma separated site addresses
localhost:8080, example.com, www.example.com {
	...
}

или

# Space separated site addresses
localhost:8080 example.com www.example.com {
	...
}

или

# Comma and new-line separated site addresses
localhost:8080,
example.com,
www.example.com {
	...
}

Адрес должен быть уникальным; вы не можете указывать один и тот же адрес более одного раза.

Плейсхолдеры нельзя использовать в адресах, но вы можете использовать переменные окружения в стиле Caddyfile в них:

{$DOMAIN:localhost} {
	...
}

По умолчанию сайты привязываются ко всем сетевым интерфейсам. Если вы хотите это переопределить, используйте директиву bind или глобальный параметр default_bind.

Сопоставители

Директивы обработчика HTTP по умолчанию применяются ко всем запросам (если не указано иное).

Сопоставители запросов могут использоваться для классификации запросов по заданным критериям. С помощью сопоставителей вы можете точно указать, к каким запросам применяется определённая директива.

Для директив, поддерживающих сопоставители, первый аргумент после директивы — маркер сопоставителя. Вот несколько примеров:

root *           /var/www  # matcher token: *
root /index.html /var/www  # matcher token: /index.html
root @post       /var/www  # matcher token: @post

Маркеры сопоставителей можно полностью опустить, чтобы сопоставить все запросы; например, * не нужно указывать, если следующий аргумент не похож на сопоставитель пути.

Прочитайте страницу о сопоставителях запросов, чтобы узнать больше.

Заменители

Заменители — простой способ вставить динамические значения в вашу статическую конфигурацию. Они могут использоваться в качестве аргументов для директив и поддиректив.

Заменители ограничены фигурными скобками { } и содержат идентификатор внутри, например: {foo.bar}. Открывающая фигурная скобка может быть экранирована \{like.this} для предотвращения замены. Идентификаторы замен обычно имеют пространства имён с точками, чтобы избежать коллизий между модулями.

Доступные заменители зависят от контекста. Не все заменители доступны во всех частях конфигурации. Например, приложение HTTP устанавливает заглушки, которые доступны только в тех областях конфигурации, которые связаны с обработкой HTTP-запросов (т. е. в директивах обработчика HTTP и сопоставителях запросов, но не в настройке tls). Некоторые директивы или сопоставители также могут устанавливать свои собственные заменители, которые могут использоваться любым последующим элементом. Некоторые заменители доступны глобально.

Вы можете использовать любые заменители в файле Caddy, но для удобства также можете использовать некоторые эквивалентные сокращения, которые расширяются при разборе файла Caddy:

Сокращение Заменяет
{cookie.*} {http.request.cookie.*}
{client_ip} {http.vars.client_ip}
{dir} {http.request.uri.path.dir}
{err.*} {http.error.*}
{file_match.*} {http.matchers.file.*}
{file.base} {http.request.uri.path.file.base}
{file.ext} {http.request.uri.path.file.ext}
{file} {http.request.uri.path.file}
{header.*} {http.request.header.*}
{host} {http.request.host}
{hostport} {http.request.hostport}
{labels.*} {http.request.host.labels.*}
{method} {http.request.method}
{path.*} {http.request.uri.path.*}
{path} {http.request.uri.path}
{port} {http.request.port}
{query.*} {http.request.uri.query.*}
{query} {http.request.uri.query}
{re.*} {http.regexp.*}
{remote_host} {http.request.remote.host}
{remote_port} {http.request.remote.port}
{remote} {http.request.remote}
{rp.*} {http.reverse_proxy.*}
{resp.*} {http.intercept.*}
{scheme} {http.request.scheme}
{tls_cipher} {http.request.tls.cipher_suite}
{tls_client_certificate_der_base64} {http.request.tls.client.certificate_der_base64}
{tls_client_certificate_pem} {http.request.tls.client.certificate_pem}
{tls_client_fingerprint} {http.request.tls.client.fingerprint}
{tls_client_issuer} {http.request.tls.client.issuer}
{tls_client_serial} {http.request.tls.client.serial}
{tls_client_subject} {http.request.tls.client.subject}
{tls_version} {http.request.tls.version}
{upstream_hostport} {http.reverse_proxy.upstream.hostport}
{uri} {http.request.uri}
{vars.*} {http.vars.*}

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

Сниппеты

Вы можете определить специальные блоки, называемые сниппетами, присвоив им имя, заключённое в скобки:

(logging) {
	log {
		output file /var/log/caddy.log
		format json
	}
}

Затем вы можете повторно использовать его в любом месте, используя специальную директиву import:

example.com {
	import logging
}
www.example.com {
	import logging
}

Директива import также может использоваться для включения других файлов на её месте. Если аргумент не соответствует определённому сниппету, он будет проверен как файл. Она также поддерживает шаблоны для импорта нескольких файлов. В качестве специального случая, она может появиться в любом месте файла Caddy (кроме аргумента другой директивы), включая область вне блоков сайта:

{
	email admin@example.com
}
import sites/*

Вы можете передать аргументы в импортированную конфигурацию (сниппеты или файлы) и использовать их следующим образом:

(snippet) {
	respond "Yahaha! You found {args[0]}!"
}
a.example.com {
	import snippet "Example A"
}
b.example.com {
	import snippet "Example B"
}

⚠️ Экспериментально | v2.9.x+

Вы также можете передать необязательный блок в импортированный сниппет и использовать их следующим образом.

(snippet) {
	{block}
	respond "OK"
}
a.example.com {
	import snippet {
		header +foo bar
	}
}
b.example.com {
	import snippet {
		header +bar foo
	}
}

Прочитайте страницу директивы import, чтобы узнать больше.

Именованные маршруты

⚠️ Экспериментально

Именованные маршруты используют синтаксис, похожий на сниппеты; они являются специальным блоком, определённым вне блоков сайта, с префиксом &( и окончанием ), при этом имя находится между ними.

&(app-proxy) {
	reverse_proxy app-01:8080 app-02:8080 app-03:8080
}

Затем вы можете повторно использовать этот именованный маршрут в любом сайте:

example.com {
	invoke app-proxy
}
www.example.com {
	invoke app-proxy
}

Это особенно полезно для уменьшения использования памяти, если один и тот же маршрут необходим во многих разных сайтах или если требуется несколько различных условий сопоставления для вызова одного и того же маршрута.

Прочитайте страницу директивы invoke, чтобы узнать больше.

Комментарии

Комментарии начинаются с # и продолжаются до конца строки:

# Comments can start a line
directive  # or go at the end

Символ решётки # для комментария не может появиться посреди маркера (т. е. он должен предшествовать пробелу или появиться в начале строки). Это позволяет использовать решётки в URI или других значениях без необходимости использования кавычек.

Переменные окружения

Если ваша конфигурация зависит от переменных окружения, вы можете использовать их в файле Caddy:

{$ENV}

Переменные окружения в этой форме заменяются перед началом разбора файла Caddy, поэтому они могут расширяться до пустых значений (т. е. ""), частичных маркеров, полных маркеров или даже нескольких маркеров и строк.

Например, переменная окружения UPSTREAMS="app1:8080 app2:8080 app3:8080" будет расширена до нескольких маркеров:

example.com {
	reverse_proxy {$UPSTREAMS}
}

Значение по умолчанию можно указать, если переменная окружения не найдена, используя : в качестве разделителя между именем переменной и значением по умолчанию:

{$DOMAIN:localhost} {
}

Если вы хотите отложить замену переменной окружения до выполнения, вы можете использовать стандартные {env.*} заменители. Обратите внимание, что не все параметры конфигурации поддерживают эти заменители, так как разработчики модулей должны добавить строку кода для выполнения замены. Если это не работает, отправьте сообщение об ошибке, чтобы запросить поддержку.

Например, если у вас установлен плагин caddy-dns/cloudflare и вы хотите настроить DNS-вызов, вы можете передать свою переменную окружения CLOUDFLARE_API_TOKEN в плагин следующим образом:

{
	acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}

Если вы запускаете Caddy в качестве системной службы systemd, см. эти инструкции по настройке переопределений службы для определения ваших переменных окружения.

© 2015-2025 Matthew Holt and The Caddy Authors
Licensed under the Apache License 2.0.
Caddy is a registered trademark of Stack Holdings GmbH.
https://caddyserver.com/docs/caddyfile/concepts

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API