Caddy란 무엇인가? 자동 SSL부터 L7·L4 리버스 프록시까지 이해하기
1장 Caddy를 단순한 웹서버로 보면 부족하다#
Caddy를 처음 접하면 Apache나 Nginx와 같은 웹서버라고 생각하기 쉽습니다.
틀린 설명은 아니지만 Caddy의 강점을 제대로 설명하기에는 부족합니다.
현대적인 서버 환경에서 Caddy는 다음 구조의 진입 게이트웨이 역할을 할 수 있습니다.
flowchart LR
U[사용자]
C[Caddy]
W[웹 애플리케이션]
A[API 서버]
G[Grafana]
T[Trilium]
S[정적 사이트]
U -->|HTTPS| C
C --> W
C --> A
C --> G
C --> T
C --> S사용자는 여러 내부 서비스의 실제 포트나 위치를 알 필요가 없습니다.
Caddy가 외부 요청을 먼저 받은 뒤 도메인·경로·헤더 등의 조건을 보고 적절한 내부 서비스로 전달합니다.
즉 Caddy는:
웹서버 + TLS 종단점 + 리버스 프록시 + 서비스 라우터
역할을 하나의 서버에서 수행할 수 있습니다.
2장 Caddy의 가장 강력한 특징은 자동 HTTPS다#
Caddy가 널리 알려진 가장 큰 이유 중 하나는 Automatic HTTPS입니다.
도메인이 Caddy 설정에 지정되고 DNS와 외부 접근 조건이 충족되면 Caddy는 기본적으로 HTTPS를 사용하고 인증서 발급과 관리를 자동화할 수 있습니다. 공식 문서 역시 도메인이 포함된 사이트는 기본적으로 HTTPS를 사용하며 Caddy가 TLS 인증서를 자동으로 프로비저닝한다고 설명합니다.
예를 들어 설정은 매우 단순할 수 있습니다.
example.com {
reverse_proxy localhost:8080
}이 정도 설정만으로도 구조적으로는 다음과 같은 역할을 Caddy가 맡게 됩니다.
sequenceDiagram
participant U as 사용자
participant C as Caddy
participant CA as 인증기관
participant A as 애플리케이션
C->>CA: TLS 인증서 발급·갱신
CA-->>C: 인증서
U->>C: HTTPS 요청
C->>A: 내부 요청 전달
A-->>C: 응답
C-->>U: HTTPS 응답운영자는 직접 인증서 파일을 다운로드하고 만료 날짜를 확인하며 갱신 스크립트를 작성하는 부담을 크게 줄일 수 있습니다.
3장 자동 SSL과 자동 HTTPS는 조금 다르게 이해해야 한다#
흔히 "Caddy는 SSL을 자동으로 해준다"고 표현합니다.
실무에서는 충분히 통하는 표현이지만 정확하게는 TLS 인증서 관리와 HTTPS 구성을 자동화한다고 보는 편이 좋습니다.
Caddy의 Automatic HTTPS는 대표적으로 인증서 자동 관리와 HTTP에서 HTTPS로의 리다이렉션을 관리합니다. 공식 문서에서는 auto_https 설정으로 인증서 자동 관리나 리다이렉션을 조정할 수 있다고 설명합니다.
개념적으로 보면 다음과 같습니다.
flowchart LR
H[HTTP 요청 :80]
C[Caddy]
S[HTTPS :443]
A[내부 애플리케이션]
H --> C
C -->|HTTPS 전환| S
S --> C
C --> A4장 인증서 갱신을 사람이 관리하지 않아도 되는 것이 왜 큰 장점인가#
서버가 한 대일 때는 인증서 갱신이 큰 작업처럼 느껴지지 않을 수 있습니다.
하지만 서비스가 늘어나면 이야기가 달라집니다.
예를 들어:
thinkx.example.com
admin.example.com
api.example.com
monitor.example.com
wiki.example.com처럼 여러 도메인을 운영한다고 하겠습니다.
각 서비스마다 인증서 파일과 갱신 스크립트를 따로 관리하면 운영 복잡도가 빠르게 증가합니다.
Caddy를 앞단에 두면:
flowchart TB
C[Caddy<br/>TLS 인증서 통합 관리]
A[thinkx.example.com]
B[admin.example.com]
D[api.example.com]
E[monitor.example.com]
C --> A
C --> B
C --> D
C --> E형태로 인증서 관리 지점을 Caddy에 집중시킬 수 있습니다.
이것이 Caddy의 편의성이 작은 개인 서버뿐 아니라 여러 서비스를 운영하는 Docker 환경에서도 돋보이는 이유입니다.
5장 TLS Termination이란 무엇인가#
Caddy를 리버스 프록시로 사용할 때 자주 등장하는 개념이 TLS Termination입니다.
외부에서는 HTTPS로 통신하지만 내부 애플리케이션까지 반드시 HTTPS를 사용할 필요는 없습니다.
예를 들어:
flowchart LR
U[사용자]
C[Caddy<br/>TLS Termination]
APP[애플리케이션<br/>HTTP :8080]
U -->|HTTPS :443| C
C -->|HTTP :8080| APPCaddy에서 암호화된 HTTPS 연결을 종료하고 내부에서는 HTTP로 전달하는 구조입니다.
공식 Caddy 문서도 caddy reverse-proxy --from example.com --to localhost:9000 같은 형태로 Caddy를 TLS terminator로 사용할 수 있음을 보여줍니다.
6장 내부 서버까지 HTTPS로 연결할 수도 있다#
백엔드 역시 HTTPS를 사용하도록 구성할 수 있습니다.
example.com {
reverse_proxy https://backend.example.internal
}Caddy의 reverse_proxy는 HTTPS upstream을 지원하며 TLS 설정과 클라이언트 인증 같은 기능도 제공합니다.
구조는 다음과 같습니다.
flowchart LR
U[사용자]
C[Caddy]
A[Backend]
U -->|HTTPS| C
C -->|HTTPS| A즉:
외부 TLS + 내부 TLS
구성도 가능합니다.
7장 Caddy의 핵심 기능인 L7 리버스 프록시#
Caddy의 기본 reverse_proxy는 HTTP 애플리케이션 계층에서 동작합니다.
OSI 모델 관점에서는 Layer 7, 즉 L7 영역입니다.
L7에서는 단순 IP와 포트뿐 아니라 HTTP 요청의 의미를 보고 라우팅할 수 있습니다.
예를 들어:
Host
Path
Header
Method
Cookie같은 정보를 사용할 수 있습니다.
구조를 보면 다음과 같습니다.
flowchart TB
U[사용자 요청]
C{Caddy L7 Router}
A[thinkx.example.com]
B[api.example.com]
D[/admin]
E[/static]
U --> C
C -->|Host = thinkx.example.com| A
C -->|Host = api.example.com| B
C -->|Path = /admin/*| D
C -->|Path = /static/*| E이것이 L4 프록시와 L7 프록시의 가장 큰 차이 중 하나입니다.
8장 도메인만으로 여러 서비스를 분리할 수 있다#
Docker 서버 한 대에서 여러 애플리케이션을 실행한다고 하겠습니다.
Trilium :8080
API :3000
Grafana :3001
Admin :9000외부 사용자가 이런 포트를 직접 기억하게 만들 필요는 없습니다.
Caddy에서:
thinkx.example.com {
reverse_proxy trilium:8080
}
api.example.com {
reverse_proxy api:3000
}
monitor.example.com {
reverse_proxy grafana:3001
}
admin.example.com {
reverse_proxy admin:9000
}처럼 구성할 수 있습니다.
전체 구조는 다음과 같습니다.
flowchart TB
Internet[Internet]
C[Caddy<br/>80 · 443]
T[Trilium<br/>8080]
API[API<br/>3000]
G[Grafana<br/>3001]
ADM[Admin<br/>9000]
Internet --> C
C -->|thinkx.example.com| T
C -->|api.example.com| API
C -->|monitor.example.com| G
C -->|admin.example.com| ADM외부에 공개해야 할 포트는 주로 80과 443으로 단순화할 수 있습니다.
9장 Docker와 Caddy의 조합이 좋은 이유#
Docker에서는 애플리케이션마다 각자 포트를 가지고 있습니다.
하지만 같은 Docker 네트워크 안에서는 컨테이너 이름을 이용해 접근할 수 있습니다.
예를 들어:
reverse_proxy trilium:8080처럼 사용할 수 있습니다.
구조는 다음과 같습니다.
flowchart TB
subgraph Docker Host
C[Caddy]
subgraph app_network
T[trilium:8080]
A[api:3000]
G[grafana:3000]
end
C --> T
C --> A
C --> G
end
U[Internet]
U -->|80 / 443| C각 컨테이너 포트를 인터넷에 직접 노출하지 않고 Caddy만 외부 진입점으로 둘 수 있다는 것이 중요한 장점입니다.
10장 Reverse Proxy란 무엇인가#
일반 Proxy와 Reverse Proxy는 방향이 다릅니다.
Forward Proxy는 사용자를 대신해 외부 서버에 접근합니다.
flowchart LR
U[사용자] --> P[Forward Proxy] --> I[Internet]Reverse Proxy는 서버를 대신해 외부 사용자의 요청을 받습니다.
flowchart LR
U[사용자] --> R[Reverse Proxy] --> S[Backend Server]Caddy의 대표적인 사용 방식이 바로 두 번째 구조입니다.
사용자는 실제 애플리케이션 서버가 어디 있는지 몰라도 됩니다.
11장 L7에서는 URL 경로를 기준으로 서비스도 나눌 수 있다#
반드시 도메인을 여러 개 사용할 필요는 없습니다.
예를 들어 하나의 도메인에서:
example.com/
example.com/api/
example.com/admin/경로를 기준으로 서로 다른 애플리케이션으로 보낼 수도 있습니다.
개념적으로:
flowchart LR
U[example.com]
C{Caddy}
WEB[Web]
API[API]
ADMIN[Admin]
U --> C
C -->|/| WEB
C -->|/api/*| API
C -->|/admin/*| ADMIN이것이 HTTP 내용을 이해하는 L7 프록시의 장점입니다.
12장 Caddy의 reverse_proxy는 단순 전달 기능만 있는 것이 아니다#
Caddy의 HTTP reverse proxy는 다양한 upstream 형태를 지원합니다.
공식 문서 기준으로 일반 TCP 주소뿐 아니라 HTTPS upstream, h2c, Unix socket 등도 사용할 수 있습니다.
예를 들면:
localhost:4000
https://backend.example.com
h2c://127.0.0.1
unix//var/php.sock같은 upstream 구성이 가능합니다.
즉 Caddy는 단순한:
도메인 → 포트매핑보다 훨씬 폭넓은 L7 프록시 역할을 수행할 수 있습니다.
13장 로드밸런서로도 사용할 수 있다#
애플리케이션 서버가 여러 대 있다고 하겠습니다.
APP1
APP2
APP3Caddy가 앞에서 요청을 여러 backend로 나누도록 만들 수 있습니다.
flowchart LR
U[사용자]
C[Caddy<br/>Reverse Proxy]
A1[App 1]
A2[App 2]
A3[App 3]
U --> C
C --> A1
C --> A2
C --> A3이 구조에서는 Caddy가 웹서버뿐 아니라 L7 로드밸런서의 역할도 맡게 됩니다.
14장 여기서 L4와 L7의 차이를 이해해야 한다#
Caddy를 제대로 활용하려면 Layer 4와 Layer 7의 차이를 알아야 합니다.
flowchart TB
L7["Layer 7<br/>HTTP · HTTPS"]
L4["Layer 4<br/>TCP · UDP"]
IP["Layer 3<br/>IP"]
L7 --> L4
L4 --> IPL7은 HTTP의 의미를 이해합니다.
예:
GET /api/users
Host: api.example.comL4는 이보다 아래에서 TCP 또는 UDP 연결을 다룹니다.
주로:
IP
Port
TCP
UDP
TLS 연결 특성같은 정보를 기반으로 처리합니다.
15장 Caddy는 기본적으로 L7에 강하다#
기본 Caddy에서 가장 대표적인 프록시 기능은 HTTP reverse_proxy입니다.
즉 일반적인 웹서비스에서는 별도의 확장 없이도 다음 구조를 만들 수 있습니다.
flowchart LR
U[Client]
C[Caddy L7]
W[Web]
API[API]
U -->|HTTPS| C
C -->|HTTP routing| W
C -->|HTTP routing| API웹서비스만 운영한다면 대부분 이 영역만으로 충분합니다.
16장 Caddy에서 L4도 가능한가#
가능합니다.
다만 매우 중요한 차이가 있습니다.
L4는 기본 Caddy의 표준 HTTP reverse_proxy 기능이 아닙니다.
Caddy에 caddy-l4 모듈을 추가해야 합니다.
현재 caddy-l4 프로젝트는 TCP·UDP 연결을 처리하는 Layer 4 Caddy 앱으로 제공되며 raw TCP/UDP 연결에 대한 라우팅과 프록시 기능을 제공합니다. 프로젝트 문서는 동시에 아직 개발 중이며 breaking change가 발생할 수 있다고 명시하고 있습니다. 또한 공식 Caddy Web Server 조직의 저장소는 아닙니다.
이 부분은 실무적으로 매우 중요합니다.
17장 caddy-l4는 별도 빌드가 필요하다#
일반 Caddy 바이너리에 L4 기능이 자동으로 포함되어 있다고 생각하면 안 됩니다.
caddy-l4 프로젝트에서는 xcaddy를 이용해 다음과 같이 빌드하는 방식을 안내합니다.
xcaddy build --with github.com/mholt/caddy-l4즉 구조적으로:
flowchart LR
C[Caddy Core]
M[caddy-l4 Module]
C --> M
M --> TCP[TCP Proxy]
M --> UDP[UDP Proxy]가 됩니다.
18장 L4를 사용하면 무엇을 프록시할 수 있을까#
L7이 웹서비스를 위한 것이라면 L4는 TCP·UDP 기반 서비스를 프록시할 수 있습니다.
개념적인 예로:
SSH
PostgreSQL
MySQL
Redis
SMTP
IMAP
기타 TCP 서비스
일부 UDP 서비스같은 비HTTP 서비스를 다룰 수 있습니다.
예를 들어:
flowchart LR
C1[SSH Client]
C2[DB Client]
C[Caddy + caddy-l4]
SSH[SSH Server :22]
DB[PostgreSQL :5432]
C1 -->|TCP| C
C2 -->|TCP| C
C --> SSH
C --> DBcaddy-l4 프로젝트 역시 raw TCP/UDP 프록시, SSH 분기, Postgres matching 등 다양한 예제를 제공합니다.
19장 L4에서도 TLS를 사용할 수 있다#
caddy-l4에는 TLS handler가 있으며 Layer 4 연결에서 TLS를 종료할 수도 있습니다.
다만 이 handler 자체가 인증서를 발급하는 것은 아니며, Caddy가 이미 관리하고 있는 인증서를 사용해 TLS termination을 수행합니다.
구조적으로:
flowchart LR
U[Client]
C[Caddy L4<br/>TLS Termination]
TCP[TCP Backend]
U -->|TLS| C
C -->|Raw TCP| TCP처럼 사용할 수 있습니다.
20장 TLS Passthrough도 가능하다#
TLS를 Caddy에서 종료하지 않고 연결 정보를 보고 다른 backend로 전달하는 방식도 생각할 수 있습니다.
flowchart LR
U[Client]
C[Caddy L4]
A[Server A<br/>TLS]
B[Server B<br/>TLS]
U -->|TLS| C
C -->|TLS Passthrough| A
C -->|TLS Passthrough| B이 경우 실제 TLS 종료는 backend에서 이루어집니다.
21장 SNI를 이용한 L4 라우팅이 강력하다#
TLS 연결에서는 클라이언트가 SNI Server Name Indication 정보를 전달할 수 있습니다.
이를 사용하면 같은 포트에서도 대상 호스트 이름에 따라 다른 TCP backend로 보낼 수 있습니다.
개념적으로:
flowchart TB
U[Client :443]
C{Caddy L4<br/>TLS SNI}
A[app.example.com]
B[db.example.com]
D[service.example.com]
U --> C
C -->|SNI = app.example.com| A
C -->|SNI = db.example.com| B
C -->|SNI = service.example.com| Dcaddy-l4 프로젝트는 TLS ServerName을 기준으로 다른 backend에 프록시하는 기능과 TLS SNI Dynamic Upstreams 예제를 제공하고 있습니다.
22장 L7 Host 라우팅과 L4 SNI 라우팅의 차이#
비슷해 보이지만 계층이 다릅니다.
L7#
HTTP 요청을 해석합니다.
Host: example.com
GET /apiL4#
HTTP 내용을 해석하지 않고 TLS handshake 같은 연결 수준의 정보를 사용할 수 있습니다.
TLS SNI = example.com이를 비교하면 다음과 같습니다.
flowchart TB
A[Client]
L4["L4<br/>TCP · UDP · TLS SNI"]
L7["L7<br/>HTTP Host · Path · Header"]
B[Backend]
A --> L4
L4 --> L7
L7 --> B23장 같은 Caddy에서 L4와 L7을 함께 사용할 수도 있다#
caddy-l4는 Caddy HTTP 앱과 함께 사용할 수 있도록 설계되어 있습니다. 프로젝트 문서에는 HTTP 앱과 Layer 4 앱을 결합하는 예제도 제공됩니다.
개념적으로는:
flowchart TB
INTERNET[Internet]
C[Caddy]
L7[L7 HTTP Router]
L4[L4 TCP/UDP Router]
WEB[Web]
API[API]
SSH[SSH]
DB[Database]
INTERNET --> C
C --> L7
C --> L4
L7 --> WEB
L7 --> API
L4 --> SSH
L4 --> DB하나의 Caddy 생태계에서 웹과 비웹 트래픽을 모두 다루는 구조를 만들 수 있다는 의미입니다.
24장 다만 L4와 HTTP 앱의 포트 충돌에 주의해야 한다#
caddy-l4 문서는 Layer 4 앱이 Caddy HTTP 앱과 동일한 네트워크 주소에 단순히 동시에 bind할 수 없다고 설명합니다.
필요한 경우 listener wrapper 같은 구조를 사용해 결합해야 합니다.
즉 다음처럼 단순하게 생각하면 안 됩니다.
HTTP app → :443
L4 app → :443둘 다 동일 포트에 그냥 bind시키는 방식은 충돌합니다.
L4와 L7을 같은 포트에서 함께 처리하려면 caddy-l4의 wrapper 및 결합 구조를 이해해야 합니다.
25장 L4와 L7을 언제 구분해서 사용해야 할까#
웹사이트나 REST API라면 일반적으로 L7이 적합합니다.
flowchart LR
H[HTTP / HTTPS]
L7[Caddy L7]
APP[Web / API]
H --> L7 --> APPHTTP가 아닌 TCP·UDP 프로토콜을 프록시해야 한다면 L4를 검토할 수 있습니다.
flowchart LR
T[TCP / UDP]
L4[Caddy + caddy-l4]
APP[SSH / DB / 기타 서비스]
T --> L4 --> APP따라서 무조건 L4가 더 좋은 것이 아니라 처리하려는 프로토콜에 따라 계층을 선택하는 것이 중요합니다.
26장 Caddy와 Nginx의 가장 큰 체감 차이는 무엇인가#
두 제품 모두 강력한 웹서버와 리버스 프록시입니다.
하지만 소규모·중규모 서비스나 개인 서버에서 Caddy가 특히 편리하게 느껴지는 부분은 HTTPS 구성의 단순함입니다.
예를 들어 Caddy에서는:
example.com {
reverse_proxy app:8080
}같은 매우 간결한 설정으로 HTTPS 기반 reverse proxy를 구성할 수 있습니다.
공식 문서 역시 host matcher나 도메인 기반 구성이 Automatic HTTPS를 활성화할 수 있음을 설명합니다.
즉 Caddy의 철학은:
복잡한 기본 설정을 운영자가 매번 작성하기보다 안전한 기본값을 자동화하는 것
에 가깝습니다.
27장 Caddy가 특히 잘 맞는 서버 환경#
다음과 같은 구조에서는 Caddy의 장점이 크게 드러납니다.
flowchart TB
VPS[VPS]
C[Caddy]
subgraph Docker
W[Wiki / Trilium]
API[API Server]
G[Grafana]
APP[Web App]
AI[AI Service]
end
Internet[Internet]
Internet -->|HTTPS| C
C --> W
C --> API
C --> G
C --> APP
C --> AI하나의 VPS에서 Docker로 여러 서비스를 운영하면서 각 서비스에 서브도메인을 붙이는 환경입니다.
28장 Caddy를 단일 진입점으로 만들면 포트 관리도 단순해진다#
Caddy가 없다면 다음처럼 여러 포트를 외부에 노출할 수 있습니다.
8080
3000
3001
9000
9090Caddy를 앞단에 두면 외부에서는 주로:
80
443만 사용하고 내부 서비스는 Docker 네트워크 안에 둘 수 있습니다.
flowchart LR
Internet[Internet]
FW[Firewall<br/>80 · 443]
C[Caddy]
A[App :8080]
B[API :3000]
G[Grafana :3001]
Internet --> FW --> C
C --> A
C --> B
C --> G공격 표면과 운영 복잡도를 줄이는 데 도움이 되는 구조입니다.
29장 Caddy는 정적 파일 서버도 될 수 있다#
모든 요청을 backend 애플리케이션으로 보낼 필요는 없습니다.
정적 HTML·CSS·JavaScript·이미지 파일은 Caddy 자체에서 제공할 수 있습니다.
예:
example.com {
root * /srv
file_server
}따라서:
flowchart LR
U[사용자]
C[Caddy]
STATIC[정적 파일]
API[API 서버]
U --> C
C --> STATIC
C --> API같은 구조도 가능합니다.
30장 하나의 Caddy에서 정적 사이트와 애플리케이션을 함께 운영할 수 있다#
예를 들어:
www.example.com
→ 정적 랜딩페이지
app.example.com
→ Docker 웹앱
api.example.com
→ API 서버처럼 구성할 수 있습니다.
flowchart TB
C[Caddy]
STATIC[Static Site]
WEB[Web App]
API[API Server]
C -->|www.example.com| STATIC
C -->|app.example.com| WEB
C -->|api.example.com| API이것이 소규모 서버에서 Caddy 하나만으로 상당히 다양한 서비스를 운영할 수 있는 이유입니다.
31장 Caddy를 마이크로서비스 Gateway처럼 사용할 수도 있다#
서비스가 여러 개라면:
/auth
/user
/order
/payment을 서로 다른 backend로 분리할 수 있습니다.
flowchart LR
U[Client]
C{Caddy}
AUTH[Auth Service]
USER[User Service]
ORDER[Order Service]
PAY[Payment Service]
U --> C
C -->|/auth| AUTH
C -->|/user| USER
C -->|/order| ORDER
C -->|/payment| PAY다만 규모가 커지고 인증·서비스 디스커버리·세밀한 트래픽 정책이 복잡해진다면 별도의 API Gateway 또는 서비스 메시와 역할을 구분하는 것이 좋습니다.
32장 Caddy의 장점은 설정 파일이 읽기 쉽다는 것이다#
Caddyfile은 비교적 사람이 읽기 쉽게 설계되어 있습니다.
예:
thinkx.example.com {
reverse_proxy trilium:8080
}
api.example.com {
reverse_proxy api:3000
}구조만 보더라도:
도메인
→ backend관계를 쉽게 이해할 수 있습니다.
서버 구성을 코드로 관리하는 Infrastructure as Code 관점에서도 작은 규모에서는 상당히 직관적입니다.
33장 설정을 코드처럼 관리할 수 있다#
Caddyfile을 Git으로 관리하면 서버 설정 변경 이력을 추적할 수 있습니다.
개념적으로:
flowchart LR
G[Git]
F[Caddyfile]
C[Caddy]
S[Services]
G --> F
F --> C
C --> S따라서:
- 누가 설정을 바꿨는지
- 이전 설정이 무엇이었는지
- 언제 도메인이 추가되었는지
같은 변경 이력을 관리할 수 있습니다.
34장 Caddy가 모든 환경의 정답은 아니다#
Caddy의 장점이 많다고 해서 모든 시스템을 Caddy 하나로 처리하는 것이 항상 최선은 아닙니다.
특히 L4 영역에서는 주의할 필요가 있습니다.
기본 HTTP Caddy 기능과 달리 caddy-l4는 별도의 확장 프로젝트이고 현재 저장소에서도 아직 개발 중이며 breaking changes를 예상하라고 명시합니다. 또한 Caddy Web Server 공식 GitHub 조직의 저장소가 아니라는 점도 밝혀져 있습니다.
따라서 매우 중요한 엔터프라이즈 L4 로드밸런싱에서는:
HAProxy
전용 Load Balancer
클라우드 L4 LB같은 선택지와 함께 비교하는 것이 합리적입니다.
35장 반대로 일반적인 웹서비스에서는 기본 Caddy만으로 충분한 경우가 많다#
다음 요구사항이라면 굳이 L4 플러그인을 사용할 필요가 없습니다.
HTTPS 사이트
REST API
WebSocket
웹 애플리케이션
Docker 서비스
서브도메인 라우팅
정적 파일이 영역은 Caddy의 기본 HTTP/L7 기능으로 처리할 수 있습니다.
즉 구조를 필요 이상으로 복잡하게 만들 필요는 없습니다.
36장 Caddy 도입 구조를 단계별로 생각하면#
처음에는 가장 단순한 구조로 시작할 수 있습니다.
flowchart LR
U[Internet]
C[Caddy]
A[Web App]
U -->|HTTPS| C --> A서비스가 늘어나면:
flowchart TB
U[Internet]
C[Caddy L7]
A[Web]
B[API]
D[Admin]
M[Monitoring]
U --> C
C --> A
C --> B
C --> D
C --> MHTTP가 아닌 서비스까지 프록시해야 한다면 그때 L4를 추가로 검토합니다.
flowchart TB
U[Internet]
C[Caddy]
L7[L7 HTTP]
L4[L4 TCP/UDP<br/>caddy-l4]
WEB[Web · API]
SSH[SSH]
DB[Database]
U --> C
C --> L7
C --> L4
L7 --> WEB
L4 --> SSH
L4 --> DB37장 Caddy의 강점을 한 장으로 정리하면#
flowchart TB
C[Caddy]
TLS[Automatic HTTPS<br/>TLS 인증서 자동 관리]
L7[L7 Reverse Proxy<br/>Host · Path · Header]
LB[Load Balancing]
STATIC[Static File Server]
DOCKER[Docker Gateway]
HTTPS[Backend HTTPS]
L4[L4 TCP · UDP<br/>caddy-l4 확장]
C --> TLS
C --> L7
C --> LB
C --> STATIC
C --> DOCKER
C --> HTTPS
C -. 확장 모듈 .-> L4여기서 반드시 구분해야 할 것은:
Automatic HTTPS와 L7 reverse proxy는 Caddy의 대표적인 기본 기능
이고,
L4 TCP/UDP proxy는 caddy-l4 확장을 추가해야 하는 기능
이라는 점입니다.
38장 Caddy를 사용하면 좋은 이유#
Caddy의 강점은 개별 기능 하나가 특별해서라기보다 여러 서버 운영 기능을 비교적 단순하게 묶을 수 있다는 데 있습니다.
도메인 관리
+
HTTPS
+
TLS 인증서
+
리버스 프록시
+
로드밸런싱
+
정적 파일
+
Docker 서비스 라우팅을 하나의 진입점에서 관리할 수 있습니다.
필요할 경우:
TCP
UDP
TLS SNI까지 caddy-l4로 확장할 수 있습니다.
39장 개인 VPS에서 특히 유용한 구성#
한 대의 VPS에서 여러 Docker 서비스를 운영한다고 하겠습니다.
가장 실용적인 구조는 다음과 같습니다.
flowchart TB
Internet[Internet]
FW[Firewall<br/>80 · 443]
C[Caddy<br/>TLS + L7 Reverse Proxy]
subgraph Docker
THINKX[ThinkX<br/>Trilium]
ADMIN[Admin]
API[API]
MON[Monitoring]
APP[Web App]
end
Internet --> FW
FW --> C
C -->|thinkx.example.com| THINKX
C -->|admin.example.com| ADMIN
C -->|api.example.com| API
C -->|monitor.example.com| MON
C -->|app.example.com| APP이 구성의 장점은 내부 애플리케이션들이 각자 인증서를 관리할 필요가 없다는 것입니다.
Caddy가 앞단에서 HTTPS를 담당하고 각 애플리케이션은 자신의 기능에 집중할 수 있습니다.
40장 L4까지 필요한 경우의 확장 구조#
추가로 데이터베이스나 SSH 같은 비HTTP 서비스를 프록시해야 한다면 다음과 같은 확장 구조를 생각할 수 있습니다.
flowchart TB
Internet[Internet]
C[Caddy]
HTTP[L7 HTTP App]
TCP[L4 App<br/>caddy-l4]
WEB[Web :8080]
API[API :3000]
SSH[SSH :22]
PG[PostgreSQL :5432]
Internet --> C
C --> HTTP
C --> TCP
HTTP --> WEB
HTTP --> API
TCP --> SSH
TCP --> PG다만 데이터베이스를 인터넷에 직접 노출해야 한다는 의미는 아닙니다.
실제 운영에서는 VPN이나 방화벽, 접근 제어와 함께 사용해야 합니다.
Caddy FAQ#
Caddy는 웹서버인가#
네. 하지만 정적 웹서버뿐 아니라 HTTPS 자동화와 L7 리버스 프록시, 로드밸런싱 등의 역할도 수행할 수 있습니다.
Caddy는 SSL 인증서를 자동으로 발급하는가#
도메인과 네트워크 조건이 충족되면 Automatic HTTPS를 통해 TLS 인증서 발급과 관리를 자동화할 수 있습니다. Caddy는 도메인 기반 사이트에서 HTTPS를 기본으로 사용하는 설계를 가지고 있습니다.
Caddy는 L7을 지원하는가#
네. 기본 reverse_proxy 기능은 HTTP 계층에서 동작하며 Host·URL·헤더 등의 HTTP 정보를 기반으로 요청을 처리할 수 있습니다.
Caddy는 L4를 지원하는가#
기본 Caddy에 TCP/UDP L4 proxy가 포함되어 있는 것은 아닙니다. caddy-l4 확장 모듈을 추가하면 TCP·UDP Layer 4 프록시 기능을 사용할 수 있습니다.
caddy-l4는 공식 Caddy 기본 기능인가#
아닙니다. 별도 프로젝트이며 저장소에서도 Caddy Web Server 공식 조직의 저장소가 아니라고 명시합니다. 또한 아직 개발 중이므로 breaking changes 가능성을 주의해야 합니다.
Caddy에서 TCP 프록시가 가능한가#
caddy-l4를 추가하면 가능합니다. Raw TCP 연결을 다른 backend로 프록시하는 기능을 제공합니다.
UDP도 가능한가#
caddy-l4는 TCP와 UDP를 대상으로 하는 Layer 4 앱으로 개발되고 있습니다.
TLS SNI 라우팅도 가능한가#
caddy-l4는 TLS ServerName을 이용해 backend를 선택하는 구성을 지원합니다.
Caddy에서 TLS Termination이 가능한가#
네. 기본 HTTP 앱에서도 HTTPS 종단점 역할을 할 수 있으며 caddy-l4에도 Layer 4 TLS termination handler가 존재합니다. 다만 L4 TLS handler는 인증서를 직접 발급하는 것이 아니라 Caddy가 관리하는 인증서를 사용합니다.
Docker와 Caddy를 함께 사용할 수 있는가#
매우 일반적인 구성입니다. Caddy를 외부 진입점으로 두고 Docker 내부 서비스에 컨테이너 이름과 포트로 reverse proxy할 수 있습니다.
Nginx 대신 Caddy를 사용해도 되는가#
일반적인 웹사이트·API·개인 VPS·Docker reverse proxy 환경에서는 충분히 검토할 수 있습니다. 특히 자동 HTTPS와 간결한 구성이 중요한 환경에서 장점이 큽니다. 다만 기존 Nginx 생태계, 특수 모듈, 매우 복잡한 네트워크 정책 등 요구사항에 따라 선택이 달라질 수 있습니다.
핵심 정리#
Caddy를 가장 단순하게 정의하면:
HTTPS를 자동화하면서 여러 내부 서비스를 외부에 안전하고 간단하게 연결해주는 현대적인 웹서버이자 리버스 프록시
라고 할 수 있습니다.
기본 구조는 다음과 같습니다.
flowchart LR
CLIENT[Client]
C[Caddy<br/>Automatic HTTPS<br/>TLS Termination<br/>L7 Reverse Proxy]
APP1[Web App]
APP2[API]
APP3[Admin]
APP4[Monitoring]
CLIENT -->|HTTPS| C
C --> APP1
C --> APP2
C --> APP3
C --> APP4Caddy의 핵심 강점은 다음 구조로 요약할 수 있습니다.
flowchart TB
C[Caddy]
A[자동 HTTPS]
T[TLS 인증서 자동 관리]
R[L7 Reverse Proxy]
B[Load Balancing]
S[Static File Server]
D[Docker Gateway]
L4[caddy-l4 확장<br/>TCP · UDP · TLS SNI]
C --> A
C --> T
C --> R
C --> B
C --> S
C --> D
C -. 선택적 확장 .-> L4공식 Caddy는 도메인 기반 설정에서 Automatic HTTPS를 제공하고 강력한 HTTP reverse proxy 기능을 갖추고 있습니다.
그리고 HTTP 이외의 TCP·UDP 영역이 필요하다면 caddy-l4를 추가해 Layer 4 프록시, TLS termination, SNI 기반 라우팅 등으로 확장할 수 있습니다. 다만 caddy-l4는 기본 Caddy에 포함된 공식 표준 기능이 아니라 별도의 개발 중 프로젝트라는 점은 반드시 구분해야 합니다.
결국 Caddy의 가장 큰 강점은 단순합니다.
작은 설정으로 HTTPS를 자동화하고, 여러 웹서비스를 L7에서 통합하며, 필요할 때는 L4까지 확장할 수 있다는 것.
특히 한 대의 VPS에서 Docker 기반으로 여러 서비스를 운영한다면 Caddy는 서버 앞단의 통합 진입점 Edge Gateway 역할을 매우 간결하게 구성할 수 있는 선택지입니다.