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