NginxとCaddyの違い:本番移行を検討する背景
Nginxは長年にわたりLinux上のリバースプロキシ・Webサーバとして標準的な選択肢であり続けています。一方、Caddyは2015年に登場し、バージョン2以降から本番利用に耐えうる安定性を備えるようになりました。
CaddyがNginxと大きく異なる点は、ACME(Automatic Certificate Management Environment)プロトコルによるTLS証明書の自動取得と自動更新を標準搭載していることです。Nginxでも Certbot や acme.sh を組み合わせることでLet’s Encryptの証明書を自動化できますが、設定ファイル・cronジョブ・systemdタイマーなど複数のコンポーネントを自前で管理する必要があります。Caddyはこれらを単一プロセスで完結させ、Caddyfileにドメイン名を記述するだけで証明書の取得・更新・HTTPSへのリダイレクトが自動的に行われます。
移行を検討する主な動機としては次のようなものが挙げられます。
- TLS証明書の期限切れ事故をなくしたい
- CertbotとNginx設定ファイルの二重管理を解消したい
- HTTP/3(QUIC)をシンプルに有効化したい
- 設定ファイルの記述量を削減したい
ただし、Nginxの複雑な rewrite ルールや upstream 設定を長期間運用してきた環境では、Caddyfileへの書き換えコストも発生します。全面移行の前に段階的な切替とロールバック設計を整えることが重要です。
移行前の準備と前提確認
本番移行を始める前に、以下の項目を確認します。
ドメインとDNSの確認
移行対象のドメインがサーバのパブリックIPを正しく指していることを確認します。CaddyのデフォルトはLet’s EncryptのHTTP-01チャレンジであるため、外部からポート80へのアクセスが可能である必要があります。ファイアウォールやセキュリティグループの設定も事前に確認しておきます。
Nginx設定とTLS証明書のバックアップ
切り戻しに備えて、Nginxの設定ディレクトリと既存証明書の格納パスを保存します。
sudo cp -r /etc/nginx /etc/nginx.bak.$(date +%Y%m%d)
sudo cp -r /etc/letsencrypt /etc/letsencrypt.bak.$(date +%Y%m%d)
Caddyのインストール
2026年時点のUbuntu 24.04 LTSやDebian 12では、Caddy公式リポジトリをaptに追加してインストールするのが標準的な方法です。
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 でバージョンを確認します。systemdサービスとして caddy.service が登録されていることも確認しておきます。
段階的な切替手順
ステップ1:Caddyをステージング状態で起動する
まずNginxを稼働させたまま、Caddyの設定ファイルを作成します。ポートの競合を避けるため、初期段階ではCaddyをポート8080で動作させ、設定の正当性を確認します。
/etc/caddy/Caddyfile の例(検証段階):
:8080 {
root * /var/www/example.com
file_server
encode gzip
log {
output file /var/log/caddy/access.log
}
}
シンタックスエラーがないことを確認してから起動します。
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl start caddy
sudo systemctl status caddy
本番TLS証明書の取得を事前にテストしたい場合、Let’s Encrypt Stagingサーバを使うとレート制限(週5回)を消費せずに動作確認ができます。Caddyfileの先頭ブロックに以下を追加します。
{
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}
ステップ2:本番ポートへの切替
Caddyの動作が確認できたら、アクセスの少ない時間帯を選んでNginxをシャットダウンし、Caddyを本番設定でリロードします。この切替時間がダウンタイムになります。
# Nginxを停止・無効化
sudo systemctl stop nginx
sudo systemctl disable nginx
# Caddyfileを本番設定に書き換えてリロード
sudo systemctl reload caddy
本番向けCaddyfileの基本構成(ドメイン名を直接記述するだけで自動HTTPSが有効になります):
example.com {
root * /var/www/example.com
file_server
encode gzip zstd
log {
output file /var/log/caddy/access.log
}
}
Caddyは起動時にZeroSSL(Caddy 2.4以降のデフォルトACMEプロバイダ)へ証明書発行リクエストを送り、HTTP→HTTPSリダイレクトを自動設定します。証明書はデフォルトで /var/lib/caddy/.local/share/caddy/certificates/ に保存されます。
ステップ3:リバースプロキシの設定
バックエンドアプリケーション(Node.js・Python・Goなど)へのリバースプロキシが必要な場合、Caddyfileの記述は1行で完結します。
example.com {
reverse_proxy localhost:3000
}
Nginxの proxy_pass + 各種 proxy_set_header に相当する設定が1行で完結します。X-Forwarded-For や Host ヘッダーの転送はCaddyがデフォルトで行うため、明示的な記述は不要です。
動作確認と検証ポイント
切替後は以下の項目を順に確認します。
TLS証明書の取得状態をログで確認する
sudo journalctl -u caddy --since "10 minutes ago" | grep -i "certificate"
certificate obtained successfully または served certificate が記録されていれば証明書取得は完了しています。エラーが出ている場合は、ファイアウォールのポート80開放状況とDNSレコードの伝播を確認します。
HTTP→HTTPSリダイレクトを確認する
curl -I http://example.com
レスポンスが 308 Permanent Redirect であれば正常です(Caddyはデフォルトで308を返します。Nginxの301を期待している設定がある場合は注意が必要です)。
アクセスログの形式を確認する
Caddyのデフォルトログ形式はJSON構造化ログです。fluentd・Promtail・Vectorなどのログ収集エージェントを使用している場合、パースの設定変更が必要になることがあります。Apache Combined Log形式が必要な場合は format single_field common_log オプションで変更できます。
Server ヘッダーの変更に注意する
CaddyはデフォルトでHTTPレスポンスに Server: Caddy ヘッダーを付与します。既存の監視ツールやWAFがサーバヘッダーの値をチェックしている場合は、設定を更新します。ヘッダーを非表示にしたい場合は header -Server ディレクティブで削除できます。
切り戻し手順と注意点
Caddyへの切替後に問題が発生した場合、Nginxへの切り戻しは以下の手順で行います。
# Caddyを停止
sudo systemctl stop caddy
# Nginxを再度有効化して起動
sudo systemctl enable nginx
sudo systemctl start nginx
# 状態確認
sudo systemctl status nginx
curl -I https://example.com
切り戻し時によくあるつまずきとして以下が挙げられます。
- Caddyがポート80/443を解放せずに停止した場合は
ss -tlnp | grep -E ':80|:443'でポートの占有状況を確認します。残留プロセスがある場合はsudo kill -9 <PID>で終了させます。 - Caddyが自動取得したTLS証明書はNginxでは利用できません。切り戻し後はCertbotが管理するNginx用証明書(
/etc/letsencrypt/live/)が有効であることを確認します。 - 切り戻し後にNginxの設定ファイルを参照しているsites-enabledのシンボリックリンクが正しいかを
nginx -tで確認します。
切り戻しまでの時間を短縮するために、Nginxのsystemdサービスを disable するだけにとどめ、設定ファイルやCertbotのタイマーは残しておくことを推奨します。完全に不要と判断できるまでは削除しないほうが安全です。
2026年時点の環境差分と注意事項
ZeroSSLがデフォルトACMEプロバイダになっている
Caddy 2.4以降、デフォルトのACMEサーバはLet’s EncryptからZeroSSLに変更されています。ZeroSSLもACMEプロトコルに対応しており、Let’s Encryptと同等に利用できますが、証明書の発行ポリシーや証明書ブランドが異なります。Let’s Encryptを明示的に使いたい場合はCaddyfileに以下を追記します。
{
acme_ca https://acme-v02.api.letsencrypt.org/directory
}
HTTP/3(QUIC)はUDPポート443の開放が必要
CaddyはデフォルトでHTTP/3を有効にしています。ファイアウォールでUDPポート443を閉じている環境ではHTTP/3ネゴシエーションが失敗しますが、HTTP/2にフォールバックするため通信自体は継続されます。HTTP/3を活用するにはUDPポート443の開放が必要です。クラウドプロバイダのセキュリティグループ設定も合わせて確認します。
systemdのネットワーク起動順序に注意する
Ubuntu 24.04 LTSやDebian 12では、systemdのサービス起動順序によってCaddyが起動してもネットワークがまだ利用できないケースがあります。Caddyのサービスファイルはデフォルトで After=network-online.target が指定されていますが、systemd-networkd-wait-online.service が正常に動作しているかを確認するとよいでしょう。起動直後のACMEチャレンジ失敗はこのタイミングの問題であることが一般的です。
Caddyfile構文の変更に注意する
2026年時点でCaddyの安定版は2.9系です。2.8以降、一部のディレクティブのパース処理が厳格化されており、古いバージョン向けの設定例がそのままでは動作しないケースがあります。特に tls ディレクティブと acme_ca グローバルオプションの組み合わせは、バージョンごとの公式ドキュメントで動作を確認することをお勧めします。
NginxとCaddyの同時稼働はできない
同一サーバ上でNginxとCaddyを同じポート(80/443)で同時稼働させることはできません。ロードバランサやL4スイッチが利用できる環境では、トラフィックを段階的に振り分ける方法も選択肢になりますが、単一サーバ構成ではメンテナンスウィンドウ内でのスナップショット切替が基本方針になります。切替前にはサーバのスナップショット(クラウドの場合はAMI・ディスクスナップショット)を取得しておくと、設定以外の問題が発生した際の復旧が容易になります。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
PR・広告
コマンド操作から基本運用までを手を動かして学べる定番書。記事で触れた技術の土台固めに。
※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。
