TheYard infrastructure

Pinch or Ctrl+scroll to zoom; the text is selectable. Source · TheYard

TheYard infrastructure: what runs today, how a merge becomes a roll, and the one piece of the production design still refused TheYard on Azure, as it runs on 2026-10-19 Everything in the solid boxes is live and measured, the rendering service included; the dashed group is the one piece of the production design the subscription still refuses. A request, left to right HOSTING.md and ADR-004, ADR-007 record the chain; ADR-010 the Admin tab; ADR-015 the cache rules. Visitor's browser theyard theyard-cosmos .stevenstout.biz Two sites, a store each by name. Bundles cached a year; the page, API and docs say no-cache. ADR-015, ADR-069 DNS at Wix theyard CNAME theyard-cosmos CNAME theyard-edge.netlify.app bare A, www, theshed CNAME Registrar-locked to Wix; the Cloudflare zone is staged for the transfer around Oct 30. HTTPS edge: Netlify (free) One Let's Encrypt cert, four names. _redirects, then netlify.toml bare and www: 301 to theyard a page, / with its query: to the rendering service as that site the rest: the web app, X-Yard-Host netlify.toml rebuilds only when edge/ changes ADR-007, ADR-069, ADR-096 Origin: App Service plan PLAN-THEYARD-SS, Linux B2, westus3 APP-THEYARD-ONE-SS-ZMNETJ67BN5H2 2 vCPU and 3.5 GB, shared by two web apps https://app-theyard-one-ss-zmnetj67bn5h2.azurewebsites.net Runs image theyard:vN from the registry, pulled with the user-assigned identity id-theyard-ss (AcrPull; Reader on the resource group). Inside: one ASP.NET Core 10 process (Dockerfile, ADR-002) Serves both sites by the name typed and The Shed as its own app inside it; the SPA, /api/*, the docs with live code (ADR-014), /healthz and /readyz, and the Admin tab, which trades the identity for a token and reads its site, the plan and six more resources from Azure, kept a minute at a time in Cosmos DB (ADR-101, ADR-102). Beside it: the rendering service, the second web app (render/, ADR-096) APP-THEYARD-RENDER-SS on the same plan, its own 62 MB image: Node and the site's build, no framework. For a page it reads what the view needs from the web app under a 2.5 s deadline, draws the site with React's server renderer and streams the HTML with the data in it; React takes it over. It draws only for its own build. resolve TLS HTTPS Store: Azure SQL Database, RG-THEYARD-SS, westus3 sqldb-theyard-ss-basic Basic 5 DTU 2 GB $4.90 a month The server is Entra-only: it has no SQL login and therefore no password. The site authenticates as id-theyard-ss, which holds db_datareader and db_datawriter and cannot create or alter a table. The schema is api/TheYard.Database, hand-written DDL published by SqlPackage. Entity Framework maps to it; a conformance test fails the build if they differ. West US 3 because West US 2 refused; the plan is here for the same reason. When the database is not there A container that cannot reach the store serves the catalogue from the JSON files instead and says so on /api/health. Bids stop outliving the process; nothing else changes for a visitor. Built in ADR-033 for a serverless database that auto-pauses. The first thing it actually caught was a deploy whose connection string never got substituted, and nobody using the site could tell. The deploy warns when a roll lands here (ADR-039 addendum). Store: Azure Cosmos DB, RG-THEYARD-SS, westus2 cosmos-theyard-ss free tier 1000 RU/s shared session consistency no keys Local authentication is disabled on the account, so there is no key to leak; the container authenticates as id-theyard-ss with a data-plane role that can read and write documents and cannot create a container (ADR-059, ADR-061). Four containers hold the catalogue, photos, accounts and bids as documents, partitioned on the make, the style, the account and the bidder (ADR-058). Nothing indexed; the definitions are infra/cosmos/*.json (ADR-040 addendum). Both stores and both sites in one process since 19 October A request gets the store its name picks: sql on theyard, cosmos on theyard-cosmos, both answered by this web app behind the same edge, which says which name was typed (ADR-105). The Store bar links each site to the other at the same page (no cookie); a measurement names a store for one request with a header. The peer read retired with the second web app, and the proof card sends a visitor's requests to the container itself on both stores and says, per path, whether the two answer in the same time and why they differ. ADR-066 the bar, ADR-069 the address, ADR-067 the proof, ADR-105 one web app. the other store, per request read once at startup, written on every bid pulled by id-theyard-ss az webapp config set (roll) A merge becomes a roll, no hands on it ADR-009 records the pipeline, ADR-005 the version, ADR-012 the changelog line each version writes. The gate, on the laptop Every check once a version: build, format, SQL project, xUnit on both stores, live, vitest and Playwright. Red commits nothing. ADR-068, ADR-075 GitHub: push to main The commit carries its own changelog line, one past the footer's number. SteveStout/TheYard Deploy and Deploy Render Both fire on the push: deploy.yml rolls the API's image onto the one web app; deploy-render.yml builds render/Dockerfile as the same version and rolls the service. OIDC; the version is the changelog's top line (ADR-031); each verifies its origin; the edge moves after. roles: AcrPush, Website Contributor, two web apps Registry (ACR) crtheyardsszmnetj67bn5h2 .azurecr.io One tag per version, two images: theyard and theyard-render. Basic tier. CI (ci.yml) On every push to main and on a pull request: style, then the three suites and the SQL project. Read-only token. ADR-068, the 5 October addendum green push image The one piece still refused: Azure Front Door infra/main.bicep with enableFrontDoor=true; ADR-001 the decision, ADR-004 and ADR-079 why it waits. Azure Front Door Global entry, TLS, the custom domain on Azure instead of the Netlify edge. fdProfile, fdEndpoint, fdOriginGroup, fdOrigin, fdRoute The web app, as a locked origin It answers only Azure Front Door's backend range, and only with this profile's ID in the X-Azure-FDID header (siteLock). siteLock, one per web app The same image Nothing about the sites changes. Front Door goes in front of the web app, which answers only to it, and the Netlify edge retires. Why it waits The free trial forbids Front Door (measured 2026-08-31). App Service was refused too, until 2026-09-20 found the region that allows it. One parameter. ADR-004, ADR-079 locked runs Source: docs/images/infrastructure.svg in the repository. Names, sizes and roles are the ones the records and the pipeline logs carry; the picture is redrawn when they change.