Repository navigation
Expand file tree
/
Copy pathCaddyfile
More file actions
99 lines (86 loc) · 3.92 KB
/
Copy pathCaddyfile
File metadata and controls
99 lines (86 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# Caddy config for the tronbrowser.dev static site. Railway terminates TLS at
# the edge and injects $PORT; Caddy serves plain HTTP on it.
{
admin off
auto_https off
}
:{$PORT:80} {
# Redirect www -> apex (Railway routes both hosts to this container).
@www host www.tronbrowser.dev
redir @www https://tronbrowser.dev{uri} permanent
root * /srv
# API lives at tronbrowser.dev/api — reverse-proxy to the bundled API process
# in this same container (one service, one domain). Keep before file_server.
@api path /api/* /api
reverse_proxy @api localhost:8090
# x402 crawl gateway (services/api/src/crawl-gate.ts). /crawl is the day-pass
# sales page and checkout, answered by the API. Every other page read is
# checked there first: AI training crawlers get the 402 offer, everyone else
# (people, search crawlers, AI chat fetchers) gets the page.
@crawl path /crawl /crawl/*
reverse_proxy @crawl localhost:8090
@pages {
method GET HEAD
not path /api/* /api /mcp/* /mcp /crawl /crawl/*
}
forward_auth @pages localhost:8090 {
uri /api/crawl-gate
}
# OpenMCP relay (tronbrowser.dev/mcp/tron): same API process. Its descriptor
# is the static /.well-known/openmcp.json below, which is what makes the
# listing "verified" on a catalog (served from this origin, not registered).
@mcp path /mcp/* /mcp
reverse_proxy @mcp localhost:8090 {
# Railway terminates TLS and Caddy sees plain HTTP, so the proto it
# forwards is "http"; the relay's health reply echoes the caller's scheme.
header_up X-Forwarded-Proto https
}
# Security headers on every response.
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"
Permissions-Policy "camera=(), microphone=(), geolocation=(), browsing-topics=()"
-Server
}
# The crawl pass pages get no CSP: their Buy button posts to /crawl/checkout,
# which redirects to coinpayportal.com, and form-action 'self' would block it.
@notcrawl not path /crawl /crawl/*
header @notcrawl Content-Security-Policy "default-src 'self'; script-src 'self' https://crawlproof.com https://cdn.jsdelivr.net; connect-src 'self' https://crawlproof.com https://cdn.jsdelivr.net; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://built.indie.pit.world https://pwamart.com; font-src 'self'; frame-src 'self' https://crawlproof.com; base-uri 'self'; form-action 'self' https://pit.world; frame-ancestors 'none'"
# Correct content types for machine-readable files.
@plain path /robots.txt /llms.txt /llms-full.txt /.well-known/security.txt
header @plain Content-Type "text/plain; charset=utf-8"
header /skill.md Content-Type "text/markdown; charset=utf-8"
header /install.sh Content-Type "text/x-shellscript; charset=utf-8"
header /sitemap.xml Content-Type "application/xml; charset=utf-8"
header /manifest.json Content-Type "application/manifest+json; charset=utf-8"
header /.well-known/openmcp.json Content-Type "application/json; charset=utf-8"
header /.well-known/openmcp.json Access-Control-Allow-Origin "*"
# Caching: long for images, SHORT for code/HTML so updates propagate fast
# (no content hashing yet — don't let stale JS strand logged-in users).
@images path *.svg *.png *.ico
header @images Cache-Control "public, max-age=86400"
@code path *.js *.css *.html / /privacy /login /settings /dns /push
header @code Cache-Control "public, max-age=60, must-revalidate"
encode gzip zstd
# Pretty URLs.
@privacy path /privacy
rewrite @privacy /privacy.html
@login path /login
rewrite @login /login.html
@settings path /settings
rewrite @settings /settings.html
@dns path /dns
rewrite @dns /dns.html
@push path /push
rewrite @push /push.html
file_server
# Real 404s (no SPA catch-all) with a branded page.
handle_errors {
@404 expression `{http.error.status_code} == 404`
rewrite @404 /404.html
header Content-Type "text/html; charset=utf-8"
file_server
}
}