{ # HTTP/1.1 + HTTP/2 + HTTP/3 (QUIC). Cloudflare serves h3 to browsers; # origin↔CF is TCP, but enabling h3 here is harmless + future-proof. servers { protocols h1 h2 h3 } } # Shared security headers. (No strict CSP yet — the app uses inline # scripts; we'll add a nonce-based CSP later.) (sechdrs) { header { Strict-Transport-Security "max-age=31536000; includeSubDomains" X-Content-Type-Options "nosniff" X-Frame-Options "SAMEORIGIN" Referrer-Policy "strict-origin-when-cross-origin" -Server } } # All sites use the Cloudflare Origin cert (valid to 2041, no ACME/renewal). (cfcert) { tls /etc/ssl/cannabuddy/origin.crt /etc/ssl/cannabuddy/origin.key } # --- Marketing landing (apex) --- cannabuddy.eu, www.cannabuddy.eu { import cfcert import sechdrs encode zstd gzip root * /var/www/cannabuddy-landing file_server } # --- App (PWA) --- tenant resolved by login, not subdomain app.cannabuddy.eu { import cfcert import sechdrs encode zstd gzip # MQTT-over-WebSocket → Mosquitto ws listener (localhost) @mqtt path /mqtt /mqtt/* reverse_proxy @mqtt 127.0.0.1:8083 # everything else → Astro SSR (Node/pm2) reverse_proxy 127.0.0.1:7502 } # --- Superadmin console (same app, host-routed; lock behind CF Access) --- admin.cannabuddy.eu { import cfcert import sechdrs encode zstd gzip reverse_proxy 127.0.0.1:7502 } # --- Forgejo --- git.cannabuddy.eu { import cfcert import sechdrs reverse_proxy 127.0.0.1:3000 } # --- Status (Uptime Kuma) --- status.cannabuddy.eu { import cfcert import sechdrs reverse_proxy 127.0.0.1:3001 }