Caddyfile 지시문
Caddyfile 지시문 (Directives)
지시문(Directives)은 사이트 블록 안에 나타나는 기능적 키워드예요. 때로는 하위 지시문을 포함할 수 있는 자체 블록을 열기도 하지만, 명시되지 않는 한 지시문은 다른 지시문 안에서 사용할 수 없어요.
출처: Caddy 공식 문서
본문
지시문은 사이트 블록 안에 나타나는 기능적 키워드예요. 때로는 하위 지시문을 포함할 수 있는 자체 블록을 열기도 하지만, 명시되지 않는 한 지시문은 다른 지시문 안에서 사용할 수 없어요. 예를 들어 file_server 블록 안에서 basic_auth를 쓸 수 없어요. file_server가 인증을 하는 방법을 모르기 때문이에요. 하지만 handle과 route 같은 특별한 지시문 블록 안에서는 일부 지시문을 사용할 수 있어요. 이들은 HTTP 핸들러 지시문을 그룹화하도록 특별히 설계됐거든요.
다음 지시문은 Caddy에 표준으로 제공되며 HTTP Caddyfile에서 사용할 수 있어요:
| 지시문 (Directive) | 설명 (Description) |
|---|---|
| abort | HTTP 요청을 중단함 |
| acme_server | 내장 ACME 서버 |
| basic_auth | HTTP 기본 인증을 강제함 |
| bind | 서버의 소켓 주소 커스터마이즈 |
| encode | 응답을 인코딩(보통 압축)함 |
| error | 에러 트리거 |
| file_server | 디스크에서 파일 서빙 |
| forward_auth | 외부 서비스에 인증 위임 |
| fs | 파일 I/O에 사용할 파일 시스템 설정 |
| handle | 상호 배타적인 지시문 그룹 |
| handle_errors | 에러 처리를 위한 라우트 정의 |
| handle_path | handle과 같지만 경로 접두사 제거 |
| header | 응답 헤더 설정 또는 제거 |
| import | 스니펫 또는 파일 포함 |
| intercept | 다른 핸들러가 쓴 응답 가로채기 |
| invoke | 명명된 route 호출 |
| log | 액세스/요청 로깅 활성화 |
| log_append | 액세스 로그에 필드 추가 |
| log_skip | 조건에 맞는 요청의 액세스 로깅 건너뛰기 |
| log_name | 쓸 로거 이름 재정의 |
| map | 입력 값을 하나 이상의 출력으로 매핑 |
| method | HTTP 메서드를 내부적으로 변경 |
| metrics | Prometheus 메트릭 노출 엔드포인트 설정 |
| php_fastcgi | FastCGI로 PHP 사이트 서빙 |
| push | HTTP/2 서버 푸시로 콘텐츠 푸시 |
| redir | 클라이언트에 HTTP 리다이렉트 발행 |
| request_body | 요청 본문 조작 |
| request_header | 요청 헤더 조작 |
| respond | 클라이언트에 하드코딩된 응답 작성 |
| reverse_proxy | 강력하고 확장 가능한 리버스 프록시 |
| rewrite | 요청을 내부적으로 재작성 |
| root | 사이트 루트 경로 설정 |
| route | 단일 단위로 문자 그대로 취급되는 지시문 그룹 |
| templates | 응답에 템플릿 실행 |
| timeouts | idle/read/write 타임아웃 설정 |
| tls | TLS 설정 커스터마이즈 |
| tracing | OpenTelemetry 추적 연동 |
| try_files | 파일 존재에 의존하는 재작성 |
| uri | URI 조작 |
| vars | 임의 변수 설정 |
문법 (Syntax)
각 지시문의 문법은 대략 이렇게 생겼어요:
directive [<matcher>] <args...> {
subdirective [<args...>]
}
<carets>는 실제 값으로 대체될 토큰을 나타내요.
[brackets]는 선택적 매개변수를 나타내요.
줄임표 ...는 연속, 즉 하나 이상의 매개변수 또는 줄을 나타내요.
하위 지시문은 문서에 달리 명시되지 않는 한 일반적으로 선택적이에요. [brackets]에 나타나지 않더라도요.
Matchers
대부분(전부는 아니지만)의 지시문은 요청을 필터링할 수 있게 해주는 matcher 토큰을 받아요. Matcher 토큰은 보통 선택적이에요. 지시문의 문법에서 이것을 보면 matcher를 지원한다는 거예요:
[<matcher>]
matcher 토큰은 모두 같은 방식으로 동작하기 때문에 중복을 줄이기 위해 각 페이지마다 matcher 토큰의 다양한 가능성을 설명하지 않아요. 대신 문법에 대한 자세한 설명은 matcher 문서를 참고해요.
지시문 순서 (Directive order)
많은 지시문이 HTTP 핸들러 체인을 조작해요. 그 지시문들이 평가되는 순서는 중요하므로, 기본 순서가 Caddy에 하드코딩돼 있어요.
이 순서는 order 글로벌 옵션이나 route 지시문으로 재정의/커스터마이즈할 수 있어요.
tracing
map
vars
fs
root
log_append
log_skip
log_name
header
copy_response_headers # only in reverse_proxy's handle_response block
request_body
timeouts
redir
# incoming request manipulation
method
rewrite
uri
try_files
# middleware handlers; some wrap responses
basic_auth
forward_auth
request_header
encode
push
intercept
templates
# special routing & dispatching directives
invoke
handle
handle_path
route
# handlers that typically respond to requests
abort
error
copy_response # only in reverse_proxy's handle_response block
respond
metrics
reverse_proxy
php_fastcgi
file_server
acme_server
정렬 알고리즘 (Sorting algorithm)
사용 편의를 위해 Caddyfile 어댑터는 다음 규칙에 따라 지시문을 정렬해요:
-
이름이 다른 지시문은 기본 순서에서의 위치로 정렬돼요. 기본 순서는
order글로벌 옵션으로 재정의할 수 있어요. 플러그인의 지시문은 순서가 없으므로order글로벌 옵션이나route지시문으로 설정해야 해요. -
같은 이름의 지시문은 matcher에 따라 정렬돼요.
-
/foo*같은 단일 경로 matcher 값을 가진 지시문은, 단일 경로를 가진 다른 지시문들과 비교해 특이성에 따라 가장 구체적인 것부터 가장 덜 구체적인 것 순으로 정렬돼요. 이는 위치가 하나뿐인pathmatcher를 가진 이름 있는 matcher에도 적용돼요.일반적으로 이는 경로 길이로 정렬해 수행하며, 뒤의
*는 무시해요. 두 matcher의 경로가 동일하면*가 없는 matcher가 더 구체적인 것으로 간주되어 더 높게 정렬돼요. 같은 길이의 경로는 알파벳순으로 정렬돼요.예를 들어:
-
/foobar는/foo보다 더 구체적이에요. -
/foo는/foo*보다 더 구체적이에요. -
/foo/*는/foo*보다 더 구체적이에요.
-
-
이름 있는 matcher나 여러 값을 가진 경로 matcher 같은 다른 matcher를 가진 지시문은 Caddyfile에 나타난 순서를 유지해요. 단일 경로를 가진 지시문은 그 뒤로 정렬되지 않으므로, 옆에 있는 다른 단일 경로 지시문들 사이에서만 정렬돼요.
예를 들어 이 지시문들은 전혀 재정렬되지 않아요.
@api이름 있는 matcher가 그들을 분리하기 때문이에요:
respond /a* "1"
respond @api "2"
respond /a/b "3"
respond /a "4"
- matcher가 없는 지시문(즉 모든 요청 매칭)은 마지막으로 정렬돼요.
정렬된 순서가 필요하지 않다면, route 지시문으로 순서를 명시적으로 설정하거나 상호 배타적인 handle 블록을 사용해요.
-
vars지시문은 그 matcher 순서가 반전돼요. 서로 덮어쓸 수 있는 값을 설정하는 작업이므로 가장 구체적인 matcher가 마지막에 평가되어야 하기 때문이에요. -
route지시문의 내용은 위의 모든 규칙을 무시하고, 지시문이 나타나는 순서를 보존해요.