Antonio Mika
·
2026-10-25
1{
2 storage redis {
3 address {$VALKEY_ADDR}
4 password "{$VALKEY_PASSWORD}"
5 timeout 5
6 key_prefix "caddy"
7 }
8 on_demand_tls {
9 ask http://web:3000/check
10 }
11 servers {
12 metrics
13 trusted_proxies static 0.0.0.0/0
14 }
15}
16
17# Metrics routes need ?x-authorization={$METRICS_TOKEN}. An unset token matches
18# nothing.
19(metrics_token) {
20 expression `{http.request.uri.query.x-authorization} == "{$METRICS_TOKEN}" && "{$METRICS_TOKEN}" != ""`
21}
22
23# Apps serve metrics on /_metrics, which only the token-checked routes reach.
24# Scrapes stay out of the access logs so the token does too.
25(block_app_metrics) {
26 @appmetrics path /_metrics /_metrics/*
27 respond @appmetrics 404
28 @metricsroutes path /_caddy/metrics /_ssh/metrics /_web/metrics /_imgproxy/metrics /_app/metrics
29 log_skip @metricsroutes
30}
31
32# custom domains
33:443 {
34 import block_app_metrics
35 reverse_proxy web:3000
36 log {
37 format append {
38 server_id {$APP_DOMAIN}
39 }
40 }
41 tls {$APP_EMAIL} {
42 on_demand
43 }
44 encode zstd gzip
45}
46
47# subdomains and root pgs domain
48*.{$APP_DOMAIN}, {$APP_DOMAIN} {
49 import block_app_metrics
50 reverse_proxy web:3000
51 log {
52 format append {
53 server_id {$APP_DOMAIN}
54 }
55 }
56 tls {$APP_EMAIL} {
57 dns cloudflare {$CF_API_TOKEN}
58 resolvers 1.1.1.1
59 }
60
61 encode zstd gzip
62
63 header {
64 # disable FLoC tracking
65 ?Permissions-Policy interest-cohort=()
66
67 # enable HSTS
68 ?Strict-Transport-Security max-age=31536000;
69
70 # disable clients from sniffing the media type
71 ?X-Content-Type-Options nosniff
72
73 # clickjacking protection
74 ?X-Frame-Options DENY
75
76 # keep referrer data off of HTTP connections
77 ?Referrer-Policy no-referrer-when-downgrade
78
79 ?X-XSS-Protection "1; mode=block"
80 }
81
82 @caddymetrics {
83 host {$APP_DOMAIN} *.{$APP_DOMAIN}
84 path /_caddy/metrics
85 import metrics_token
86 }
87
88 metrics @caddymetrics {
89 disable_openmetrics
90 }
91
92 @sshmetrics {
93 host {$APP_DOMAIN} *.{$APP_DOMAIN}
94 path /_ssh/metrics
95 import metrics_token
96 }
97
98 handle @sshmetrics {
99 rewrite * /metrics
100 reverse_proxy ssh:9222
101 }
102
103 @webmetrics {
104 host {$APP_DOMAIN} *.{$APP_DOMAIN}
105 path /_web/metrics
106 import metrics_token
107 }
108
109 handle @webmetrics {
110 rewrite * /_metrics
111 reverse_proxy web:3000 {
112 header_up Host {$APP_DOMAIN}
113 }
114 }
115
116 @imgproxymetrics {
117 host {$APP_DOMAIN} *.{$APP_DOMAIN}
118 path /_imgproxy/metrics
119 import metrics_token
120 }
121
122 handle @imgproxymetrics {
123 rewrite * /metrics
124 reverse_proxy imgproxy:8081
125 }
126}