From 5caa8f50e800990ff4367b0f420f9c39a0a1ea24 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sun, 8 Nov 2026 13:16:33 +0000 Subject: [PATCH] dev2-site: redirect_to for retired domains; 28 sites 308 to .pwa.pit.world sites.d "redirect_to" ({"default": origin, "": origin}) makes `dev2-site vhost` render redirect-only servers: every host 308s to its target with path and query kept (308 so POSTs and webhooks survive), and port 80 keeps the ACME location so the old certificate renews while the domain lasts. "redirect_paths" sends a prefix elsewhere (c0upons.com/bbs). The 28 apps moved to .pwa.pit.world in #241 now redirect from their old domains (supabase. to -supabase), and env_overrides pointing at the old URLs follow them so a re-provision cannot undo it. Co-Authored-By: Claude Opus 5.5 --- dev2/dev2-site | 52 +++++++++++++++++++++++++ dev2/sites.d/advis0r.com.json | 11 +++++- dev2/sites.d/agenticjobs.work.json | 6 ++- dev2/sites.d/aiornot.vote.json | 15 ++++++- dev2/sites.d/avenasea.com.json | 6 +++ dev2/sites.d/bg0ne.com.json | 6 ++- dev2/sites.d/brisk.news.json | 9 ++++- dev2/sites.d/c0ncerts.com.json | 9 ++++- dev2/sites.d/c0upons.com.json | 25 +++++++++++- dev2/sites.d/cigarunderground.org.json | 6 ++- dev2/sites.d/d1sks.com.json | 6 +++ dev2/sites.d/d3vices.com.json | 6 +++ dev2/sites.d/datamart.help.json | 6 ++- dev2/sites.d/getprivacycode.com.json | 6 +++ dev2/sites.d/goingbroke.now.json | 12 +++++- dev2/sites.d/icemap.app.json | 9 ++++- dev2/sites.d/media2markdown.com.json | 9 ++++- dev2/sites.d/naallo.com.json | 6 +++ dev2/sites.d/opensocial.chat.json | 8 +++- dev2/sites.d/opensourcelegends.com.json | 11 +++++- dev2/sites.d/recipepdfs.com.json | 6 +++ dev2/sites.d/ringhuman.com.json | 12 +++++- dev2/sites.d/saasrow.com.json | 7 +++- dev2/sites.d/submitfleet.com.json | 6 ++- dev2/sites.d/sysops.ceo.json | 6 ++- dev2/sites.d/tleehealth.com.json | 8 +++- dev2/sites.d/tsbb.dev.json | 11 +++++- dev2/sites.d/typeheard.com.json | 8 +++- dev2/sites.d/weedforcrypto.com.json | 9 ++++- 29 files changed, 266 insertions(+), 31 deletions(-) create mode 100644 dev2/sites.d/avenasea.com.json create mode 100644 dev2/sites.d/d1sks.com.json create mode 100644 dev2/sites.d/d3vices.com.json create mode 100644 dev2/sites.d/getprivacycode.com.json create mode 100644 dev2/sites.d/naallo.com.json create mode 100644 dev2/sites.d/recipepdfs.com.json diff --git a/dev2/dev2-site b/dev2/dev2-site index e00230b..16cd089 100755 --- a/dev2/dev2-site +++ b/dev2/dev2-site @@ -1569,7 +1569,59 @@ def proxy_tuned(text, p): mb = p.get("max_body", "512m") return text.replace("__MAX_BODY__", mb).replace("proxy_read_timeout 300s;", "proxy_read_timeout 3600s;\n proxy_send_timeout 3600s;").replace("client_max_body_size " + mb + ";", "client_max_body_size " + mb + ";\n large_client_header_buffers 8 64k;") +def render_redirect_vhost(s, redirect_to): + """A retired site (sites.d "redirect_to"): every host 308s to its new home, path and query kept. + redirect_to maps a host to its target origin, with "default" for the rest; "redirect_paths" + sends a path prefix elsewhere (c0upons.com/bbs). 308 keeps POST a POST (forms, webhooks). + Port 80 keeps the ACME location so the old certificate renews while the domain lasts.""" + if "default" not in redirect_to: die(f"{s['site']}: redirect_to needs a \"default\" target") + hosts = site_domains(s) + [p["host"] for p in (s.get("proxies") or []) if p["host"] not in site_domains(s)] + groups = {} + for h in hosts: + groups.setdefault(redirect_to.get(h, redirect_to["default"]).rstrip("/"), []).append(h) + paths = "".join(f" location ^~ {pre.rstrip('/')} {{\n return 308 {to.rstrip('/')}$request_uri;\n }}\n" + for pre, to in (s.get("redirect_paths") or {}).items()) + conf = (f"# {s['site']}: managed by cli-tools/dev2/dev2-site vhost. Do not hand-edit; re-run\n" + f"# `dev2-site vhost {s['site']}` after changing sites.d/{s['site']}.json.\n" + f"# Retired: the app lives on elsewhere; this domain only redirects (redirect_to).\n") + for to, hs in groups.items(): + names = " ".join(hs) + conf += f""" +server {{ + listen 80; + listen [::]:80; + server_name {names}; + + location ^~ /.well-known/acme-challenge/ {{ + root /var/www/acme; + default_type "text/plain"; + }} +{paths} location / {{ + return 308 {to}$request_uri; + }} +}} + +server {{ + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + server_name {names}; + + ssl_certificate /etc/nginx/ssl/{s['site']}/fullchain.pem; + ssl_certificate_key /etc/nginx/ssl/{s['site']}/privkey.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers off; + +{paths} location / {{ + return 308 {to}$request_uri; + }} +}} +""" + return conf, hosts + def render_vhost(s): + if s.get("redirect_to"): + return render_redirect_vhost(s, s["redirect_to"]) proxies = s.get("proxies") or [] domains = [d for d in site_domains(s) if d not in {p["host"] for p in proxies}] if s.get("nginx_app") is False: # the app runs elsewhere (bittorrented.com); only its proxies live here diff --git a/dev2/sites.d/advis0r.com.json b/dev2/sites.d/advis0r.com.json index ef777cd..4aa02a5 100644 --- a/dev2/sites.d/advis0r.com.json +++ b/dev2/sites.d/advis0r.com.json @@ -1 +1,10 @@ -{ "branch": "main", "env_remove": ["DATABASE_AUTH_TOKEN"] } +{ + "branch": "main", + "env_remove": [ + "DATABASE_AUTH_TOKEN" + ], + "redirect_to": { + "default": "https://advis0r.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/agenticjobs.work.json b/dev2/sites.d/agenticjobs.work.json index be5e75e..ef868dc 100644 --- a/dev2/sites.d/agenticjobs.work.json +++ b/dev2/sites.d/agenticjobs.work.json @@ -2,5 +2,9 @@ "env_overrides": { "OBSCURA_MCP_URL": "", "PGSSLMODE": "require" - } + }, + "redirect_to": { + "default": "https://agenticjobs.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/aiornot.vote.json b/dev2/sites.d/aiornot.vote.json index 51007b5..d52ae7c 100644 --- a/dev2/sites.d/aiornot.vote.json +++ b/dev2/sites.d/aiornot.vote.json @@ -1 +1,14 @@ -{"branch": "master", "env_remove": ["TURSO_DATABASE_URL", "TURSO_AUTH_TOKEN"], "mem_limit": "2g", "node_heap_mb": 1024, "mem_note": "2026-10-01: next + media daemon, 530 MB steady"} +{ + "branch": "master", + "env_remove": [ + "TURSO_DATABASE_URL", + "TURSO_AUTH_TOKEN" + ], + "mem_limit": "2g", + "node_heap_mb": 1024, + "mem_note": "2026-10-01: next + media daemon, 530 MB steady", + "redirect_to": { + "default": "https://aiornot.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/avenasea.com.json b/dev2/sites.d/avenasea.com.json new file mode 100644 index 0000000..2e30ca1 --- /dev/null +++ b/dev2/sites.d/avenasea.com.json @@ -0,0 +1,6 @@ +{ + "redirect_to": { + "default": "https://avenasea.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/bg0ne.com.json b/dev2/sites.d/bg0ne.com.json index 1e7ae44..5164790 100644 --- a/dev2/sites.d/bg0ne.com.json +++ b/dev2/sites.d/bg0ne.com.json @@ -1,4 +1,8 @@ { "mem_limit": "3g", - "mem_note": "2026-10-01: rembg model loads peak at 1.25 GB" + "mem_note": "2026-10-01: rembg model loads peak at 1.25 GB", + "redirect_to": { + "default": "https://bg0ne.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/brisk.news.json b/dev2/sites.d/brisk.news.json index 3632691..24b9209 100644 --- a/dev2/sites.d/brisk.news.json +++ b/dev2/sites.d/brisk.news.json @@ -9,9 +9,14 @@ "env_overrides": { "NEXT_PUBLIC_SUPABASE_ANON_KEY": "secret:NEXT_PUBLIC_SUPABASE_ANON_KEY", "SUPABASE_SERVICE_ROLE_KEY": "secret:SUPABASE_SERVICE_ROLE_KEY", - "NEXT_PUBLIC_SUPABASE_URL": "https://supabase.brisk.news" + "NEXT_PUBLIC_SUPABASE_URL": "https://brisk-supabase.pwa.pit.world" }, "mem_limit": "3g", "node_heap_mb": 1536, - "mem_note": "2026-10-01: ~1 GB steady (apps/notify ~900 MB) beside next-server" + "mem_note": "2026-10-01: ~1 GB steady (apps/notify ~900 MB) beside next-server", + "redirect_to": { + "default": "https://brisk.pwa.pit.world", + "supabase.brisk.news": "https://brisk-supabase.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/c0ncerts.com.json b/dev2/sites.d/c0ncerts.com.json index 5d6de50..7079083 100644 --- a/dev2/sites.d/c0ncerts.com.json +++ b/dev2/sites.d/c0ncerts.com.json @@ -8,9 +8,14 @@ } ], "env_overrides": { - "NEXT_PUBLIC_SUPABASE_URL": "https://supabase.c0ncerts.com", + "NEXT_PUBLIC_SUPABASE_URL": "https://c0ncerts-supabase.pwa.pit.world", "NEXT_PUBLIC_SUPABASE_ANON_KEY": "secret:NEXT_PUBLIC_SUPABASE_ANON_KEY", "SUPABASE_SERVICE_ROLE_KEY": "secret:SUPABASE_SERVICE_ROLE_KEY" }, - "subnet_octet": 178 + "subnet_octet": 178, + "redirect_to": { + "default": "https://c0ncerts.pwa.pit.world", + "supabase.c0ncerts.com": "https://c0ncerts-supabase.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/c0upons.com.json b/dev2/sites.d/c0upons.com.json index 7c8cfe8..6c44e02 100644 --- a/dev2/sites.d/c0upons.com.json +++ b/dev2/sites.d/c0upons.com.json @@ -1 +1,24 @@ -{"branch": "master", "env_remove": ["TURSO_DATABASE_URL", "TURSO_AUTH_TOKEN", "SQLITECLOUD_URL"], "mem_limit": "2g", "mem_note": "2026-10-01: 530 MB steady, 910 MB peak", "nginx_locations": " # c0upons.com/bbs: the tsbb board in ~/www/c0upons.com-bbs (TSBB_BASE_URL=https://c0upons.com/bbs).\n # The path is passed through unstripped: tsbb (>= 0.9.0) mounts itself under it.\n location ~ ^/bbs(/|$) {\n proxy_pass http://127.0.0.1:3293;\n proxy_http_version 1.1;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_set_header X-Forwarded-Host $host;\n proxy_read_timeout 300s;\n }\n", "bbs_note": "2026-10-06: /bbs is a tsbb board in ~/www/c0upons.com-bbs (port 3293, vault c0upons-bbs--prod), not part of this repo's deploy; it follows tsbb GitHub releases", "redis": true, "env_overrides": {"REDIS_URL": "redis://redis:6379"}, "redis_note": "2026-11-02: own redis for @profullstack/scraper-daemon (BullMQ; daily peerpush.com/deals job, c0upons PR #100)"} +{ + "branch": "master", + "env_remove": [ + "TURSO_DATABASE_URL", + "TURSO_AUTH_TOKEN", + "SQLITECLOUD_URL" + ], + "mem_limit": "2g", + "mem_note": "2026-10-01: 530 MB steady, 910 MB peak", + "nginx_locations": " # c0upons.com/bbs: the tsbb board in ~/www/c0upons.com-bbs (TSBB_BASE_URL=https://c0upons.com/bbs).\n # The path is passed through unstripped: tsbb (>= 0.9.0) mounts itself under it.\n location ~ ^/bbs(/|$) {\n proxy_pass http://127.0.0.1:3293;\n proxy_http_version 1.1;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_set_header X-Forwarded-Host $host;\n proxy_read_timeout 300s;\n }\n", + "bbs_note": "2026-10-06: /bbs is a tsbb board in ~/www/c0upons.com-bbs (port 3293, vault c0upons-bbs--prod), not part of this repo's deploy; it follows tsbb GitHub releases", + "redis": true, + "env_overrides": { + "REDIS_URL": "redis://redis:6379" + }, + "redis_note": "2026-11-02: own redis for @profullstack/scraper-daemon (BullMQ; daily peerpush.com/deals job, c0upons PR #100)", + "redirect_to": { + "default": "https://c0upons.pwa.pit.world" + }, + "redirect_paths": { + "/bbs": "https://c0upons-bbs.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/cigarunderground.org.json b/dev2/sites.d/cigarunderground.org.json index a5f50d8..74331a7 100644 --- a/dev2/sites.d/cigarunderground.org.json +++ b/dev2/sites.d/cigarunderground.org.json @@ -1,4 +1,8 @@ { "health_path": "/healthz", - "db_sslparams": "sslmode=require" + "db_sslparams": "sslmode=require", + "redirect_to": { + "default": "https://cigarunderground.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/d1sks.com.json b/dev2/sites.d/d1sks.com.json new file mode 100644 index 0000000..7b3ce9a --- /dev/null +++ b/dev2/sites.d/d1sks.com.json @@ -0,0 +1,6 @@ +{ + "redirect_to": { + "default": "https://d1sks.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/d3vices.com.json b/dev2/sites.d/d3vices.com.json new file mode 100644 index 0000000..22dad26 --- /dev/null +++ b/dev2/sites.d/d3vices.com.json @@ -0,0 +1,6 @@ +{ + "redirect_to": { + "default": "https://d3vices.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/datamart.help.json b/dev2/sites.d/datamart.help.json index 157951b..5823e7a 100644 --- a/dev2/sites.d/datamart.help.json +++ b/dev2/sites.d/datamart.help.json @@ -26,5 +26,9 @@ "mem_limit": "512m", "mem_note": "Next.js 16 standalone on Bun (the Datamart web app), server-rendered pages over the mcp.profullstack.com API", "notes": "Not a Railway site: born on dev2 2026-10-07 as a placeholder; since 2026-10-08 the Datamart web app (Next.js on Bun, pages over the Datamart API at mcp.profullstack.com). No database, no secrets. Deploys on push to main.", - "vault": "" + "vault": "", + "redirect_to": { + "default": "https://datamart.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/getprivacycode.com.json b/dev2/sites.d/getprivacycode.com.json new file mode 100644 index 0000000..af6b024 --- /dev/null +++ b/dev2/sites.d/getprivacycode.com.json @@ -0,0 +1,6 @@ +{ + "redirect_to": { + "default": "https://getprivacycode.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/goingbroke.now.json b/dev2/sites.d/goingbroke.now.json index c6bdbd9..5723805 100644 --- a/dev2/sites.d/goingbroke.now.json +++ b/dev2/sites.d/goingbroke.now.json @@ -1,5 +1,13 @@ { "branch": "master", - "env_remove": ["TURSO_DATABASE_URL", "TURSO_AUTH_TOKEN", "DATA_DIR"], - "db_sslparams": "sslmode=require" + "env_remove": [ + "TURSO_DATABASE_URL", + "TURSO_AUTH_TOKEN", + "DATA_DIR" + ], + "db_sslparams": "sslmode=require", + "redirect_to": { + "default": "https://goingbroke.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/icemap.app.json b/dev2/sites.d/icemap.app.json index ca93013..110325b 100644 --- a/dev2/sites.d/icemap.app.json +++ b/dev2/sites.d/icemap.app.json @@ -8,9 +8,14 @@ ], "env_overrides": { "SUPABASE_SERVICE_ROLE_KEY": "secret:SUPABASE_SERVICE_ROLE_KEY", - "SUPABASE_URL": "https://supabase.icemap.app" + "SUPABASE_URL": "https://icemap-supabase.pwa.pit.world" }, "extensions": [ "postgis" - ] + ], + "redirect_to": { + "default": "https://icemap.pwa.pit.world", + "supabase.icemap.app": "https://icemap-supabase.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/media2markdown.com.json b/dev2/sites.d/media2markdown.com.json index 83ad9d6..b3b8b81 100644 --- a/dev2/sites.d/media2markdown.com.json +++ b/dev2/sites.d/media2markdown.com.json @@ -1 +1,8 @@ -{"repo": "profullstack/media2markdown", "notes": "deployed to Railway with `railway up`, so the registry saw no repo; the GitHub repo is private"} +{ + "repo": "profullstack/media2markdown", + "notes": "deployed to Railway with `railway up`, so the registry saw no repo; the GitHub repo is private", + "redirect_to": { + "default": "https://media2markdown.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/naallo.com.json b/dev2/sites.d/naallo.com.json new file mode 100644 index 0000000..c391e40 --- /dev/null +++ b/dev2/sites.d/naallo.com.json @@ -0,0 +1,6 @@ +{ + "redirect_to": { + "default": "https://naallo.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/opensocial.chat.json b/dev2/sites.d/opensocial.chat.json index 5980934..461cf37 100644 --- a/dev2/sites.d/opensocial.chat.json +++ b/dev2/sites.d/opensocial.chat.json @@ -22,5 +22,9 @@ "API_INTERNAL_ORIGIN": "http://opensocial-api:3101", "API_HOST": "0.0.0.0" }, - "health_path": "/" -} \ No newline at end of file + "health_path": "/", + "redirect_to": { + "default": "https://opensocial.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/opensourcelegends.com.json b/dev2/sites.d/opensourcelegends.com.json index b7a699a..12bccb1 100644 --- a/dev2/sites.d/opensourcelegends.com.json +++ b/dev2/sites.d/opensourcelegends.com.json @@ -1,5 +1,12 @@ { "branch": "master", - "env_remove": ["TURSO_DATABASE_URL", "TURSO_AUTH_TOKEN"], - "db_sslparams": "sslmode=require" + "env_remove": [ + "TURSO_DATABASE_URL", + "TURSO_AUTH_TOKEN" + ], + "db_sslparams": "sslmode=require", + "redirect_to": { + "default": "https://opensourcelegends.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/recipepdfs.com.json b/dev2/sites.d/recipepdfs.com.json new file mode 100644 index 0000000..8c776b1 --- /dev/null +++ b/dev2/sites.d/recipepdfs.com.json @@ -0,0 +1,6 @@ +{ + "redirect_to": { + "default": "https://recipepdfs.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/ringhuman.com.json b/dev2/sites.d/ringhuman.com.json index 6d2a6e3..119163a 100644 --- a/dev2/sites.d/ringhuman.com.json +++ b/dev2/sites.d/ringhuman.com.json @@ -1 +1,11 @@ -{ "branch": "master", "env_remove": ["TURSO_DATABASE_URL", "TURSO_AUTH_TOKEN"] } +{ + "branch": "master", + "env_remove": [ + "TURSO_DATABASE_URL", + "TURSO_AUTH_TOKEN" + ], + "redirect_to": { + "default": "https://ringhuman.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/saasrow.com.json b/dev2/sites.d/saasrow.com.json index 0fb1120..51032cb 100644 --- a/dev2/sites.d/saasrow.com.json +++ b/dev2/sites.d/saasrow.com.json @@ -19,5 +19,10 @@ }, "keep_services": [ "functions" - ] + ], + "redirect_to": { + "default": "https://saasrow.pwa.pit.world", + "supabase.saasrow.com": "https://saasrow-supabase.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/submitfleet.com.json b/dev2/sites.d/submitfleet.com.json index 458b657..0393157 100644 --- a/dev2/sites.d/submitfleet.com.json +++ b/dev2/sites.d/submitfleet.com.json @@ -30,5 +30,9 @@ "max_body": "8m", "mem_limit": "384m", "mem_note": "Node 24, Hono API + MCP + dashboard + worker in one process, SQLite file in volumes/data", - "notes": "Not a Railway site: born on dev2 2026-10-14. SubmitFleet engine (launch/directory submissions). SQLite at /data/submitfleet.db (volumes/data). SUBMITFLEET_SECRET_KEY from vault submitfleet--prod. Deploys on push to main." + "notes": "Not a Railway site: born on dev2 2026-10-14. SubmitFleet engine (launch/directory submissions). SQLite at /data/submitfleet.db (volumes/data). SUBMITFLEET_SECRET_KEY from vault submitfleet--prod. Deploys on push to main.", + "redirect_to": { + "default": "https://submitfleet.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/sysops.ceo.json b/dev2/sites.d/sysops.ceo.json index 930db9a..287aee1 100644 --- a/dev2/sites.d/sysops.ceo.json +++ b/dev2/sites.d/sysops.ceo.json @@ -25,5 +25,9 @@ "max_body": "1m", "mem_limit": "64m", "mem_note": "nginx:alpine-slim serving one static index.html", - "notes": "Not a Railway site: born on dev2 2026-10-07. Placeholder page (index.html with

sysops.ceo

) served by nginx in the container. No database, no secrets. Not a node app: skip `healthchecks`. Deploys on push to main." + "notes": "Not a Railway site: born on dev2 2026-10-07. Placeholder page (index.html with

sysops.ceo

) served by nginx in the container. No database, no secrets. Not a node app: skip `healthchecks`. Deploys on push to main.", + "redirect_to": { + "default": "https://sysops.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/tleehealth.com.json b/dev2/sites.d/tleehealth.com.json index aac1f0a..bc9a4f9 100644 --- a/dev2/sites.d/tleehealth.com.json +++ b/dev2/sites.d/tleehealth.com.json @@ -28,9 +28,13 @@ "mem_limit": "512m", "mem_note": "Bun + Hono web and API; no workers yet", "env_overrides": { - "SITE_URL": "https://tleehealth.com", + "SITE_URL": "https://tleehealth.pwa.pit.world", "NODE_ENV": "production" }, "notes": "Not a Railway site: born on dev2 2026-10-06. Telehealth + practice management. Database via db-create (migrations run on app boot). Secrets in vault tleehealth--prod. Deploys on push to master.", - "vault": "tleehealth--prod" + "vault": "tleehealth--prod", + "redirect_to": { + "default": "https://tleehealth.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/tsbb.dev.json b/dev2/sites.d/tsbb.dev.json index 79a7315..33c6433 100644 --- a/dev2/sites.d/tsbb.dev.json +++ b/dev2/sites.d/tsbb.dev.json @@ -1 +1,10 @@ -{ "env_remove": ["TSBB_DATABASE_AUTH_TOKEN"], "notes": "Turso -> shared Postgres 2026-09-25 (profullstack/tsbb#28); TSBB_DATABASE_URL is rewritten to the cluster URL by provision" } +{ + "env_remove": [ + "TSBB_DATABASE_AUTH_TOKEN" + ], + "notes": "Turso -> shared Postgres 2026-09-25 (profullstack/tsbb#28); TSBB_DATABASE_URL is rewritten to the cluster URL by provision", + "redirect_to": { + "default": "https://tsbb.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." +} diff --git a/dev2/sites.d/typeheard.com.json b/dev2/sites.d/typeheard.com.json index d14cd88..13daf1f 100644 --- a/dev2/sites.d/typeheard.com.json +++ b/dev2/sites.d/typeheard.com.json @@ -33,10 +33,14 @@ "mem_limit": "3g", "mem_note": "whisper.cpp base model ~400 MB per transcription, CONCURRENCY=2", "env_overrides": { - "SITE_URL": "https://typeheard.com", + "SITE_URL": "https://typeheard.pwa.pit.world", "DATA_DIR": "/data", "CONCURRENCY": "2", "NODE_ENV": "production" }, - "notes": "Not a Railway site: born on dev2 2026-10-06. Transcription SaaS (whisper.cpp in the image). Database via db-create; uploads wait in volumes/data until transcribed. Domain not registered yet (Porkbun credit $0), so cert/vhost/dns wait for it." + "notes": "Not a Railway site: born on dev2 2026-10-06. Transcription SaaS (whisper.cpp in the image). Database via db-create; uploads wait in volumes/data until transcribed. Domain not registered yet (Porkbun credit $0), so cert/vhost/dns wait for it.", + "redirect_to": { + "default": "https://typeheard.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." } diff --git a/dev2/sites.d/weedforcrypto.com.json b/dev2/sites.d/weedforcrypto.com.json index 7af8eb2..685ecd3 100644 --- a/dev2/sites.d/weedforcrypto.com.json +++ b/dev2/sites.d/weedforcrypto.com.json @@ -12,6 +12,11 @@ "SUPABASE_SECRET_KEY": "secret:SUPABASE_SECRET_KEY", "SUPABASE_SERVICE_ROLE_KEY": "secret:SUPABASE_SERVICE_ROLE_KEY", "SUPABASE_DB_PASSWORD": "secret:SUPABASE_DB_PASSWORD", - "NEXT_PUBLIC_SUPABASE_URL": "https://supabase.weedforcrypto.com" - } + "NEXT_PUBLIC_SUPABASE_URL": "https://weedforcrypto-supabase.pwa.pit.world" + }, + "redirect_to": { + "default": "https://weedforcrypto.pwa.pit.world", + "supabase.weedforcrypto.com": "https://weedforcrypto-supabase.pwa.pit.world" + }, + "redirect_note": "2026-11-08: domain retired; the app runs on as .pwa.pit.world (dev2/edge/edge.json). This vhost only 308s there until the domain lapses." }