CRUMB a card from devarno-cloud

Deployment Topology, Proxy Conflict & CI after eu-1

smo1 intermediate 7 min read

ELI5

Three hosts, three jobs. Cloudflare runs the edge worker on smo1.io. Railway runs the API and its database. Vercel runs the two websites. The worker shows marketing pages by fetching them from a second address, origin.smo1.io, that does not pass back through Cloudflare, otherwise it would end up asking itself. Since 2026-10-24 most of the automated checks run once a night on GitHub’s machines instead of on every push.

Technical Deep Dive

Source: zoomies-edge wrangler.toml:1-67, .github/workflows/deploy-cloudflare.yml:1-60, .github/workflows/ci.yml:1-24 (origin/main 5bdde59); purr-api .github/workflows/nightly-gates.yml:1-40 (bb6cfc2); meow-web .github/workflows/ci.yml:1-20 (e5d808c); smo1-io docs/decisions/2026-09-02-production-api-host.md (status open, “Ratified by alex@devarno.com”), docs/decisions/2026-10-24-eu1-retire-ci-nightly-gates.md (status open, sign-off PENDING), .github/workflows/prod-health.yml:18 (1f19667); public probes 2026-10-25.

Production map

flowchart TB
U[Visitor] -->|"smo1.io/*"| Z[zoomies-edge Worker]
U -.->|"petrova.smo1.io/*, no DNS yet"| Z
Z -->|"API_URL = purr-api-production.up.railway.app"| P[purr-api on Railway]
Z -->|"LANDING_ORIGIN = origin.smo1.io"| W[whiskers-landing on Vercel]
D[Dashboard user] -->|"app.smo1.io"| M[meow-web on Vercel]
M -->|"PURR_API_URL"| P
X[API clients and x402 Gateway] -->|"purr.smo1.io, Cloudflare proxied"| P
P --> PG[(Railway Postgres)]
ProjectPlatformHostDeploys by
zoomies-edgeCloudflare Workersroutes smo1.io/*, petrova.smo1.io/*deploy-cloudflare.yml on push to main: wrangler deploy --env lion, then curls https://smo1.io/health
purr-apiRailway, project “SMO1 • IO”purr.smo1.io and purr-api-production.up.railway.appRailway git auto-deploy from main
meow-webVercelapp.smo1.ioVercel git integration
whiskers-landingVercelorigin.smo1.ioVercel git integration

Note the Worker calls the Railway hostname, not purr.smo1.io (wrangler.toml:39). The 2026-09-02 decision made purr.smo1.io the production API host after api.smo1.io was found not to resolve; on 2026-10-25 purr.smo1.io answered through Cloudflare (cf-ray), which the x402 provenance check requires (smo1-025). The Railway hostname still serves every route except the paid create.

The proxy conflict

Cloudflare routes smo1.io/* to the Worker. If the Worker fetched https://smo1.io/pricing it would be routed to itself. The landing site is therefore attached to Vercel as origin.smo1.io, a DNS-only record: on 2026-10-25 it answered server: Vercel with no cf-ray. If someone orange-clouds it, non-slug pages break.

Health checks

  • Worker: GET https://smo1.io/health returns {"status":"ok","environment":"lion",...} from the Worker itself.
  • purr-api: GET https://purr.smo1.io/health returns {"status":"ok"}; smo1-io prod-health.yml checks it daily at 06:52 UTC.

CI after eu-1

eu-1, the Hermes runner host, retires with no successor. On 2026-10-24 purr-api (#81), zoomies-edge (#26), whiskers-landing (#19), catnip-packages (#23) and smo1-io (#107) merged a change that removes push and pull_request triggers from gate CI. nightly-gates.yml runs on GitHub-hosted ubuntu-latest once a night (purr-api 02:43 UTC, zoomies-edge 02:55, smo1-io 03:13) and calls ci.yml only if main moved since the last green run. So PRs in those repos show no checks. meow-web was not part of the flip and still runs CI on push and pull request.

The governing smo1-io decision is status: open, sign-off: PENDING; its text says “the five PRs it describes are open and unmerged”, which stopped being true when they merged. Deploys were not touched: the Worker still deploys on push to main.

Key Terms

  • Proxy conflict — a Worker fetching its own routed hostname loops back into itself
  • origin.smo1.io — DNS-only Vercel attachment of whiskers-landing
  • nightly-gates.yml — once-a-night gate entry point; runs ci.yml only when main moved
  • lion — the only wrangler environment that is deployed

Q&A

Q: Which platform hosts each project in production? A: zoomies-edge on Cloudflare Workers, purr-api and its Postgres on Railway, meow-web and whiskers-landing on Vercel. catnip-packages and litter-box are not deployed.

Q: What is the proxy conflict and how is it resolved? A: The Worker owns smo1.io/*, so fetching a landing page from smo1.io would route back to the Worker. It is resolved by serving whiskers-landing on origin.smo1.io, which is DNS-only to Vercel, and setting that as LANDING_ORIGIN.

Q: What is the purpose of origin.smo1.io? A: It is the address the Worker fetches marketing pages, static assets and unknown paths from. Visitors are not meant to use it, though it is publicly reachable.

Q: Where does smo1 gate CI run since eu-1 retired, and what is the governing decision’s status? A: On GitHub-hosted runners, once a night via nightly-gates.yml, in five of the six repos; meow-web keeps per-push CI. The decision 2026-10-24-eu1-retire-ci-nightly-gates is still open with sign-off pending, even though its PRs are merged.

Examples

A contributor opens a purr-api PR and sees no checks. That is expected: run gh workflow run ci.yml --ref <branch> to gate it by hand, or wait for the 02:43 UTC nightly after merge. A zoomies-edge merge still deploys immediately, because deploy-cloudflare.yml kept its push trigger.

neighbors on the map