{$SERVER_NAME:localhost} {
# Caddy automatically enables HTTPS when SERVER_NAME is a real domain
# For localhost, it uses HTTP only
# Security headers
header {
# Prevent clickjacking
X-Frame-Options "SAMEORIGIN"
# Prevent MIME type sniffing
X-Content-Type-Options "nosniff"
# Enable XSS protection
X-XSS-Protection "1; mode=block"
# Referrer policy
Referrer-Policy "strict-origin-when-cross-origin"
# Remove server header
-Server
}
# Health endpoints
handle /health {
rewrite * /v2/health
reverse_proxy finance-query-v2:8000
}
handle /ping {
rewrite * /v2/health
reverse_proxy finance-query-v2:8000
}
# V2 API (Rust)
handle /v2/* {
reverse_proxy finance-query-v2:8000
}
# V2 WebSocket streaming
handle /v2/stream {
reverse_proxy finance-query-v2:8000
}
# V1 API (Python)
handle /v1/* {
reverse_proxy finance-query-v1:8000
}
# V1 WebSocket endpoints
handle /quotes {
reverse_proxy finance-query-v1:8000
}
handle /profile* {
reverse_proxy finance-query-v1:8000
}
handle /market {
reverse_proxy finance-query-v1:8000
}
handle /hours {
reverse_proxy finance-query-v1:8000
}
# Monitoring (protected with basic auth)
# Password hash is injected by caddy-entrypoint.sh
handle /grafana* {
basicauth * {
admin {{HASHED_PASSWORD}}
}
reverse_proxy grafana:3000
}
handle /prometheus* {
basicauth * {
admin {{HASHED_PASSWORD}}
}
uri strip_prefix /prometheus
reverse_proxy prometheus:9090
}
# Root path shows health status
handle / {
rewrite * /v2/health
reverse_proxy finance-query-v2:8000
}
# Default to V2
handle {
reverse_proxy finance-query-v2:8000
}
# Logging
log {
output stdout
format json
}
}