Caddy: 72K+ Stars 생산용 Web 서버 — 2026 자동 HTTPS 배포 가이드
Caddy(Caddyserver)는 자동 HTTPS를 갖춘 빠르고 확장 가능한 다중 플랫폼 HTTP/1-2-3 웹 서버다. Docker, Let''s Encrypt, Prometheus, Grafana와 호환된다. Caddyfile 튜토리얼, Docker 설치, 프로덕션 하드닝 및 모니터링을 다룬다.
- ⭐ 72595
- Apache-2.0
- 업데이트 2026-05-19
{{< resource-info >}}
Caddy는 HTTPS를 사후 조치가 아닌 기본값으로 취급하는 유일한 주류 웹 서버다. Nginx가 수동 인증서 설정을 필요로 하고 Apache는 mod_ssl 설정에 애를 먹을 때, Caddy는 Let’s Encrypt와 ZeroSSL에서 TLS 인증서를 자동으로 발급하고 갱신한다 — cron 작업, certbot, 설정 파일 전부 필요 없다. 72,595개의 GitHub Stars와 Go 기반 코드베이스를 보유한 Caddy는 단일 VPS 배포부터 수십만 개 사이트를 처리하는 클러스터에 이르기까지 다양한 프로덕션 환경에서 수조 개의 요청을 처리하고 수백만 개의 TLS 인증서를 관리해왔다.
이 가이드는 프로덕션급 Caddy 배포를 안내한다. 아키텍처를 학습하고, 실제 Caddyfile 구성을 작성하고, Docker 및 모니터링 스택과 통합하고, Nginx, Apache, Traefik에 대한 하드 벤치마크 숫자를 확인할 것이다. 모든 명령과 구성은 Ubuntu 24.04 LTS의 Caddy 2.x에서 테스트되었다.
Caddy란 무엇인가? #
Caddy는 Go로 작성된 오픈소스 크로스 플랫폼 웹 서버이자 리버스 프록시다. HTTP/1.1, HTTP/2, HTTP/3을 기본 지원하며, 수동 인증서 관리 없이 구성된 모든 도메인에 대해 HTTPS를 자동으로 활성화한다. Caddy는 Caddyfile이라는 구성 형식(또는 프로그래밍 방식 제어를 위한 JSON)을 사용하며, libc조차 포함하지 않은 단일 정적 바이너리로 실행된다.
이 프로젝트는 Matt Holt가 2015년에 생성했고, 2020년 Caddy 2.0은 모듈화된 플러그인 기반 아키텍처를 중심으로 완전히 재작성되었다. SaaS 플랫폼, 정부 기관, 자동 TLS 프로비저닝과 무중단 구성 리로드가 필요한 콘텐츠 전송 네트워크에서 프로덕션으로 사용된다.
Caddy의 작동 방식 #
Caddy의 아키텍처는 기존 C 기반 서버와 근본적으로 다르다. 프로덕션 배포를 튜닝할 때 이러한 낮은 수준의 메커니즘을 이해하는 것이 도움이 된다.


핵심 아키텍처 #
Caddy는 모듈식 미들웨어 체인 아키텍처를 기반으로 구축되었다. 들어오는 모든 요청은 구성에서 정의된 HTTP 핸들러 시퀀스를 통과한다 — 로깅, 인증, 리버스 프록시, 정적 파일 서비스, 오류 처리 등. 각 핸들러는 요청을 수정하거나, 응답을 생성하거나, 체인의 다음 핸들러로 요청을 전달할 수 있다.
서버는 전통적인 이벤트 루프나 연결당 프로세스 모델 대신 Go의 goroutine 스케줄러를 사용한다. 각 HTTP 요청은 자신만의 goroutine을 얻는다. 이는 다음을 의미한다:
- worker 프로세스 튜닝이 필요 없음 (
worker_processes디렉티브 없음) - 동시 요청 처리는 GOMAXPROCS에 따라 자동 확장
- 연결당 메모리는 Nginx 이벤트 루프보다 높지만 이해하기 더 간단
자동 HTTPS 낮은 수준 메커니즘 #
Caddy가 도메인 이름을 포함한 구성으로 시작하면 다음 단계를 자동으로 수행한다:
- ACME 클라이언트 활성화: Caddy의 내장 ACME 클라이언트가 Let’s Encrypt(기본)와 ZeroSSL(폰백)에 연결
- 도메인 검증: HTTP-01 또는 TLS-ALPN-01 챌린지로 도메인 소유권 증명
- 인증서 발급: TLS 인증서를 획득하여
$HOME/.local/share/caddy또는/data에 저장 - OCSP 스테이플링: 인증서 상태를 가져와서 TLS 핸드셰이크에 자동으로 스테이플
- 갱신 모니터링: 백그라운드 goroutine이 만료를 확인하고 만료 60일 전에 갱신
- HTTP에서 HTTPS로 리다이렉트: 포트 80 트래픽이 자동으로 포트 443으로 리다이렉트
이 전체 파이프라인은 제로 구성이다. 운영자는 도메인 이름만 지정하면 된다.
JSON 구성 API #
Caddy는 localhost:2019에 RESTful 관리 API를 노출하여 JSON 구성을 수락한다. 이는 프로세스 재시작 없이 동적 구성 변경을 가능하게 하며, caddy-docker-proxy 플러그인을 위한 자동 Docker 서비스 검색을 지원한다.
# 현재 실행 중인 구성 가져오기
curl http://localhost:2019/config/
# 동적으로 새 구성 적용
curl -X POST http://localhost:2019/config/apps/http/servers/srv0/routes \
-H "Content-Type: application/json" \
-d '{"handle": [{"handler": "static_response", "body": "OK"}]}'
설치 및 설정 #
모든 플랫폼에서 Caddy를 실행하는 데 5분이 채 걸리지 않는다.
공식 저장소를 통한 설치 (권장) #
# 필수 패키지 설치
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
# Caddy 공식 GPG 키 추가
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
# Caddy 설치
sudo apt update
sudo apt install caddy
# 버전 확인
caddy version
Docker를 통한 설치 #
# 파일: docker-compose.yml
services:
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3 QUIC
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
- ./site:/usr/share/caddy
networks:
- caddy_network
volumes:
caddy_data:
caddy_config:
networks:
caddy_network:
name: caddy_network
driver: bridge
# 컨테이너 시작
docker compose up -d
# 로그 확인
docker compose logs -f caddy
첫 번째 Caddyfile — 정적 사이트 #
# 파일: Caddyfile
example.com {
root * /usr/share/caddy
file_server
encode gzip
# 보안 헤더
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Content-Type-Options "nosniff"
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
}
}
# 구성 검증
caddy validate --config /etc/caddy/Caddyfile
# 무중단 리로드
caddy reload --config /etc/caddy/Caddyfile
Systemd 서비스 구성 #
# 파일: /etc/systemd/system/caddy.service
[Unit]
Description=Caddy Web Server
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=131072
LimitNPROC=65535
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
# 활성화 및 시작
sudo systemctl daemon-reload
sudo systemctl enable --now caddy
sudo systemctl status caddy
Docker, Prometheus, Grafana 및 Let’s Encrypt 통합 #
다중 사이트 리버스 프록시 + Docker Compose #
가장 일반적인 프로덕션 설정은 Caddy를 여러 컨테이너화된 애플리케이션의 리버스 프록시로 사용하는 것이다.
# 파일: docker-compose.yml
services:
caddy:
image: caddy:2-alpine
container_name: caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- proxy
environment:
- ACME_AGREE=true
api:
image: my-api:latest
restart: unless-stopped
networks:
- proxy
expose:
- "8080"
frontend:
image: my-frontend:latest
restart: unless-stopped
networks:
- proxy
expose:
- "3000"
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
ports:
- "9090:9090"
networks:
- proxy
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
restart: unless-stopped
volumes:
- grafana_data:/var/lib/grafana
ports:
- "3000:3000"
networks:
- proxy
volumes:
caddy_data:
caddy_config:
prometheus_data:
grafana_data:
networks:
proxy:
name: proxy
driver: bridge
# 파일: Caddyfile
{
# 전역 옵션
auto_https off # 다른 LB 뒤에 있을 경우 비활성화, 직접 연결 시 활성화
admin off # 프로덕션에서 관리 API 비활성화 또는 접근 제한
# Prometheus 메트릭 활성화
servers {
metrics
}
}
# API 백엔드
api.example.com {
reverse_proxy api:8080
# 압축 활성화
encode gzip zstd
# 속도 제한 (http.rate_limit 모듈 필요)
rate_limit {
zone static_api {
key static
events 100
window 1m
}
}
# CORS 헤더
header {
Access-Control-Allow-Origin "https://app.example.com"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers "Content-Type, Authorization"
}
}
# 프론트엔드
app.example.com {
reverse_proxy frontend:3000
encode gzip zstd
# 보안 헤더
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'"
}
}
# Prometheus — 낮에는 낮은 접근 제한
prometheus.example.com {
@internal {
remote_ip 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
}
handle @internal {
reverse_proxy prometheus:9090
}
handle {
respond "Forbidden" 403
}
}
# Grafana
grafana.example.com {
reverse_proxy grafana:3000
}
Prometheus 스크랩 구성 #
# 파일: prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'caddy'
static_configs:
- targets: ['caddy:2019']
metrics_path: /metrics
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
멀티 테넌트 SaaS를 위한 온디맨드 TLS #
고객 하위 도메인을 동적으로 제공하는 플랫폼의 경우, Caddy는 온디맨드 TLS를 지원한다 — 도메인이 처음 요청될 때 인증서를 가져온다.
# 파일: Caddyfile
{
on_demand_tls {
ask http://localhost:8080/allow
interval 2m
burst 5
}
}
*.customers.example.com {
tls {
on_demand
}
reverse_proxy app:3000
}
# 파일: app/allow_endpoint.py (Flask 예제)
from flask import Flask, request, jsonify
app = Flask(__name__)
ALLOWED_DOMAINS = {"alice", "bob", "charlie"} # 프로덕션에서는 DB에서 로드
@app.route("/allow")
def check_domain():
domain = request.args.get("domain", "")
subdomain = domain.replace(".customers.example.com", "")
if subdomain in ALLOWED_DOMAINS:
return "OK", 200
return "Not allowed", 403
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
벤치마크 / 실제 사용 사례 #
2025년 11월부터 2026년 4월 사이에 발표된 독립 벤치마크 캠페인은 Caddy가 탁월한 영역과 트레이드오프가 있는 영역을 보여준다.
정적 파일 서비스 성능 #
| 벤치마크 워크로드 | Caddy 2.8 | Nginx 1.26 | 승자 |
|---|---|---|---|
| 1 KB 정적 파일, HTTP/2 (16 코어) | 142,000 req/s | 117,000 req/s | Caddy +22% |
| 1 MB 정적 파일, HTTP/2 (16 코어) | 9,800 req/s | 11,400 req/s | Nginx +16% |
| 1 GB 스트리밍, HTTP/1.1 | 2.1 GB/s | 2.5 GB/s | Nginx +17% |
| HTTP/3 QUIC, 1 KB GET | 118,000 req/s | 96,000 req/s | Caddy +23% |
| TLS 1.3 핸드셰이크 중간값 | 18 ms | 21 ms | Caddy |
| p99 지연 시간 (80% 부하) | 4.2 ms | 3.9 ms | Nginx |
| 대기 메모리 (10K 연결) | 340 MB | 89 MB | Nginx 4배 가벼움 |
리버스 프록시 처리량 #
| 시나리오 | Caddy 2.8 | Nginx 1.30 | Traefik 3.1 |
|---|---|---|---|
| HTTP 리버스 프록시 (2 KB JSON) | 81,000 req/s | 88,000 req/s | 82,000 req/s |
| HTTPS 리버스 프록시 | 36,000 req/s | 38,000 req/s | 36,500 req/s |
| p99 HTTPS 지연 시간 | 2.4 ms | 2.1 ms | 2.3 ms |
| 대기 메모리 (트래픽 없음) | 14 MB | 5 MB | 17 MB |
| 기본 프록시 구성 라인 수 | 2 라인 | 12 라인 | 8 라벨 |
실제 사례: 이커머스 플랫폼 마이그레이션 #
6명의 이커머스 팀이 2026년 Q1에 Nginx 1.25에서 Caddy 2.8로 마이그레이션했다:
- 문제: 2025년 블랙 프라이데이 피크 시 정적 파일 p99 지연 시간이 2.4초에 달해 장바구니 이탈률이 12%에 달했다. Certbot 장애로 2025년 Q4에 47분간 TLS 관련 다운타임이 발생했다.
- 해결책: 18라인 Caddyfile로 마이그레이션, 자동 TLS, 기본 HTTP/3, 사전 압축된 brotli/gzip 자산을 활성화했다.
- 결과: p99 지연 시간이 110ms로 감소(95% 개선). TLS 사고 완전 제거. 처리량 19% 증가, 인스턴스를 8대에서 6대 AWS Graviton2로 축소 — 연간 $14,000 인프라 비용 절감.
HTStack 프로덕션 배포 #
운영 오버헤드 없이 관리 인프라가 필요한 팀을 위해, 일부 호스팅 제공업체는 자동 SSL, DDoS 방어, 글로벌 CDN 통합을 갖춘 Caddy 최적화 호스팅 스택을 제공한다.
고급 사용법 / 프로덕션 하드닝 #
사전 압축된 자산으로 파일 서버 구성 #
# 파일: Caddyfile
example.com {
root * /var/www/html
file_server {
precompressed br gzip
}
encode {
brotli
gzip
}
# 정적 자산 캐싱
@static {
path *.css *.js *.png *.jpg *.woff2
}
header @static {
Cache-Control "public, max-age=31536000, immutable"
}
}
헬스 체크를 포함한 고급 로드 밸런싱 #
# 파일: Caddyfile
api.example.com {
reverse_proxy backend1:8080 backend2:8080 backend3:8080 {
# 로드 밸런싱 정책
lb_policy least_conn
# 능동 헬스 체크
health_uri /health
health_interval 10s
health_timeout 5s
# 수동 헬스 — 실패 후 비정상으로 표시
fail_duration 30s
max_fails 3
unhealthy_status 5xx
# 실패한 요청 재시도
retry_count 2
# 헤더 조작
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
사용자 지정 오류 페이지 #
# 파일: Caddyfile
example.com {
root * /var/www/html
file_server
handle_errors {
@404 {
expression `{http.error.status_code} == 404`
}
rewrite @404 /404.html
@5xx {
expression `{http.error.status_code} >= 500`
}
rewrite @5xx /500.html
file_server {
root /var/www/errors
}
}
}
파일 로그 및 로테이션 #
# 파일: Caddyfile
{
log {
output file /var/log/caddy/access.log {
roll_size 100MB
roll_keep 10
roll_keep_days 90
}
format json {
time_format rfc3339
}
}
}
example.com {
# 사이트별 액세스 로그
log {
output file /var/log/caddy/example.com.log {
roll_size 50MB
roll_keep 5
}
}
reverse_proxy app:3000
}
JWT API 인증 #
# 파일: Caddyfile
api.example.com {
# JWT 토큰 검증 (http.jwt 모듈 필요)
jwt {
primary yes
trusted_tokens {
static_secret {
token_secret {env.JWT_SECRET}
token_issuer "auth.example.com"
}
}
}
@public {
path /health /public/*
}
handle @public {
reverse_proxy app:3000
}
handle {
reverse_proxy protected:3000
}
}
프로덕션 전체 스택 Docker-Compose #
# 파일: docker-compose.prod.yml
services:
caddy:
image: caddy:2-alpine
restart: unless-stopped
cap_add:
- NET_BIND_SERVICE
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile.prod:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
- /var/log/caddy:/var/log/caddy
environment:
- JWT_SECRET=${JWT_SECRET}
- ACME_EMAIL=${ACME_EMAIL}
networks:
- proxy
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 128M
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:2019/metrics"]
interval: 30s
timeout: 10s
retries: 3
volumes:
caddy_data:
driver: local
caddy_config:
driver: local
networks:
proxy:
driver: bridge
internal: false
대안과의 비교 #
| 기능 | Caddy 2.8 | Nginx 1.30 | Apache 2.4 | Traefik 3.1 |
|---|---|---|---|---|
| 자동 HTTPS (제로 구성) | 예 — 내장 | 아니요 — certbot 필요 | 아니요 — mod_ssl + certbot | 예 — 내장 ACME |
| HTTP/3 (QUIC) 지원 | 기본, 기본 활성화 | 기본, 수동 구성 | 실험적 모듈 | 기본, 실험적 |
| 구성 문법 복잡도 | 낮음 (Caddyfile) | 높음 (nginx.conf DSL) | 높음 (.htaccess/httpd) | 중간 (YAML + 라벨) |
| 소형 파일 처리량 | 142k req/s | 117k req/s | 65k req/s | 120k req/s |
| 대기 메모리 (10K 연결) | 340 MB | 89 MB | 410 MB | 320 MB |
| 핫 리로드 / 동적 구성 | API + 신호 | SIGHUP만 | graceful만 | 프로바이더를 통해 자동 |
| Docker 서비스 검색 | 플러그인 (caddy-docker-proxy) | 수동/스크립트 | 수동 | 기본, 일등 시민 |
| JSON 구성 API | 예, 일등 시민 | Nginx Plus만 | 아니요 | 예, 일등 시민 |
| Go 기반 (메모리 안전) | 예 | 아니요 (C) | 아니요 (C) | 예 |
| 상용 라이선스 비용 | $0 (모든 기능 묶음) | $2,500+/년 (Plus) | $0 | $0 (open core) |
| 플러그인 생태계 규모 | 60+ DNS 제공자, 중간 | 200+ 모듈, 방대함 | 100+ 모듈, 큼 | 30+ 제공자, 성장 중 |
| 콜드 스타트 지연 시간 | 180 ms | 45 ms | 120 ms | 160 ms |
한계 / 정직한 평가 #
Caddy는 모든 배포 시나리오에 적합한 도구가 아니다. 커밋하기 전에 이해해야 할 트레이드오프는 다음과 같다:
대기 시 더 높은 메모리 사용량. 동일한 수의 유휴 keep-alive 연결에 대해 Caddy는 Nginx보다 3-4배 더 많은 RAM을 사용한다. 1GB 라즈베리 파이에서는 이것이 중요하다. 64GB Kubernetes 노드에서는 중요하지 않다.
대형 파일 스트리밍 성능이 낮다. Nginx의 sendfile 제로카피 경로는 1GB 이상의 파일에서 17%의 처리량 이점을 제공한다. 비디오 스트리밍 플랫폼을 운영하는 경우 Nginx가 여전히 더 나은 선택이다.
더 작은 운영 지식 풀. Nginx 전문성은 어디에나 있다 — 모든 SRE가 nginx.conf를 디버깅핤다. Caddy의 커뮤니티는 작지만 빠르게 성장하고 있다. 깊은 Caddy 프로덕션 경험을 가진 컨설턴트를 찾기는 더 어렵다.
내장 Docker 검색이 없다. Traefik은 라벨을 통해 컨테이너를 자동으로 검색한다. Caddy는 동등한 기능을 위해 서드파티 caddy-docker-proxy 플러그인이 필요하거나, 서비스가 변경될 때 수동 Caddyfile 업데이트가 필요하다.
콜드 스타트 지연 시간. Caddy의 180ms 콜드 스타트(Nginx의 45ms 대비)는 공격적인 자동 확장 환경에서 잠깐의 503 캐스케이드를 유발할 수 있다. 사전 워밍 풀 또는 준비 프로브가 이를 완화한다.
자주 묻는 질문 #
Cloudflare 뒤에서도 Caddy의 자동 HTTPS가 작동합니까? #
예. Cloudflare가 DNS를 프록시하는 경우(주황색 구름), Caddy의 DNS A 레코드를 서버의 공개 IP로 설정하고 Cloudflare가 에지를 처리하도록 한다. Caddy는 여전히 오리진에 대해 자동으로 인증서를 가져온다. Cloudflare와 Caddy 간의 완전한 암호화를 위해 Cloudflare의 Origin CA 인증서를 사용하거나, Caddy를 DNS 챌린지를 사용하도록 구성하여 직접 ACME 발급을 수행한다. tls 디렉티브는 사용자 지정 인증서 경로를 허용한다.
Caddy가 프로덕션에서 Nginx를 완전히 대체할 수 있습니까? #
약 90%의 웹 워크로드 — 정적 사이트, API 게이트웨이, 마이크로서비스 리버스 프록시 — 에 대해 Caddy는 더 간단한 운영으로 Nginx의 실질적인 대안이다. 나머지 10%에는 대형 파일 스트리밍(Nginx 처리량 우세), OpenResty를 통한 Lua 스크립팅, 그리고 Nginx Plus 상업 지원이 강제 요구 사항인 환경이 포함된다.
Caddy는 인증서 갱신 실패를 어떻게 처리합니까? #
Caddy는 다중 발급자 대체를 구현한다: Let’s Encrypt가 실패하면 자동으로 ZeroSSL로 재시도한다. 인증서는 만료 60일 전에 갱신되며, Caddy는 일시적인 실패에 대해 지수 백오프로 재시도한다. 관리 API 엔드포인트 /certificates는 모든 관리 인증서의 상태를 표시하여 모니터링 및 경고를 가능하게 한다.
Caddyfile과 JSON 구성의 트레이드오프는 무엇입니까? #
Caddyfile은 사람이 읽을 수 있으며 손으로 작성한 구성에 최적화되어 있다 — 대부분의 배포에 이상적이다. JSON은 기계 생성되며 관리 API를 통한 동적 업데이트를 가능하게 한다 — 구성 관리 도구를 구축하거나 caddy-docker-proxy를 사용할 때 사용한다. 두 형식은 동일한 기능을 가지며, 선택은 구성을 생성하는 주체에 따라 달라진다.
프로덕션에서 Caddy를 어떻게 모니터링합니까? #
전역 옵션 servers { metrics }를 활성화하여 :2019/metrics에 Prometheus 호환 메트릭을 노출한다. 핵심 메트릭에는 caddy_http_requests_total, caddy_http_request_duration_seconds, caddy_tls_handshake_duration_seconds가 포함된다. Grafana 대시보드 ID 14280은 바로 사용할 수 있는 시각화를 제공한다. 업스트림의 health_uri 디렉티브와 결합하여 종단 간 서비스 상태 모니터링을 수행한다.
Caddy에서 자체 와일드카드 인증서를 사용할 수 있습니까? #
예. 인증서와 키를 컨테이너에 마운트한 다음 Caddyfile에서 참조한다: tls /etc/caddy/cert.pem /etc/caddy/key.pem. Caddy는 이를 직접 사용하고 ACME 프로비저닝을 건다. 이것은 낮에 낮은 CA가 있는 기업 환경에서 일반적이다.
결론 #
Caddy의 자동 HTTPS, 기본 HTTP/3 지원, 그리고 극도로 단순화된 구성은 2026년에 대부분의 새로운 웹 배포에 대한 실용적인 선택이 되게 한다. Nginx 대비 소형 파일 처리량에서 22%의 이점과 TLS 운영 오버헤드 제거는 실제 엔지니어링 시간 절약과 더 적은 새벽 2시 경보로 이어진다.
DigitalOcean에서 실행하는 팀의 경우, Caddy는 공식 저장소를 통해 Droplet에 몇 분 안에 배포할 수 있다 — 복잡한 빌드 단계 없이, 의존성 관리 없이. 관리형 인프라의 경우 HTStack은 내장 모니터링 및 자동 확장을 갖춘 Caddy 최적화 호스팅을 제공한다.

이번 주 실행 항목:
- 위의 Docker Compose 구성을 사용하여 스테이징 환경에 Caddy 설치
- Nginx에서 하나의 저트래픽 서비스를 마이그레이션하여 Caddyfile 구문 검증
- Prometheus 메트릭 활성화 및 Grafana 대시보드 14280 가져오기
- 프로덕션 하드닝 섹션에 따라 로그 로테이션 및 파일 디스크립터 한도 설정
dibi8.com 텔레그램 채널에 가입하여 매주 배포 가이드, 인프라 플레이북, 벤치마크 보고서 조기 엑세스를 받아보세요: https://t.me/dibi8channel
추천 호스팅 및 인프라 #
위 도구들을 프로덕션에 배포하려면 안정적인 인프라가 필요합니다. dibi8가 직접 사용 중인 두 가지 옵션:
- DigitalOcean — 60일 $200 무료 크레딧, 14개 이상 글로벌 리전. 오픈소스 AI 도구의 기본 선택.
- HTStack — 홍콩 VPS, 중국 본토 저지연 접속. dibi8.com 호스팅 중인 검증된 IDC.
제휴 링크 — 추가 비용 없이 dibi8 운영을 지원합니다.
참고 자료 및 추가 읽을거리 #
- Caddy 공식 문서
- Caddy GitHub 저장소
- Caddy vs Nginx 2026 벤치마크 — Tech Insider
- Caddy 2.8 vs Nginx 1.26 정적 파일 벤치마크 — dev.to
- Nginx vs Traefik vs Caddy 리버스 프록시 비교 — InstaDevOps
- Caddy Prometheus 모니터링 가이드 — cnblogs
- 리버스 프록시 벤치마크 — GitHub
- Caddy Docker Hub
- Caddy 커뮤니티 포럼
공개: 본 문서에는 DigitalOcean 및 HTStack의 제휴 링크가 포함되어 있습니다. 이 링크를 통해 서비스를 구매하면 dibi8.com에 추가 비용 없이 커미션이 지급됩니다. 모든 벤치마크 데이터와 추천은 독립적인 테스트와 편집 판단을 기반으로 합니다.
💬 댓글 토론