Caddyfile のコンセプト
このドキュメントは HTTP Caddyfile の詳細について学ぶのに役立ちます。
構造
Caddyfile の構造は視覚的に説明できます
重要なポイント
-
オプションの グローバルオプションブロック は、ファイルの最初の行になります。
-
それ以外の場合は、Caddyfile の最初の行は 常に サービスを提供するサイトの アドレス です。
-
すべての ディレクティブ と マッチャ は 必ず サイトブロックに入れる必要があります。サイトブロック間でグローバルなスコープや継承はありません。
-
サイトブロックが 1 つしかない場合は、中括弧
{ }
はオプションです。
Caddyfile は 1 つ以上のサイトブロックで構成され、サイトの アドレス で必ず始まります。アドレスの前に表示されるディレクティブは、パーサーにとって混乱します。
ブロック
ブロック の開始と終了は中括弧で行われます
... {
...
}
-
開始中括弧
{
は行の最後になければならず、スペースが先行する必要があります。 -
終了中括弧
}
は行自体に表示する必要があります。
サイトブロックが 1 つしかない場合は、中括弧 (およびインデント) はオプションです。これは、1 つのサイトを素早く定義するために便利なもので、たとえばこれです
localhost
reverse_proxy /api/* localhost:9001
file_server
に相当します
localhost {
reverse_proxy /api/* localhost:9001
file_server
}
サイトブロックが 1 つしかない場合は、好みによってどちらか一方を使用できます。
同じ 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
はディレクティブです。ディレクティブとはサイトブロックの行で最初にくる単語です。
2 番目の例では、localhost:9000
はディレクティブの後に同じ行に登場するため、引数です。
ディレクティブは、独自のブロックを開くことができます。サブディレクティブはディレクティブブロック内の各行の先頭に表示されます
localhost {
reverse_proxy localhost:9000 localhost:9001 {
lb_policy first
}
}
ここでは、lb_policy
は reverse_proxy
のサブディレクティブです(バックエンド間で使用するロードバランシングポリシーを設定します)。
別途記載されていない限り、ディレクティブは他のディレクティブブロック内で使用できません。たとえば、basicauth
は file_server
内では使用できません。これはファイルサーバーが認証方法を知らないためです。一方、 route
、handle
、および handle_path
ブロックではディレクティブを使用できます。これらは特にディレクティブをグループ化するように設計されています。
HTTP の Caddyfile が調整されると、HTTP ハンドラディレクティブは特定のデフォルト ディレクティブの順序 に沿って並べ替えられます(route
ブロック内を除く)。したがって、ディレクティブの表示順は route
ブロックを除くすべてのブロックにおいて無関係です。
トークンと引用符
Caddyfile は、構文解析される前にトークンに解析されます。トークンは空白で区切られているため、Caddyfile では空白が重要です。
多くの場合、ディレクティブは特定数の引数を必要とします。1 つの引数が空白を含む値を持つ場合、2 つの個別トークンとして解析されます
directive abc def
これは問題を引き起こし、エラーや予期しない動作が発生する可能性があります。
abc def
が単一引数の値であると想定される場合は、引用符で囲む必要があります
directive "abc def"
引用符で囲まれたトークンで引用符を使用する必要がある場合は、引用符をエスケープできます
directive "\"abc def\""
引用符のエスケープを回避するには、代わりにバックスペース ` `
を使用してトークンを囲みます。たとえば
directive `{"foo": "bar"}`
引用符で囲まれたトークン内では、スペース、タブ、改行を含む他のすべての文字がそのまま処理されます。したがって、複数行のトークンを使用できます
directive "first line
second line"
ヒアドキュメント もサポートされています:
example.com {
respond <<HTML
<html>
<head><title>Foo</title></head>
<body>Foo</body>
</html>
HTML 200
}
ヒアドキュメントの開始マーカーは <<
で始まり、任意のテキスト(大文字が推奨)が続きます。ヒアドキュメントの終了マーカーは同じテキスト(上の例では HTML
)にする必要があります。必要に応じて、開始マーカーを \<<
でエスケープしてヒアドキュメントの構文解析を防止できます。
終了マーカーをインデントすると、テキストの各行からインデントが取り除かれます(PHP から着想)。これは、ブロック 内で可読性を向上させるのに適していますが、トークンテキスト内の空白を十分に制御できます。末尾の改行も削除されますが、終了マーカーの前に空白行を追加することで保持できます。
終了マーカーの後に追加のトークンをディレクティブの引数として続けることができます(上の例ではステータスコード 200
)。
グローバルオプション
Caddyfile は、キーを持たない特殊なブロック(グローバルオプションブロック)で始まる場合があります
{
...
}
存在する場合は、設定ファイルの最初のブロックである必要があります。
グローバルに適用されるオプション、または特定のサイトに適用されないオプションを設定するために使用されます。内部では、グローバルオプションのみを設定できます。通常のサイトディレクティブは使用できません。
たとえば、トラブルシューティングのために冗長ログを出力するために一般的に使用される debug
グローバルオプションを有効にするには
{
debug
}
グローバルオプションページ で詳細をご確認ください
アドレス
アドレスは常にサイトブロックの先頭に表示され、通常は Caddyfile の最初の項目です。
以下は有効なアドレスの例です
アドレス | 効果 |
---|---|
example.com |
管理対象公開信用証明書のHTTPS |
*.example.com |
管理対象ワイルドカード公開信用証明書のHTTPS |
localhost |
管理対象ローカル信用証明書のHTTPS |
http:// |
http_port の影響を受ける、HTTPのキャッチオール |
https:// |
https_port の影響を受ける、HTTPSのキャッチオール |
http://example.com |
Host マッチャーを使用した明示的なHTTP |
example.com:443 |
https_port のデフォルトにマッチするためにHTTPS |
:443 |
https_port のデフォルトにマッチするためにHTTPSのキャッチオール |
:8080 |
非標準ポートのHTTP、Host マッチャーなし |
localhost:8080 |
有効なドメインを持つため、非標準ポートのHTTPS |
https://example.com:443 |
HTTPSだが、https:// と:443 の両方が冗長 |
127.0.0.1 |
ローカル信用IP証明書のHTTPS |
http://127.0.0.1 |
IPアドレスHost マッチャーのHTTP(localhost を拒否) |
アドレスから、Caddyはサイトのスキーム、ホスト、ポートを推測できます。アドレスにポートがない場合、Caddyfileは指定されている場合はスキームに一致するポートを選択するか、またはデフォルトポートの443が想定されます。
ホスト名を指定した場合、一致するHost
ヘッダーを持つリクエストのみが有効になります。言い換えると、サイトアドレスがlocalhost
の場合、Caddyは127.0.0.1
へのリクエストと一致しません。
ワイルドカード(*
)を使用できますが、ホスト名のラベルを正確に1つのみ表す必要があります。たとえば、*.example.com
はfoo.example.com
と一致しますがfoo.bar.example.com
とは一致せず、*
はlocalhost
とは一致しますがexample.com
とは一致しません。ワイルドカード証明書パターンで実際的な例を参照してください。
全ホストをキャッチするには、アドレスからホスト部分を省略します。たとえば、単にhttps://
のようにします。これはオンデマンドTLSを使用する場合に、事前にドメインがわかっていない場合に便利です。
複数のサイトが同じ定義を共有する場合は、スペースまたはコンマを使用してすべてのサイトを一緒にリストできます。次の3つの例は同等です。
# 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
次の引数がパスマッチャーのように見えない場合は、マッチャートークンを完全に省略してすべてのリクエストと一致させることができます。
リクエストマッチャープールを読み、詳細を確認してください。
プレースホルダー
Caddyfileで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.*} |
{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
ディレクティブは、他のファイルをその場所に含めるために使用することもできます。引数が定義されたスニペットと一致しない場合、ファイルとして試行されます。また、複数のファイルをインポートするためのグロブもサポートしています。特殊なケースとして、サイトブロックの外側など、Caddyfile の任意の場所 (別のディレクティブへの引数として使用する場合を除く) に表示できます。
{
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"
}
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 やその他の値内のハッシュを、引用符を必要とせずに使用できます。
環境変数
構成が環境変数に依存する場合、Caddyfile で使用できます。
{$ENV}
この形式の環境変数は Caddyfile の解析が始まる前に置換されるため、空の値 (つまり ""
)、部分トークン、完全トークン、または複数のトークンと行にまで展開できます。
例えば、環境変数 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サービスとして実行している場合は、この手順を参照して、サービスオーバーライドを設定して環境変数を定義してください。