지시어
각 항목은 문법, 지정하지 않았을 때의 기본값, 쓸 수 있는 위치를 보여 줍니다. 버전 표기(어느 버전에서 도입되었는지 알려 주는 Since: 줄)는 아직 공개하지 않았습니다.
📖 이 페이지는 출발점이 되는 일부를 다룹니다. 여기에 없어도 받아들여지는 지시어는 pingclair validate가 검증합니다. 서버가 구현하지 않은 지시어는 조용히 받아들이지 않고 이름을 들어 거부합니다.
encode
섹션 제목: “encode”Syntax: encode <format> [<format> ...]Default: no compressionContext: site block응답을 압축합니다. 인수는 선호 순서대로 나열하며 클라이언트가 받아들이는 첫 형식을 사용합니다. 지원 형식은 zstd와 gzip입니다.
Brotli를 지정하면 gzip으로의 암묵적 하향이 아니라 컴파일 오류가 됩니다. 프록시에 스트리밍 Brotli 인코더가 없어 그 옵션을 충족할 수 없기 때문입니다.
example.com { encode zstd gzip file_server ./public}file_server
섹션 제목: “file_server”Syntax: file_server [<root>]Default: disabledContext: site block디스크에서 파일을 제공합니다. MIME 타입 판별, 범위 요청, ETag와 Last-Modified 검증을 지원합니다. 인수를 주면 이 지시어 자체의 루트가 되고, 생략하면 root로 설정한 사이트 루트를 씁니다.
localhost:8080 { file_server ./public}header
섹션 제목: “header”Syntax: header [<matcher>] <field> <value> header [<matcher>] { <field> <value> # set +<field> <value> # append -<field> # remove set <field> <value> # set, spelled explicitly }Default: noneContext: site block응답 헤더를 추가, 교체, 제거합니다. 필드 이름만 쓰면 설정, +를 앞에 두면 추가, -를 앞에 두면 제거입니다.
example.com { header { X-Frame-Options "DENY" X-Content-Type-Options "nosniff" Strict-Transport-Security "max-age=31536000; includeSubDomains" -X-Powered-By }}log
섹션 제목: “log”Syntax: log [<name>] { <options> }Default: no access sinkContext: site block, global options접근 로그 출력 대상을 설정합니다. 단독 log는 그 사이트의 기본 출력을 켜고, log <name> { ... }는 이름 있는 로거를 설정합니다. 블록이 없는 log <name>은 global options에서 선언한 채널을 참조합니다.
블록 옵션에는 출력 대상과 형식(output, format), hostnames 선택자, include와 exclude 필터, sampling, 그리고 파일 로테이션(mode, dir_mode, roll_*)이 있습니다.
example.com { log { output file /var/log/pingclair/access.log }}레코드는 쓰기 전에 모아 두며, 따라가지 못하는 출력 대상은 레코드를 버리고 pingclair_access_log_dropped_total에 계산합니다. 모든 요청을 시스템 저널에 쓰는 경우 저널 수신 측의 처리 비용도 부담합니다.
reverse_proxy
섹션 제목: “reverse_proxy”Syntax: reverse_proxy [<matcher>] <upstream> [<upstream> ...] reverse_proxy [<matcher>] { ... }Default: noneContext: site block요청을 하나 이상의 업스트림으로 전달합니다. 기본 부하 분산 정책은 라운드 로빈입니다. 호스트 이름 업스트림은 dns_refresh 간격으로 다시 해석되므로 새 주소로 재시작한 백엔드에도 개입 없이 따라갑니다. 해석에 실패하면 직전 주소를 로테이션에 남겨 둡니다.
:80 :8080 { reverse_proxy { lb_policy least_conn to 10.0.0.1:8080 { weight 3 } to 10.0.0.2:8080 to 10.0.0.3:8080 { backup } health_check { path /health interval 5s timeout 2s status 200 204 consecutive_failure 3 consecutive_success 2 } }}능동 상태 확인은 대역 외에서 실행되므로 실패한 백엔드는 사용자 요청이 도달하기 전에 로테이션에서 빠지고, 설정한 횟수만큼 성공하면 복귀합니다. backup 업스트림은 모든 주 업스트림을 쓸 수 없을 때만 사용합니다.
root
섹션 제목: “root”Syntax: root [<matcher>] <path>Default: noneContext: site block사이트 루트를 설정합니다. file_server는 자체 루트를 가질 수 있지만, 여기에서 설정하면 파일을 다루는 다른 지시어와 파일 서버가 같은 위치를 가리키게 됩니다.
example.com { root * /srv/public file_server}tls
섹션 제목: “tls”Syntax: tls <mode> tls { <options> }Default: automatic HTTPS for public namesContext: site block인증서를 얻는 방법을 제어합니다.
| 모드 | 동작 |
|---|---|
tls auto |
ACME로 공개 인증서를 발급받고 자동으로 갱신합니다. |
tls internal |
상주하는 로컬 인증 기관에서 발급합니다. 루트 인증서는 $PINGCLAIR_TLS_STORE/internal/root.crt에 있고 클라이언트가 신뢰해야 합니다. |
tls { cert ...; key ... } |
블록에서 지정한 인증서와 키 파일을 사용합니다. |
블록 형식은 http3로 HTTP/3을 켜고 dns cloudflare <token>으로 DNS-01 발급도 지원합니다. 구현된 DNS 공급자는 이것뿐입니다. 다른 공급자 이름은 받아들이고 무시하는 대신 기동 시 거부됩니다. DNS-01이 와일드카드 인증서를 성립시키는 전제이기 때문입니다.
example.com { tls { cert /etc/pingclair/certs/example.com.pem key /etc/pingclair/certs/example.com.key http3 } reverse_proxy localhost:3000}🌍 Global options
섹션 제목: “🌍 Global options”Global options는 파일 맨 앞의 이름 없는 블록에 씁니다.
| 옵션 | 문법 | 내용 |
|---|---|---|
admin |
admin <address> [<token>] |
Admin API 리스너. token이 없으면 루프백 연결만 받습니다. |
auto_https |
auto_https on | off | disable_redirects |
자동 HTTPS와 80번 포트 리디렉션을 제어합니다. |
dns_refresh |
dns_refresh <duration> |
호스트 이름 업스트림의 재해석 간격. off는 기동 시 해석한 주소로 고정합니다. |
email |
email <address> |
ACME 발급에 쓰는 계정 이메일. |
trusted_proxies |
trusted_proxies <cidr> [<cidr> ...] |
클라이언트 식별 헤더를 주장할 수 있는 대응 지점. 변경은 재시작이 필요합니다. |
{ email admin@example.com admin 127.0.0.1:2019 dns_refresh 30s}