Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 568 lines 18 kB view raw
1# lith production Caddyfile — full subdomain routing 2# Cloudflare handles TLS. Caddy serves HTTP on :80. 3 4# --- papers.aesthetic.computer --- 5# (touched 2026-04-29 to re-fire webhook after the install-Caddyfile-before-reload fix) 6:443 { 7 tls /etc/caddy/origin-cert.pem /etc/caddy/origin-key.pem 8 log { 9 output file /var/log/caddy/access.log { 10 roll_size 50MiB 11 roll_keep 3 12 roll_keep_for 72h 13 } 14 format json 15 level INFO 16 } 17 # --- Global performance headers --- 18 # Cache static assets (1h fresh, serve stale for 24h while revalidating) 19 @cacheable path *.mjs *.js *.css *.woff2 *.woff *.ttf *.png *.jpg *.jpeg *.svg *.gif *.webp *.ico *.mp3 *.wav *.mp4 *.json 20 header @cacheable Cache-Control "public, max-age=3600, stale-while-revalidate=86400" 21 header @cacheable Access-Control-Allow-Origin * 22 23 # Service workers must always revalidate — cached sw.js delays rollout of 24 # bumped CACHE_NAME, pinning clients to stale module caches. 25 @serviceworker path /sw.js /firebase-messaging-sw.js 26 header @serviceworker Cache-Control "no-cache, no-store, must-revalidate" 27 28 # HTML: no-cache (always revalidate, but use ETag for 304) 29 @html path / *.html 30 header @html Cache-Control "no-cache" 31 32 # Encode everything (Caddy does this by default, but be explicit) 33 encode zstd gzip 34 35 @papers host papers.aesthetic.computer papers.prompt.ac 36 handle @papers { 37 handle /en { 38 rewrite * /index.html?lang=en 39 root * /opt/ac/system/public/papers.aesthetic.computer 40 file_server 41 } 42 handle /da { 43 rewrite * /index.html?lang=da 44 root * /opt/ac/system/public/papers.aesthetic.computer 45 file_server 46 } 47 handle /es { 48 rewrite * /index.html?lang=es 49 root * /opt/ac/system/public/papers.aesthetic.computer 50 file_server 51 } 52 handle /cn { 53 rewrite * /index.html?lang=zh 54 root * /opt/ac/system/public/papers.aesthetic.computer 55 file_server 56 } 57 root * /opt/ac/system/public/papers.aesthetic.computer 58 59 # /platter is the existing white research-records page (platter.html). 60 # We briefly created /platter/ as a directory with our own index — that 61 # was the wrong call; restored below by deleting the dir's index and 62 # reversing the prior 301 with a 302 to invalidate cached redirects. 63 # /platter/jeffrey/ remains a real directory (the dashboard); its 64 # explicit canonical redirect stays so the page's relative 65 # `./manifest.json` fetch resolves correctly. 66 # (See: 2026-04-29 platter restoration.) 67 redir /platter/ /platter 302 68 redir /platter/jeffrey /platter/jeffrey/ permanent 69 70 # SPA fallback for unknown paths: if none of {path}, {path}.html, 71 # {path}/index.html, or {path}index.html exists on disk, serve 72 # /index.html — but mark it no-cache. Without this, a request for a 73 # not-yet-deployed PDF gets the SPA HTML, and Cloudflare pins that 74 # HTML to the PDF URL for 4h via its default static-asset cache. 75 # (See: 2026-04-26 latency-paper deploy gap.) The two index.html 76 # terms cover both /platter (no slash → {path}/index.html) and 77 # /platter/ (slash → {path}index.html). (See: 2026-04-29 78 # jeffrey-platter URL move.) 79 @missing not file { 80 try_files {path} {path}.html {path}/index.html {path}index.html 81 } 82 handle @missing { 83 header Cache-Control "no-cache, must-revalidate, max-age=0" 84 rewrite * /index.html 85 file_server 86 } 87 88 # NOTE: {path} is intentionally absent from the top-level try_files. 89 # Caddy's try_files matches directories as well as files, so including 90 # {path} would silently match a request for /platter (the directory), 91 # short-circuit before {path}/index.html, then file_server would serve 92 # the wrong content rather than canonicalizing to /platter/. Without 93 # {path} here, file_server handles existing regular files itself and 94 # issues a 301 redirect for directory-without-slash to the canonical 95 # /<dir>/ form. (See: 2026-04-29 platter URL move.) 96 try_files {path}.html {path}/index.html {path}index.html 97 file_server 98 } 99 100 # --- bills.aesthetic.computer --- 101 @bills host bills.aesthetic.computer 102 handle @bills { 103 root * /opt/ac/system/public/bills.aesthetic.computer 104 try_files {path} {path}.html /index.html 105 file_server 106 } 107 108 # --- give.aesthetic.computer --- 109 @give host give.aesthetic.computer 110 handle @give { 111 handle /api/* { 112 reverse_proxy localhost:8888 113 } 114 handle /da { 115 rewrite * /index.html?lang=da&currency=dkk 116 root * /opt/ac/system/public/give.aesthetic.computer 117 file_server 118 } 119 handle /es { 120 rewrite * /index.html?lang=es&currency=usd 121 root * /opt/ac/system/public/give.aesthetic.computer 122 file_server 123 } 124 handle /de { 125 rewrite * /index.html?lang=de&currency=eur 126 root * /opt/ac/system/public/give.aesthetic.computer 127 file_server 128 } 129 handle /cn { 130 rewrite * /index.html?lang=zh&currency=usd 131 root * /opt/ac/system/public/give.aesthetic.computer 132 file_server 133 } 134 root * /opt/ac/system/public/give.aesthetic.computer 135 try_files {path} {path}.html /index.html 136 file_server 137 } 138 139 # --- news.aesthetic.computer --- 140 @news host news.aesthetic.computer 141 handle @news { 142 handle /api/* { 143 reverse_proxy localhost:8888 144 } 145 handle { 146 rewrite * /api/news{uri} 147 reverse_proxy localhost:8888 148 } 149 } 150 151 # --- api.aesthetic.computer --- 152 @apidomain host api.aesthetic.computer api.prompt.ac 153 handle @apidomain { 154 reverse_proxy localhost:8888 155 } 156 157 # --- feed.aesthetic.computer (DP-1 Feed V2 — Go + Postgres) --- 158 @feed host feed.aesthetic.computer 159 handle @feed { 160 header Access-Control-Allow-Origin * 161 handle /api/* { 162 reverse_proxy localhost:8787 163 } 164 handle /health { 165 reverse_proxy localhost:8787 166 } 167 handle { 168 root * /opt/dp1-feed 169 rewrite * /landing-page.html 170 file_server 171 } 172 } 173 174 # --- ipfs.aesthetic.computer (self-hosted IPFS gateway) --- 175 # Kubo emits Access-Control-Allow-Origin: * on its own. An earlier Caddy 176 # `header` directive was stacking a second copy, producing "*, *" that 177 # browsers reject. Let Kubo own the header, Caddy just proxies. 178 @ipfs host ipfs.aesthetic.computer 179 handle @ipfs { 180 reverse_proxy localhost:8090 181 } 182 183 # --- justanothersystem.org --- 184 @wwwjas2 host www.justanothersystem.org 185 handle @wwwjas2 { 186 redir https://justanothersystem.org{uri} 301 187 } 188 189 @jas host justanothersystem.org 190 handle @jas { 191 handle /api/* { 192 reverse_proxy localhost:8888 193 } 194 redir /bio /cv 301 195 redir /bio/ /cv 301 196 root * /opt/ac/system/public/justanothersystem.org 197 try_files {path} {path}.html /index.html 198 file_server 199 } 200 201 # --- builds.false.work --- 202 @builds_api { 203 host builds.false.work 204 path /api/* /.netlify/functions/* 205 } 206 handle @builds_api { 207 reverse_proxy localhost:8888 208 } 209 @builds host builds.false.work 210 handle @builds { 211 root * /opt/ac/system/public/builds.false.work 212 try_files {path} {path}.html /index.html 213 file_server 214 } 215 216 # --- sotce.net --- 217 @sotce host sotce.net www.sotce.net 218 handle @sotce { 219 handle /api/* { 220 reverse_proxy localhost:8888 221 } 222 handle /user { 223 reverse_proxy localhost:8888 224 } 225 handle /handle { 226 reverse_proxy localhost:8888 227 } 228 handle /authorized { 229 reverse_proxy localhost:8888 230 } 231 handle /aesthetic.computer/* { 232 uri strip_prefix /aesthetic.computer 233 root * /opt/ac/system/public/aesthetic.computer 234 file_server 235 } 236 # Everything else → sotce-net function 237 handle { 238 rewrite * /api/sotce-net{uri} 239 reverse_proxy localhost:8888 240 } 241 } 242 243 # --- kidlisp.com subdomains --- 244 @keep host keep.kidlisp.com 245 handle @keep { 246 handle /api/* { 247 reverse_proxy localhost:8888 248 } 249 handle /technology { 250 root * /opt/ac/system/public/kidlisp.com 251 rewrite * /keeps-tech.html 252 file_server 253 } 254 handle /wallet { 255 root * /opt/ac/system/public/kidlisp.com 256 rewrite * /wallet/index.html 257 file_server 258 } 259 handle { 260 root * /opt/ac/system/public/kidlisp.com 261 rewrite * /keeps.html 262 file_server 263 } 264 } 265 266 @buy host buy.kidlisp.com 267 handle @buy { 268 root * /opt/ac/system/public/kidlisp.com 269 rewrite * /buy.html 270 file_server 271 } 272 273 @pj host pj.kidlisp.com 274 handle @pj { 275 root * /opt/ac/system/public/kidlisp.com 276 rewrite * /pj.html 277 file_server 278 } 279 280 @device host device.kidlisp.com 281 handle @device { 282 handle /api/* { 283 reverse_proxy localhost:8888 284 } 285 handle /js/* { 286 root * /opt/ac/system/public/kidlisp.com 287 file_server 288 } 289 handle /qr/* { 290 root * /opt/ac/system/public/kidlisp.com 291 rewrite * /qr.html 292 file_server 293 } 294 handle { 295 root * /opt/ac/system/public/kidlisp.com 296 rewrite * /device.html 297 file_server 298 } 299 } 300 301 @topcalm host top.kidlisp.com calm.kidlisp.com 302 handle @topcalm { 303 handle /js/* { 304 root * /opt/ac/system/public/kidlisp.com 305 file_server 306 } 307 reverse_proxy localhost:8888 308 } 309 310 @learn host learn.kidlisp.com 311 handle @learn { 312 handle /api/* { 313 reverse_proxy localhost:8888 314 } 315 handle /decree* { 316 root * /opt/ac/system/public/kidlisp.com 317 rewrite * /decree.html 318 file_server 319 } 320 handle { 321 root * /opt/ac/system/public/kidlisp.com 322 rewrite * /learn.html 323 file_server 324 } 325 } 326 327 @keepsredirect host keeps.kidlisp.com 328 handle @keepsredirect { 329 redir https://keep.kidlisp.com{uri} 301 330 } 331 332 @keepsac host keeps.aesthetic.computer 333 handle @keepsac { 334 reverse_proxy localhost:8888 335 } 336 337 # --- jas.life --- 338 @jaslife host jas.life 339 handle @jaslife { 340 root * /opt/ac/system/public/jas.life 341 try_files {path} {path}.html /index.html 342 file_server 343 } 344 345 # --- www.jas.life redirect --- 346 @wwwjas host www.jas.life 347 handle @wwwjas { 348 redir https://jas.life{uri} 301 349 } 350 351 # --- pals.aesthetic.computer --- 352 # pals.aesthetic.computer → /api/logo (dynamic logo generation) 353 @pals host pals.aesthetic.computer 354 handle @pals { 355 rewrite * /api/logo{uri} 356 reverse_proxy localhost:8888 357 } 358 359 @l5prompt host l5.prompt.ac 360 handle @l5prompt { 361 redir https://l5.aesthetic.computer{uri} 301 362 } 363 @p5prompt host p5.prompt.ac 364 handle @p5prompt { 365 redir https://p5.aesthetic.computer{uri} 301 366 } 367 @procprompt host processing.prompt.ac 368 handle @procprompt { 369 redir https://processing.aesthetic.computer{uri} 301 370 } 371 @siteprompt host sitemap.prompt.ac 372 handle @siteprompt { 373 redir https://sitemap.aesthetic.computer{uri} 301 374 } 375 @apiprompt host api.prompt.ac 376 handle @apiprompt { 377 redir https://api.aesthetic.computer{uri} 301 378 } 379 380 # --- legacy duckweedtri hosts --- 381 @duckweedaesthetic host duckweedtri.aesthetic.computer 382 handle @duckweedaesthetic { 383 redir https://aesthetic.computer{uri} 301 384 } 385 386 @duckweedprompt host duckweedtri.prompt.ac 387 handle @duckweedprompt { 388 redir https://aesthetic.computer{uri} 301 389 } 390 391 # --- prompt.ac/menuband: serve from origin (no redirect) --- 392 # The host+path matcher is more specific than the host-only @promptac 393 # below, so Caddy evaluates this first. Earlier nested-handle attempt 394 # silently fell through to the redirect; named top-level matchers are 395 # the reliable shape. 396 @promptac_menuband { 397 host prompt.ac 398 path /menuband /menuband/* 399 } 400 handle @promptac_menuband { 401 root * /opt/ac/system/public 402 try_files {path} {path}/index.html 403 file_server 404 } 405 406 # --- prompt.ac → aesthetic.computer (everything else, 301) --- 407 @promptac host prompt.ac 408 handle @promptac { 409 redir https://aesthetic.computer{uri} 301 410 } 411 412 @tryshared { 413 host l5.aesthetic.computer processing.aesthetic.computer 414 path /aesthetic.computer/* 415 } 416 handle @tryshared { 417 root * /opt/ac/system/public 418 file_server 419 } 420 421 # --- l5.aesthetic.computer --- 422 @l5 host l5.aesthetic.computer 423 handle @l5 { 424 handle /api/* { 425 reverse_proxy localhost:8888 426 } 427 handle /docs* { 428 reverse_proxy localhost:8888 429 } 430 root * /opt/ac/system/public/l5.aesthetic.computer 431 try_files {path} {path}.html /index.html 432 file_server 433 } 434 435 # --- processing.aesthetic.computer --- 436 @processing host processing.aesthetic.computer 437 handle @processing { 438 handle /api/* { 439 reverse_proxy localhost:8888 440 } 441 handle /docs* { 442 reverse_proxy localhost:8888 443 } 444 root * /opt/ac/system/public/processing.aesthetic.computer 445 try_files {path} {path}.html /index.html 446 file_server 447 } 448 449 # --- rdp.jas.life --- 450 @rdp host rdp.jas.life 451 handle @rdp { 452 root * /opt/ac/system/public/rdp.jas.life 453 try_files {path} {path}.html /index.html 454 file_server 455 } 456 457 # --- kidlisp.com root domain --- 458 @kidlisproot host kidlisp.com www.kidlisp.com 459 handle @kidlisproot { 460 handle /api/* { 461 reverse_proxy localhost:8888 462 } 463 handle /.netlify/functions/* { 464 reverse_proxy localhost:8888 465 } 466 handle /keeps { 467 redir https://keep.kidlisp.com/ 301 468 } 469 # Serve AC runtime assets for iframe embedding 470 handle /aesthetic.computer/* { 471 root * /opt/ac/system/public 472 file_server 473 } 474 # kidlisp.com SPA 475 handle { 476 root * /opt/ac/system/public/kidlisp.com 477 try_files {path} {path}.html /index.html 478 file_server 479 } 480 } 481 482 # --- notepat.com --- 483 @notepatroot host notepat.com www.notepat.com 484 handle @notepatroot { 485 @notepatindex path / 486 handle @notepatindex { 487 rewrite * /notepat 488 } 489 # Permalink: notepat.com/amxd → current notepat.com.amxd as a 490 # direct download. Clients get the Content-Disposition so it 491 # lands in ~/Downloads instead of opening in-browser. 492 handle /amxd { 493 rewrite * /m4l/notepat.com.amxd 494 header Content-Disposition "attachment; filename=\"notepat.com.amxd\"" 495 root * /opt/ac/system/public 496 file_server 497 } 498 reverse_proxy localhost:8888 499 } 500 @mainspa host aesthetic.computer www.aesthetic.computer lith.aesthetic.computer notepat.com www.notepat.com p5.aesthetic.computer sitemap.aesthetic.computer 501 handle @mainspa { 502 # Assets → DO Spaces CDN. The bucket root maps directly to 503 # assets.aesthetic.computer (no /assets/ prefix exists in the 504 # bucket), so we use handle_path to strip the matched /assets/ 505 # prefix before substituting {path} into the redirect target. 506 # The previous form (`handle /assets/*` + `{uri}`) doubled the 507 # prefix and produced 403s on assets.aesthetic.computer/assets/... 508 # (See: 2026-04-29 platter readings 403 fix.) 509 handle_path /assets/* { 510 redir https://assets.aesthetic.computer{path} 302 511 } 512 # API → lith 513 handle /api/* { 514 reverse_proxy localhost:8888 515 } 516 handle /.netlify/functions/* { 517 reverse_proxy localhost:8888 518 } 519 # Media → lith 520 handle /media/* { 521 reverse_proxy localhost:8888 522 } 523 # Static rewrite shortcuts 524 handle /disks/* { 525 uri strip_prefix /disks 526 root * /opt/ac/system/public/aesthetic.computer/disks 527 file_server 528 } 529 handle /lib/* { 530 uri strip_prefix /lib 531 root * /opt/ac/system/public/aesthetic.computer/lib 532 file_server 533 } 534 # Static files, then SPA fallback 535 handle { 536 root * /opt/ac/system/public 537 @static file 538 handle @static { 539 file_server 540 } 541 handle { 542 reverse_proxy localhost:8888 543 } 544 } 545 } 546 547 # --- false.work --- 548 @falseroot host false.work 549 handle @falseroot { 550 root * /opt/ac/system/public/false.work 551 try_files {path} {path}.html /index.html 552 file_server 553 } 554 555 @wwwfalse host www.false.work 556 handle @wwwfalse { 557 redir https://false.work{uri} 301 558 } 559 560 # --- Fallback for any unmatched host --- 561 handle { 562 reverse_proxy localhost:8888 563 } 564} 565 566:80 { 567 redir https://{host}{uri} 301 568}