2026年9月26日

2026年9月26日

Caddy でリバースプロキシを設定する方法|Caddyfile の reverse_proxy・自動 HTTPS・ヘッダー・確認手順

Caddy でリバースプロキシを設定するには、Caddyfile にサイトアドレスと reverse_proxy <転送先> を書き、caddy run または caddy reload で読み込むだけです。公開ドメインを書けば証明書の取得と HTTP から HTTPS への転送も自動で行われるため、Nginx や Apache に比べて書く量がかなり少なくなります。

結論を先にまとめます。

  • 最小構成は example.com { reverse_proxy localhost:8080 } の 3 行です。
  • 自動 HTTPS が働くのは、DNS がこのサーバーを向いていて 80 番と 443 番が外から届く場合です。条件を満たさないと証明書の取得で止まります。
  • Caddy は既定で X-Forwarded-For、X-Forwarded-Proto、X-Forwarded-Host を付けて転送し、Host ヘッダーはそのまま渡します。外部から来た X-Forwarded-* は信用しません。
  • 設定を変えたら caddy validate で確認し、caddy reload で無停止反映します。
Caddy のリバースプロキシ設定の流れ。Caddy を入れる、Caddyfile を書く、DNS と 80/443 を通す、reload して curl で確認する

WordPress を Caddy の後ろに置くときの注意(実 IP、HTTPS 判定、リダイレクトループ)は、別記事の「Caddy を WordPress の前に置くリバースプロキシ構成」にまとめています。この記事は Caddy のリバースプロキシそのものの設定を扱います。

Caddy のリバースプロキシの特徴

Caddy は Go で書かれた Web サーバーで、設定ファイル Caddyfile と自動 HTTPS が特徴です。リバースプロキシは reverse_proxy ディレクティブが担当し、次のことを 1 つのディレクティブでまかないます(公式ドキュメント reverse_proxy)。

機能 設定 既定
転送先 reverse_proxy localhost:8080 など —
複数の転送先の振り分け lb_policy random
死活監視 health_uri(能動)/ fail_duration(受動) 無効
転送時のヘッダー header_up / header_down X-Forwarded-* を付与
転送先が HTTPS reverse_proxy https://backend TLS 検証あり
接続のタイムアウト transport http { dial_timeout 3s } など dial_timeout 3 秒

Nginx の proxy_pass と proxy_set_header を数行書く作業が、Caddy では既定値に含まれています。細かく変えたいときだけサブディレクティブを足します。

手順 1: Caddy をインストールする

Debian / Ubuntu では Caddy の公式リポジトリから入れます(公式のインストール手順)。パッケージを入れると caddy サービスが登録され、設定ファイルは /etc/caddy/Caddyfile です。

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
sudo apt update
sudo apt install caddy
caddy version

上のリポジトリの URL と鍵の場所は、公式ページの最新の記載を確認してから実行してください(2026年11月現在の公式手順です)。

手順 2: Caddyfile に reverse_proxy を書く

/etc/caddy/Caddyfile を次のように書き換えます。example.com はこのサーバーを向いている自分のドメイン、localhost:8080 はプロキシ先(アプリケーションサーバー)です。

example.com {
	reverse_proxy localhost:8080
}

これだけで、次の動きになります。

  • 443 番で example.com の HTTPS を受け、80 番への HTTP アクセスは HTTPS へ転送(リダイレクト)します。
  • 証明書は Let's Encrypt などの ACME 対応の認証局から自動で取得・更新します。
  • 受けたリクエストを localhost:8080 へ HTTP で転送し、応答をそのまま返します。

特定のパスだけをプロキシし、ほかは静的ファイルを返す構成は次のとおりです。

example.com {
	root * /var/www
	reverse_proxy /api/* localhost:5000
	file_server
}

転送先に HTTPS を使う場合は reverse_proxy https://backend.internal と書きます。転送先の証明書は検証されるので、自己署名証明書の内部サーバーなら transport http { tls_trust_pool file /path/ca.pem } のように信頼する CA を指定します。tls_insecure_skip_verify は公式ドキュメントが本番での使用を避けるよう明記しているオプションです。

手順 3: 自動 HTTPS の条件を満たす

Caddy の自動 HTTPS が有効になる条件は、公式ドキュメント Automatic HTTPS に次のように整理されています。

  • サイトアドレスがドメイン名(localhost や IP アドレスでない)で、ワイルドカードは左端 1 つまで。
  • そのドメインの DNS がこのサーバーを向いている。
  • 80 番と 443 番が外から到達できる(ファイアウォールやクラウドのセキュリティグループで開ける)。
  • Caddy がその 2 つのポートを待ち受けられる。
  • データディレクトリ(証明書の保存先)に書き込めて、再起動後も残る。

条件を満たさない場合、Caddy は証明書の取得を繰り返して失敗し、ログに ACME のエラーが出ます。社内だけで使うサーバーや、まだ DNS を切り替えていない段階では、サイトアドレスを http://example.com と書くか、グローバルオプションで自動 HTTPS を切ります。

{
	auto_https off
}

http://example.com {
	reverse_proxy localhost:8080
}

localhost を書いた場合は、Caddy が自前の認証局で証明書を発行して HTTPS にします。開発環境で便利ですが、公開サーバーでは公開ドメインを使ってください。

手順 4: ヘッダーと振り分けを調整する

転送時のヘッダー

Caddy は既定で、クライアントの IP を X-Forwarded-For に追加し、X-Forwarded-Proto(https か http か)と X-Forwarded-Host(元のホスト名)を設定して転送します。Host ヘッダーは受けたものをそのまま渡します。外から届いた X-Forwarded-* ヘッダーは、なりすましを防ぐため既定では無視されます。

ヘッダーを足したり変えたりするときは header_up(転送先へ)と header_down(クライアントへ)を使います。

example.com {
	reverse_proxy localhost:8080 {
		header_up X-Real-IP {remote_host}
		header_down -Server
	}
}

Caddy の前にさらに別のプロキシ(CDN やロードバランサー)がある場合は、グローバルオプションの servers { trusted_proxies static <範囲> } でそのプロキシの IP 範囲を信頼すると、X-Forwarded-For からクライアント IP を読み取るようになります。

複数の転送先

転送先を複数書くと振り分けます。既定は random で、round_robin、least_conn、ip_hash などに変えられます。能動的な死活監視は health_uri を書くと有効になり、既定では 30 秒ごとに確認します。

example.com {
	reverse_proxy app1:8080 app2:8080 {
		lb_policy round_robin
		health_uri /healthz
		health_interval 10s
	}
}

手順 5: 反映して確認する

設定を変えたら、まず文法を確認し、次に無停止で読み込みます。

caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
sudo journalctl -u caddy -n 50 --no-pager

caddy fmt --overwrite /etc/caddy/Caddyfile で整形もできます(Caddyfile はタブでのインデントが推奨です)。

動作確認は curl で行います。

# HTTP が HTTPS へ転送されるか
curl -sI http://example.com/ | head -n 3
# HTTPS で応答が返り、転送先のヘッダーが見えるか
curl -sI https://example.com/ | head -n 10
# 証明書の発行元
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -dates

転送先側で受け取っているヘッダーを確かめたいときは、転送先のアクセスログに X-Forwarded-For と X-Forwarded-Proto を出すか、一時的にリクエストヘッダーをそのまま返す小さなアプリを置くと分かります。

WordPress の観点

WordPress サイトに Caddy を使う構成は 2 つあります。

構成 Caddyfile の中心 向く場面
Caddy が PHP-FPM と直接やり取りする php_fastcgi unix//run/php/php8.3-fpm.sock と file_server 1 台で完結する一般的な WordPress
Caddy が後ろの Apache / Nginx へ転送する reverse_proxy 既存サーバーの前に HTTPS 終端として置く、複数サイトの入口を 1 つにする

後者では WordPress が「自分は HTTP で動いている」と判断してリダイレクトを繰り返す問題や、アクセス元 IP がすべて Caddy になる問題が起きます。対処は「Caddy を WordPress の前に置くリバースプロキシ構成」を参照してください。Web サーバーの選び方全般は「Apache と Nginx の違い」で扱っています。

よくある質問

Caddy のリバースプロキシで証明書が取れません

DNS がこのサーバーを向いているか、80 番と 443 番が外から届くか、Caddy がその 2 ポートを使えるか(他の Web サーバーが先に使っていないか)を順に確認します。journalctl -u caddy に ACME の失敗理由が出ます。DNS を切り替える前に試しているなら、http:// を付けたサイトアドレスで先にプロキシだけ動かします。

reverse_proxy の転送先にパスを書けますか

書けません。reverse_proxy localhost:8080/app のように転送先にパスやクエリを含めると設定エラーになります。パスを変えて転送したいときは handle_path や rewrite と組み合わせます。

Nginx の proxy_set_header に当たるものは何ですか

header_up です。ただし X-Forwarded-For、X-Forwarded-Proto、X-Forwarded-Host は Caddy が既定で付けるので、Nginx のように毎回書く必要はありません。Host を転送先のホスト名に変えたいときだけ header_up Host {upstream_hostport} を書きます。

設定を変えたら接続が切れますか

caddy reload(systemctl reload caddy)は無停止で設定を入れ替えます。文法エラーがあると新しい設定は適用されず、古い設定のまま動き続けるので、先に caddy validate で確認しておくと安全です。

まとめ

  • Caddy のリバースプロキシは example.com { reverse_proxy localhost:8080 } が最小構成で、HTTPS 化と HTTP からの転送は自動です。
  • 自動 HTTPS には DNS・80/443 番の到達・ポートの確保が必要で、満たせないときは http:// か auto_https off で切り替えます。
  • ヘッダーは既定で X-Forwarded-* が付き、変更は header_up。反映は caddy validate → caddy reload の順で行います。

関連記事

参考: Caddy – reverse_proxy (Caddyfile directive)、Caddy – Automatic HTTPS、Caddy – Global options、Caddy – Install

更新履歴: 2026-11-09 全面改訂(定型文の手順を Caddy 2 の公式ドキュメントに沿った設定手順に置き換え、自動 HTTPS の条件・ヘッダーの既定・確認コマンドを追加)。この記事はワードプレス博士(ライトセンド株式会社)が運営しています。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲