Nginx の設定に疲れたら Caddy に移行しよう — 設定ファイル比較と移行手順
TL;DR
- Nginx の SSL 設定・certbot 更新・proxy_set_header の記述量に疲れた人向け
- Caddy はドメイン名を書くだけで自動 HTTPS + リバースプロキシが完成する
- Nginx → Caddy の移行手順を 3 パターン(単一サーバー・複数サービス・WebSocket)で解説
動作確認環境
- Ubuntu 24.04 LTS
- Caddy v2.9.x
- 移行元: Nginx 1.24.x + certbot
# Caddy インストール(Ubuntu/Debian)
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
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
なぜ Nginx から Caddy に移行するのか
設定量の差を見てほしい
Nginx: SSL + リバースプロキシ(19行)
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Caddy: 同じことをする設定(2行)
example.com {
reverse_proxy localhost:3000
}
Caddy はドメイン名を書くだけで以下を自動で行う:
- Let's Encrypt から SSL 証明書を取得
- 証明書の自動更新(期限 30 日前)
- HTTP → HTTPS リダイレクト
- 適切な
proxy_set_header相当のヘッダー付与 - HTTP/2 対応
- OCSP ステープリング
certbot の cron 設定も不要。ssl_protocols や ssl_ciphers の選定も不要。
移行パターン 1: 単一サービス
最もシンプルなケース。Next.js や Express が 1 つ動いている場合。
Before(Nginx)
# /etc/nginx/sites-enabled/myapp
server {
listen 80;
server_name myapp.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name myapp.example.com;
ssl_certificate /etc/letsencrypt/live/myapp.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
After(Caddy)
# /etc/caddy/Caddyfile
myapp.example.com {
reverse_proxy 127.0.0.1:3000
}
移行コマンド
# 1. Nginx を停止(port 80/443 を解放)
sudo systemctl stop nginx
sudo systemctl disable nginx
# 2. Caddyfile を作成
sudo tee /etc/caddy/Caddyfile << 'EOF'
myapp.example.com {
reverse_proxy 127.0.0.1:3000
}
EOF
# 3. Caddy を起動
sudo systemctl enable caddy
sudo systemctl start caddy
# 4. 証明書の自動取得を確認(数秒で完了)
sudo journalctl -u caddy --no-pager -n 20
# "certificate obtained successfully" が出れば OK
移行パターン 2: 複数サービス
API サーバー + フロントエンド + 管理画面など、1 台のサーバーで複数サービスを動かしている場合。
Before(Nginx)
# api.example.com
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
# ... header 設定省略
}
}
# app.example.com
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
# ... header 設定省略
}
}
# admin.example.com
server {
listen 443 ssl http2;
server_name admin.example.com;
ssl_certificate /etc/letsencrypt/live/admin.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:4000;
# ... header 設定省略
}
}
After(Caddy)
api.example.com {
reverse_proxy 127.0.0.1:8080
}
app.example.com {
reverse_proxy 127.0.0.1:3000
}
admin.example.com {
reverse_proxy 127.0.0.1:4000
}
3 ドメイン分の SSL 証明書が自動で取得・更新される。certbot の --expand オプションとの格闘が不要になる。
移行パターン 3: WebSocket 対応
チャットアプリや Socket.IO を使っているサービスの場合。
Before(Nginx)
server {
listen 443 ssl http2;
server_name ws.example.com;
# ... SSL 設定省略
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 86400;
}
}
After(Caddy)
ws.example.com {
reverse_proxy 127.0.0.1:3001
}
Caddy は WebSocket のアップグレードを自動で処理する。proxy_http_version や Upgrade ヘッダーの設定は不要。
注意点
Caddy が向かないケース
- 超高負荷(10 万 req/s 以上): Nginx の方がチューニングの余地が大きい
-
複雑なルーティングルール:
locationの正規表現マッチが多用されている場合、Caddy のhandle+pathに変換する手間がある - 既存の Nginx モジュール依存: Lua モジュールなど Nginx 固有の機能を使っている場合
certbot の証明書は削除してよいか
Caddy に移行したら certbot の証明書は不要。ただし、すぐに削除せず 1 週間ほど Caddy の自動取得が安定しているか確認してから削除するのが安全。
# Caddy の証明書状態確認
sudo caddy list-certs
# または
sudo journalctl -u caddy | grep -i "certificate"
まとめ
| 項目 | Nginx | Caddy |
|---|---|---|
| SSL 設定 | certbot + cron + 手動設定 | 自動(ゼロ設定) |
| 設定ファイル量 | 多い | 少ない |
| WebSocket | 明示的な設定が必要 | 自動対応 |
| パフォーマンス | 超高負荷向け | 中〜高負荷で十分 |
| 学習コスト | 高い | 低い |
個人開発やスタートアップ規模のサーバーなら、Caddy に移行するメリットは大きい。設定ファイルのメンテナンスコストが劇的に下がる。
Caddy のロードバランシング、キャッシュ戦略、セキュリティヘッダーなど、リバースプロキシの全機能については Caddy v2リバースプロキシ設定ガイド — 自動HTTPSで簡単構築 でまとめています。