# ── Global options ───────────────────────────────────────────────────────────── { debug servers { protocols h1 h2 } } # ── Snippets reutilizables ───────────────────────────────────────────────────── (security_headers) { header { Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" -Server } } (internal_only) { basic_auth { carlos $2a$14$6MgHKR/jLD..MFkuNo0i1OBs.wwZOntIDiYsYpsyyH./OCKa8SoGS } @blocked not remote_ip 24.139.235.46/32 192.168.68.0/24 2605:ba00:3108::/48 74.115.203.2/32 165.225.192.0/18 abort @blocked } # ── Main site ────────────────────────────────────────────────────────────────── carloselugo.com, www.carloselugo.com { reverse_proxy frontend:80 import security_headers encode gzip log { output file /var/log/caddy/access.log format json } } # ── Uptime Kuma ──────────────────────────────────────────────────────────────── uptime.carloselugo.com { import internal_only import security_headers reverse_proxy uptime-kuma:3001 encode gzip log { output file /var/log/caddy/uptime.log format json } } # ── Grafana — metrics.carloselugo.com ───────────────────────────────────────── metrics.carloselugo.com { import internal_only import security_headers header X-Frame-Options "SAMEORIGIN" reverse_proxy grafana:3000 encode gzip log { output file /var/log/caddy/metrics.log format json } } # ── Portainer — portainer.carloselugo.com ───────────────────────────────────── portainer.carloselugo.com { import internal_only import security_headers header X-Frame-Options "SAMEORIGIN" reverse_proxy portainer:9000 encode gzip log { output file /var/log/caddy/portainer.log format json } } # ── ntfy (notificaciones push) ──────────────────────────────────────────────── ntfy.carloselugo.com { reverse_proxy ntfy:80 { # ntfy usa SSE (Server-Sent Events) para push en tiempo real. # Sin esto, las notificaciones no llegan al celular. flush_interval -1 } } # ── Gitea (git) ─────────────────────────────────────────────────────────────── git.carloselugo.com { import security_headers reverse_proxy gitea:3000 encode gzip log { output file /var/log/caddy/gitea.log format json } } # ── Dozzle (logs de containers) — protegido ─────────────────────────────────── logs.carloselugo.com { import internal_only import security_headers reverse_proxy dozzle:8080 encode gzip log { output file /var/log/caddy/dozzle.log format json } } # ── NI Quiz — evento público ─────────────────────────────────────────────────── ni-quiz.carloselugo.com { import security_headers reverse_proxy ni-quiz:8000 { header_up Host {host} header_up X-Real-IP {remote_host} } log { output file /var/log/caddy/ni-quiz.log format json } } # ── MarkItDown ──────────────────────────────────────────────────────────────── md.carloselugo.com { import security_headers reverse_proxy markitdown:8000 log { output file /var/log/caddy/markitdown.log format json } } # ── NI Quiz — evento público ─────────────────────────────────────────────────── route-rush.carloselugo.com { import security_headers reverse_proxy route-rush:8001 { header_up Host {host} header_up X-Real-IP {remote_host} } log { output file /var/log/caddy/ni-quiz.log format json } } # ── IT Tools ────────────────────────────────────────────────────────────────── tools.carloselugo.com { import security_headers reverse_proxy it-tools:80 encode gzip log { output file /var/log/caddy/it-tools.log format json } }