Nginx や Apache を使っていたサーバーを Caddy に乗り換えるとき、最初に詰まるのが 設定ファイルの書き方とHTSPS証明書の扱いです。Caddy は「ドメイン名を書くだけで自動HTTPS」という設計ですが、ファイルサーバーやリバースプロキシの応用設定になるといきなり情報が少なくなります。
この記事では、Ubuntu 24.04 に Caddy 2.11.4 をインストールしてから、ファイルサーバー・リバースプロキシ・自動HTTPS の3パターンを実際に設定・検証した手順を紹介します。
この記事のポイント
caddy validateで Caddyfile の構文エラーを事前にチェックできるfile_server browseでディレクトリ一覧UIが即座に使える- リバースプロキシで
X-Forwarded-Forは Caddy がデフォルトで付与するため明示不要 - 本番ドメインなら TLS 設定ゼロで Let’s Encrypt 証明書を自動取得・自動更新する
encode gzip1行で gzip 圧縮が有効になる
目次
Caddy 2.11.4 のインストール
Ubuntu 24.04 では、Caddy の公式リポジトリを追加してから apt でインストールします。Ubuntu のデフォルトリポジトリには古いバージョンが含まれることがあるので、公式の手順を使うのが確実です。

実際にコンテナで実行したログを見ると、GPGキーの取得からパッケージのインストール完了まで一連の流れが確認できます。ダウンロードサイズは 17.3 MB、展開後は 48.6 MB でした。
… (依存パッケージをインストール)
$ 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-get update && sudo apt-get install -y caddy
Get:1 … caddy 2.11.4 [17.3 MB]
Setting up caddy (2.11.4) …
$ caddy version
v2.11.4 h1:XKxkMTgNSizEvKG6QHue6cAsFOteU2qA61w2tKkCWi0=
$ which caddy && ls -lh $(which caddy)
/usr/bin/caddy
-rwxr-xr-x 1 root root 48M Jun 3 04:24 /usr/bin/caddy
バイナリは /usr/bin/caddy に配置されます。Caddy は Go 製のシングルバイナリなので、依存ライブラリがなく管理が楽です。
インストール後は systemd サービスとして登録されます。
$ sudo systemctl status caddy
● caddy.service – Caddy
Active: active (running) since Sun 2026-06-21 15:39:00 UTC; 2s ago
Main PID: 1234 (caddy)
Memory: 20.1 MiB
└─1234 /usr/bin/caddy run –environ –config /etc/caddy/Caddyfile
Caddyfile の基本構造
Caddy の設定ファイルは /etc/caddy/Caddyfile に置きます。Nginx の server {} ブロックに相当するのが、Caddy では 「アドレス + ブロック」の形式です。
:8080 {
root * /var/www/html
file_server
}
# ドメイン指定(自動HTTPS)
example.com {
reverse_proxy localhost:3000
}
設定を書いたら必ず caddy validate で構文チェックします。これをやらずに systemctl reload すると、エラー時に Caddy が止まります。
Valid configuration
$ sudo systemctl reload caddy
設定変更の流れ
Caddyfile を編集 → caddy validate で確認 → sudo systemctl reload caddy で反映。restart ではなく reload を使うと接続を切らずに設定を切り替えられます。
ファイルサーバーの設定
Caddy の file_server ディレクティブは、指定ディレクトリのファイルをそのまま配信します。browse オプションをつけると、ディレクトリ一覧をブラウザで見られるUIが自動で有効になります。

:8080 {
root * /var/www/files
file_server browse
encode gzip
}
$ caddy validate –config /etc/caddy/Caddyfile
Valid configuration
実際に起動した Caddy ファイルサーバーにブラウザでアクセスすると、次のような画面が表示されます。

ファイル名・サイズ・更新日時が一覧表示され、クリックでダウンロードできます。encode gzip を追加しているので、gzip 対応ブラウザへのレスポンスは自動的に圧縮されます。

サブディレクトリもそのままドリルダウンできます。社内ファイルサーバーやビルド成果物の配信用途では、Nginx で設定するより大幅に短い記述で同等の機能が実現できます。
特定ファイルを非表示にする
file_server に hide オプションを追加すると、特定のファイルやパターンを一覧から除外できます。設定ファイル自体を誤って公開するリスクを防ぐのに使います。
root * /var/www/files
file_server browse {
hide .env .git *.key
}
encode gzip
}
リバースプロキシの設定
reverse_proxy は Caddy で最もよく使うディレクティブです。ローカルで動いているアプリ(Node.js・Python・Go など)を外部に公開するために使います。

基本的なリバースプロキシ
reverse_proxy localhost:8000
}
これだけで、example.com へのアクセスがポート 8000 のアプリに転送されます。Let’s Encrypt 証明書の取得・更新も自動です(ドメインが正しく設定されていれば)。
パスベースのルーティング
APIエンドポイントだけ別のアップストリームに転送したい場合は、パスマッチを使います。
reverse_proxy /api/* localhost:3000 {
header_up X-Real-IP {remote_host}
}
header {
Access-Control-Allow-Origin *
-Server
}
}
$ caddy validate –config /etc/caddy/Caddyfile
Valid configuration
header -Server は Server ヘッダーを応答から削除するオプションです。バージョン情報の露出を避けたい場合に使います。
複数サブドメインをまとめて管理
reverse_proxy localhost:8000
}
api.example.com {
reverse_proxy localhost:3000
}
files.example.com {
root * /var/www/files
file_server browse
encode gzip
}
1ファイルに複数ブロックを並べるだけです。Nginx で複数の server_name を管理するよりずっとシンプルです。

自動HTTPS と証明書の扱い
Caddy で最も驚くのが TLS 周りの自動化です。本番ドメインなら設定ゼロで Let’s Encrypt 証明書を取得・更新します。

本番ドメインの場合
reverse_proxy localhost:8000
}
# ← TLS の設定は不要。ドメイン名を書くだけ。
ポート 80/443 が開いており、ドメインがこのサーバーに向いていれば、起動時に自動で証明書を取得します。証明書は ~/.local/share/caddy/ に保存され、有効期限前に自動更新されます。
グローバルオプションで ACME メールを設定
email admin@example.com
}
example.com {
reverse_proxy localhost:8000
}
グローバルブロック {} は Caddyfile の先頭に記述します。メールアドレスは Let’s Encrypt の重要通知(証明書の失効警告など)に使われるので、設定しておきます。
イントラネット・開発環境での内部CA
外部から到達できないサーバーや開発環境では、Let’s Encrypt は使えません。そのときは tls { internal } で Caddy の内部CAを使います。
tls {
internal
}
root * /var/www/files
file_server browse
}
$ sudo caddy trust
Successfully installed Caddy Local Authority root certificate
caddy trust でこのサーバーのルート証明書を OS の信頼ストアに追加します。他のクライアントからアクセスする場合は、~/.local/share/caddy/pki/authorities/local/root.crt を配布してインストールしてもらいます。
本番でのステージング ACME テスト
Let’s Encrypt には rate limit(1ドメインあたり週5回)があります。設定をテストするときは、グローバルブロックに acme_ca https://acme-staging-v02.api.letsencrypt.org/directory を追加してステージング ACME を使ってください。証明書は正式でないため警告が出ますが、発行フローは本番と同じです。
よくあるエラーと解決策
① caddy validate で構文エラー
Error: /etc/caddy/Caddyfile:3 expected expression, but got ‘}’
# → ブロックの閉じ括弧が多い、ディレクティブ名のスペルミスなど
エラーメッセージに行番号が出るので、その行前後を確認します。Caddyfile はインデントにタブを使うのが正式フォーマットです(caddy fmt --overwrite で自動整形できます)。
② ACME 証明書取得失敗
# → ドメインのDNSがこのサーバーを向いていない
# → ポート80/443がファイアウォールでブロックされている
原因は大体どちらかです。DNS の浸透を待ってから再起動するか、ufw allow 80 / ufw allow 443 でポートを開けます。
③ systemctl reload 後に 502 Bad Gateway
リバースプロキシ先のアプリが起動していないか、ポート番号が違います。ss -tlnp | grep ポート番号 でアプリが本当に動いているか確認します。
LISTEN 0 128 0.0.0.0:8000 …
# ← ポート8000でアプリが動いていることを確認
$ sudo journalctl -u caddy -f
# ← Caddy のリアルタイムログで詳細確認
まとめ
Caddy 2.11.4 の応用設定を Ubuntu 24.04 で実際に検証しました。
- インストールは公式リポジトリ追加 +
apt install caddy。バイナリは 48MB のシングルバイナリ file_server browseで静的ファイル配信とディレクトリUI が即座に使える- リバースプロキシは
reverse_proxy localhost:PORTの1行が基本。X-Forwarded-Forはデフォルトで付与されるため手書き不要 - 本番ドメインなら TLS の設定は不要。ドメイン名を書くと Let’s Encrypt が自動で動く
- イントラや開発環境は
tls { internal }で内部CA証明書を使える - 設定変更後は必ず
caddy validate→sudo systemctl reload caddyの順で
VPS で Caddy を運用するなら、スペックとコストのバランスが重要です。1vCPU/1GB RAM のプランでも十分に動きますが、複数ドメインや高トラフィック向けには余裕を持ったプランを選ぶといいです。
Ubuntu へのサーバー初期設定は 「Ubuntu VPS の初期セットアップ」 にまとめています。Caddy インストール前に SSH 設定・ファイアウォール設定を済ませておくと安全です。


コメント