지난 7편 동안 두 서버를 기초부터 실전까지 다뤘습니다. 마지막으로 둘을 정면으로 비교해 보겠습니다. 결론부터 말하면 "어느 쪽이 더 좋은가"가 아니라 "무엇을 우선하는가"의 문제입니다.
1. 한눈에 보는 비교표
| 항목 | Nginx | Caddy |
|---|---|---|
| 언어 / 런타임 | C, 마스터-워커 멀티 프로세스 | Go, 단일 프로세스 + goroutine |
| 설계 철학 | 명시적 설정, 최소 기본값, 극한의 효율 | 안전한 기본값, 자동화, 개발자 경험 |
| 설정 형식 | nginx.conf (자체 DSL) | Caddyfile (사람용) / JSON (원본) |
| 설정 변경 | 파일 수정 + reload | 파일 + reload, 또는 REST API로 실시간 |
| HTTPS | 수동 (certbot), 공식 ACME 모듈 신규 도입 | 완전 자동 (발급·갱신·리다이렉트·OCSP) |
| HTTP/3 | 지원 (빌드 옵션 + 설정 필요) | 기본 활성화 |
| 리버스 프록시 헤더 / WebSocket | 수동 설정 | 자동 |
| 액티브 헬스 체크 | NGINX Plus 전용 | 기본 내장 |
| Rate Limit | 기본 내장 | 플러그인 |
| HTTP 캐시 | 기본 내장, 매우 성숙 | 플러그인 |
| L4 (TCP/UDP) 프록시 | 기본 내장 (stream) | 플러그인 (layer4) |
| 확장 방식 | C 모듈(동적 로드 가능), Lua(OpenResty), njs | Go 플러그인 (xcaddy로 재컴파일) |
| 메모리 안전성 | C (수동 메모리 관리) | Go (메모리 안전 언어) |
| 성능 / 자원 효율 | 최상급, 낮은 메모리 사용 | 충분히 빠름, 상대적으로 높은 메모리 기본선 |
| 생태계 / 자료 | 압도적 | 양호, 공식 문서 품질 높음 |
| 상용 지원 | NGINX Plus (F5) | 스폰서십 기반 지원 |
| 라이선스 | BSD 2-Clause | Apache 2.0 |
2. Nginx의 장점
① 검증된 성능과 자원 효율
20년 넘게 세계 최대 규모의 트래픽을 처리해 온 서버입니다. C로 작성된 이벤트 기반 구조 덕분에 적은 메모리와 CPU로 매우 많은 연결을 처리합니다. 저사양 VPS, 엣지 장비, 수십만 동시 연결이 필요한 환경에서 특히 강합니다.
② 프록시 "부가 기능"이 전부 내장
Rate Limit(limit_req), 캐시(proxy_cache), L4 프록시(stream), 연결 제한, 대역폭 제한, map, split_clients(A/B 테스트), mirror(트래픽 미러링), sub_filter(응답 본문 치환)… 이 모든 게 공식 바이너리 하나에 들어 있습니다. 커스텀 빌드 없이 공식 이미지 그대로 쓸 수 있다는 건 운영상 큰 장점입니다.
③ 압도적인 생태계와 레퍼런스
- 어떤 에러든 검색하면 답이 있습니다.
- 클라우드 벤더 문서, 오픈소스 프로젝트의 배포 가이드 대부분이 Nginx 예제를 제공합니다.
- 인프라 엔지니어 채용 시장에서 Nginx 경험은 사실상 기본 소양입니다.
- OpenResty, Kong, APISIX 등 Nginx 위에 세워진 생태계가 있습니다.
④ 세밀한 제어
버퍼 크기, 타임아웃, 캐시 키, 업스트림 재시도 조건 등 거의 모든 동작을 직접 조정할 수 있습니다. 특수한 요구사항이나 극한 튜닝이 필요할 때 손댈 곳이 많다는 건 장점입니다.
⑤ 상용 지원 옵션
규제 산업이나 대기업 환경에서는 "문제 생기면 책임지고 지원해 줄 벤더"가 필요한 경우가 있습니다. NGINX Plus는 그 선택지를 제공합니다.
3. Nginx의 단점
① HTTPS 운영이 번거롭다
certbot 설치, 갱신 타이머, 갱신 후 reload, 최초 발급 시의 닭-달걀 문제(인증서가 없으면 HTTPS server 블록이 뜨지 않음)… 하나하나는 어렵지 않지만 잊으면 사고가 나는 작업입니다. "인증서 만료로 서비스 장애"는 지금도 흔한 장애 원인입니다. 공식 ACME 모듈이 등장해 개선되고 있지만, 아직은 명시적 설정이 필요하고 비교적 새로운 기능입니다.
② 함정이 많은 설정 문법
시리즈에서 다룬 것만 해도:
- location 매칭 우선순위 (정규식이 접두사보다 우선)
proxy_pass끝 슬래시 유무에 따른 경로 치환add_header/proxy_set_header상속 단절- "If is Evil"
rootvsalias- upstream 호스트명을 시작 시 한 번만 해석
경험자에게는 상식이지만, 가끔 만지는 개발자에게는 매번 문서를 다시 찾게 만드는 요소입니다.
③ 안전하지 않은 기본값
WebSocket, 프록시 헤더, HTTP→HTTPS 리다이렉트, 보안 헤더, 업스트림 keepalive 등이 모두 직접 켜야 하는 기능입니다. 빠뜨려도 에러가 나지 않고 "그냥 조금 잘못 동작"하기 때문에 발견이 늦습니다.
④ 오픈소스 버전의 기능 제한
액티브 헬스 체크, 동적 업스트림 관리 API, 실시간 대시보드 같은 기능은 NGINX Plus에 있습니다. 오픈소스만으로는 외부 도구로 보완해야 합니다.
⑤ 동적 설정이 어렵다
설정 변경은 기본적으로 "파일 수정 → reload"입니다. 업스트림을 자주 바꾸는 동적 환경에서는 템플릿 엔진 + reload 자동화(confd, consul-template 등)를 덧대야 합니다.
⑥ 메모리 안전성
C로 작성된 만큼 메모리 관련 취약점(CVE)이 역사적으로 꾸준히 나왔습니다. 성숙한 프로젝트라 대응은 빠르지만, 구조적 위험은 존재합니다.
4. Caddy의 장점
① 자동 HTTPS: 비교 불가능한 편의성
도메인을 적는 순간 발급·갱신·리다이렉트·OCSP 스테이플링·HTTP/2·HTTP/3가 끝납니다. Let's Encrypt 장애 시 ZeroSSL로 자동 대체되고, 갱신 실패 시 재시도 로직도 내장되어 있습니다. 인증서 만료 장애라는 카테고리 자체를 거의 없애줍니다.
여기에 On-Demand TLS(고객 커스텀 도메인), 내장 ACME 서버(사내 CA), tls internal(로컬·폐쇄망 HTTPS)까지 TLS 자동화에서는 독보적입니다.
② 안전하고 합리적인 기본값
reverse_proxy 한 줄에 프록시 헤더, WebSocket, 커넥션 풀이 들어 있습니다. "아무것도 안 하면 올바르게 동작"하는 방향으로 설계되어, 빠뜨려서 생기는 사고가 적습니다.
③ 짧고 읽기 쉬운 설정
7편에서 같은 요구사항이 Nginx 약 130줄, Caddy 약 70줄이었습니다. handle_path처럼 의도가 이름에 드러나는 지시어 덕분에 설정 파일이 곧 문서가 됩니다. 팀원이 처음 봐도 이해하기 쉽습니다.
④ API 기반 동적 설정
Admin API로 설정 전체 또는 일부를 무중단으로 실시간 교체할 수 있습니다. 배포 파이프라인, 멀티 테넌트 플랫폼, 셀프서비스 도메인 연결 같은 시나리오에서 강력합니다. 설정이 잘못되면 적용 자체가 거부되고 기존 설정이 유지됩니다.
⑤ 오픈소스에 액티브 헬스 체크와 동적 업스트림
Nginx에서는 상용 버전에 있는 기능이 무료로 기본 제공됩니다. lb_try_duration으로 배포 중 짧은 다운타임을 흡수하는 것도 실용적입니다.
⑥ 단일 바이너리와 메모리 안전성
외부 라이브러리 의존 없이 파일 하나로 동작해, 배포·반입(특히 폐쇄망)·버전 관리가 단순합니다. Go로 작성되어 버퍼 오버플로 같은 메모리 안전성 취약점에서 구조적으로 유리합니다.
⑦ 로컬 개발 경험
caddy file-server, caddy reverse-proxy 한 줄, localhost에 자동 HTTPS. 개발 환경에서 프로덕션과 같은 HTTPS 조건을 손쉽게 재현할 수 있습니다.
5. Caddy의 단점
① 핵심 프록시 기능 일부가 플러그인
Rate Limit, HTTP 캐시, L4 프록시, DNS 챌린지가 모두 플러그인입니다. 이는 곧:
- 공식 패키지/이미지를 그대로 쓸 수 없고 xcaddy 커스텀 빌드가 필요
- 커스텀 바이너리의 보안 업데이트를 직접 추적하고 재빌드해야 함
- 플러그인마다 성숙도와 유지보수 상태가 제각각
을 의미합니다. apt로 설치한 Caddy는 apt upgrade로 업데이트되지만, 커스텀 빌드는 그렇지 않습니다.
② 지시어 실행 순서의 비직관성
작성 순서가 아니라 미리 정해진 순서로 실행된다는 규칙은, 단순한 설정에서는 편하지만 조건이 얽히면 7편의 관리자 페이지 예시처럼 조용히 의도와 다르게 동작할 수 있습니다. handle/route의 차이를 확실히 알아야 합니다.
③ 자원 효율
Go 런타임과 GC 때문에 메모리 기본 사용량이 Nginx보다 높고, 극한 부하에서는 처리량과 지연 시간 꼬리(tail latency)에서 Nginx가 유리한 경우가 많습니다. 대부분의 서비스에서는 체감되지 않지만, 초대형 트래픽이나 초저사양 장비에서는 고려 대상입니다.
④ 상대적으로 작은 생태계
자료의 절대량이 적고, 서드파티 도구(예: 각종 대시보드, 클라우드 벤더 가이드)가 Nginx만큼 다양하지 않습니다. 인터넷에 v1 시절의 낡은 자료가 섞여 있어 혼란을 주기도 합니다.
⑤ "자동"의 이면
자동 HTTPS는 편하지만, 동작 원리를 모르면 문제가 생겼을 때 막막합니다. DNS가 아직 전파되지 않았거나 80 포트가 막혀 있으면 발급에 실패하고, 컨테이너 데이터 볼륨을 영속화하지 않으면 재시작마다 재발급하다 rate limit에 걸립니다. 자동화는 이해를 대체하지 않습니다.
⑥ 설정의 진실 원천 문제
Admin API로 바꾼 설정과 Caddyfile이 어긋날 수 있습니다. API를 쓸지 파일을 쓸지 팀 규칙이 필요합니다.
6. 항목별 판정
| 관점 | 우위 | 한 줄 이유 |
|---|---|---|
| 처음 배우기 | Caddy | 짧은 설정, 안전한 기본값 |
| HTTPS 운영 | Caddy | 완전 자동, 만료 장애 거의 없음 |
| 순수 성능·자원 효율 | Nginx | C + 20년 최적화 |
| 캐시 / Rate Limit / L4 | Nginx | 기본 내장, 성숙도 |
| 헬스 체크 / 동적 업스트림 | Caddy | 오픈소스에 내장 |
| 동적 설정 (API) | Caddy | Admin API |
| 세밀한 튜닝 | Nginx | 조정 가능한 파라미터가 많음 |
| 메모리 안전성 | Caddy | Go |
| 자료·커뮤니티·채용 시장 | Nginx | 압도적 점유율 |
| 기본 패키지로 끝나는가 | Nginx | 플러그인 커스텀 빌드 불필요 |
| 로컬 개발 / 사내 HTTPS | Caddy | tls internal, 내장 ACME 서버 |
| 상용 지원 | Nginx | NGINX Plus |
7. 상황별 선택 가이드
Caddy를 추천하는 경우
- 개인 프로젝트, 사이드 프로젝트, 블로그: 인증서 신경 쓸 시간에 기능을 만드세요.
- 소~중규모 팀의 서비스: 전담 인프라 엔지니어가 없을수록 안전한 기본값의 가치가 큽니다.
- 멀티 테넌트 SaaS: 고객 커스텀 도메인은 On-Demand TLS가 사실상 정답입니다.
- 사내망 / 폐쇄망의 내부 서비스:
tls internal이나 내장 ACME 서버로 사내 HTTPS를 쉽게 구성하고, 단일 바이너리라 반입도 간편합니다. - 로컬 개발 환경: HTTPS가 필요한 기능 테스트.
- 서비스가 자주 추가·삭제되는 셀프호스팅 홈랩.
Nginx를 추천하는 경우
- 대규모 트래픽, 저사양 장비: 자원 효율이 결정적일 때.
- 캐시 서버 / CDN 오리진 앞단:
proxy_cache의 성숙도와 세밀한 제어. - Rate Limit, L4 프록시가 핵심 요구사항인데 커스텀 빌드를 피하고 싶을 때.
- 이미 Nginx 운영 경험과 자산(설정, 모니터링, 런북)이 쌓인 조직: 갈아탈 이유가 명확하지 않다면 굳이 바꿀 필요가 없습니다.
- 상용 지원이 필요한 엔터프라이즈 환경.
- OpenResty/Lua로 복잡한 게이트웨이 로직이 필요할 때.
둘 다 쓰는 구성도 흔하다
인터넷 ──▶ Caddy (TLS 자동화, 라우팅) ──▶ Nginx (캐시, 정적 파일) ──▶ 앱혹은 반대로 앞단 L4는 Nginx stream, 내부 서비스별 HTTPS는 Caddy가 맡는 식으로 각자의 강점만 조합할 수도 있습니다. 다만 홉이 늘어나는 만큼 디버깅 포인트도 늘어나니, 이유가 분명할 때만 쓰세요.
이런 경우는 둘 다 아닐 수도
- 쿠버네티스: 인그레스/Gateway API 컨트롤러(NGINX Ingress Controller, Traefik, Envoy Gateway 등)를 쓰는 게 일반적입니다.
- 서비스 메시 / 고급 L7 트래픽 제어: Envoy 계열.
- 컨테이너 라벨 기반 자동 라우팅: Traefik이 이 영역의 강자입니다.
- 클라우드 관리형: AWS ALB, Cloudflare 등이 TLS와 라우팅을 대신해 주면 웹 서버는 단순한 역할만 해도 됩니다.
8. 의사결정 플로차트
시작
│
├─ 쿠버네티스 위인가? ─── 예 ──▶ 인그레스/Gateway 컨트롤러 검토
│ │ 아니오
│ ▼
├─ 고객 커스텀 도메인 HTTPS가 필요한가? ─── 예 ──▶ Caddy (On-Demand TLS)
│ │ 아니오
│ ▼
├─ 초대형 트래픽 / 저사양 / 캐시가 핵심인가? ─── 예 ──▶ Nginx
│ │ 아니오
│ ▼
├─ 팀에 Nginx 운영 자산이 이미 충분한가? ─── 예 ──▶ Nginx 유지
│ │ 아니오
│ ▼
├─ Rate Limit/L4가 필수인데 커스텀 빌드는 싫은가? ─── 예 ──▶ Nginx
│ │ 아니오
│ ▼
└──────────────────────────────────────────────▶ Caddy9. 시리즈를 마치며
정리하자면 이렇습니다.
Nginx는 "무엇이든 할 수 있지만, 모든 것을 직접 말해줘야 하는" 숙련된 전문가의 도구입니다. Caddy는 "알아서 올바르게 해주지만, 특별한 것은 부품을 붙여야 하는" 현대적인 도구입니다.
어느 쪽을 고르든, 이 시리즈에서 다룬 공통 개념(리버스 프록시, TLS와 ACME, 프록시 헤더, 로드 밸런싱과 헬스 체크, 캐시와 Rate Limit, 실제 클라이언트 IP)을 이해하고 있다면 도구를 바꾸는 건 문법을 바꾸는 일에 불과합니다. 7편의 대응표를 옆에 두고 직접 두 서버를 같은 구성으로 띄워보는 것을 추천합니다. 한 번 해보면 각자의 철학이 손에 잡힐 겁니다.
긴 시리즈 읽어주셔서 감사합니다.
시리즈 전체 목록
- 웹 서버와 리버스 프록시, 무엇을 하는 물건인가
- Nginx 기초 — 아키텍처와 설정 파일 읽는 법
- Nginx 중급 — location 매칭, 리버스 프록시, 로드 밸런싱, HTTPS
- Nginx 심화 — 캐싱, Rate Limit, 보안, 성능 튜닝, L4 프록시
- Caddy 기초 — Caddyfile과 자동 HTTPS
- Caddy 심화 — 매처, 지시어 순서, 헬스 체크, Admin API, 플러그인
- 실전 — 같은 아키텍처를 Nginx와 Caddy로 각각 구성하기
- Nginx vs Caddy — 장단점 비교와 선택 가이드 (이 글)