# Global config { email me@sauravdhakal.com.np acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN} } # ----------------------------------------------- # PUBLIC services (resolves to your public VPS IP) # ----------------------------------------------- # blog.sauravdhakal.com.np { # reverse_proxy blog:3000 # } #n8n-webhook.sauravdhakal.com.np { # reverse_proxy n8n:5678 #} # Public — only webhook endpoint, no UI n8n.sauravdhakal.com.np { @public path /webhook/* /webhook-test/* handle @public { reverse_proxy localhost:5678 } handle { abort # block everything else (UI, API, etc) } } # Private — full n8n UI through VPN n8n-admin.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:5678 } # ----------------------------------------------- # VPN-ONLY services (resolves to 100.81.85.182) # bind tells Caddy to only listen on Netbird interface # ----------------------------------------------- vault.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8080 } actual.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8081 } immich.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8082 } filebrowser.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8083 } syncthing.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8384 } portainer.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:9000 } uptime.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:3001 } # ----------------------------------------------- # Gitea — DUAL MODE # Public: Web UI (read-only via matchers) # Private: Full access (SSH + push/pull via VPN) # ----------------------------------------------- # PUBLIC Gitea Web UI gitea.sauravdhakal.com.np { # Allow public access (no bind = all interfaces) # Security headers header { X-Content-Type-Options nosniff X-Frame-Options DENY Referrer-Policy strict-origin-when-cross-origin } # Restrict dangerous endpoints on public access # Block only git PUSH operations (write), allow clone (read) @publicDangerous { path /api/v1/repos/*/archive/* path /repos/*/archive/* path /*/git-receive-pack } handle @publicDangerous { respond 403 } # Allow everything else (UI, API read, etc) reverse_proxy localhost:3000 { header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} } } # PRIVATE Gitea (Full Access via VPN) gitea-private.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:3000 } # Woodpecker CI — VPN only ci.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8000 } # Your site — public, with caching sauravdhakal.com.np, www.sauravdhakal.com.np { root * /home/saurav/site/public header /static/* Cache-Control "public, max-age=31536000, immutable" # assets forever header /assets/* Cache-Control "public, max-age=31536000, immutable" # assets forever # This is where you learn caching header Cache-Control "public, max-age=3600" # cache 1 hour by default file_server encode gzip } memos.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:5230 } dozzle.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:8888 } docs.sauravdhakal.com.np { bind 100.81.85.182 reverse_proxy localhost:3030 } # # glances.sauravdhakal.com.np { # bind 100.81.85.182 # reverse_proxy localhost:61208 # }