# phasefinal-web The Phase Final, Inc. corporate site — a single static page served by nginx on **ana-docker**, fronted by Traefik at `www.phasefinal.com`. Built from the design brief at `docs/design/` (boothed 2026-08-29); the markup and CSS came from a Claude Design session and are checked in verbatim under `conf/site/` apart from the two post-export steps below. ## Two steps every fresh export needs The design tool ships the site with **no font binaries** and the `@font-face` block **commented out**, deliberately, to honour the brief's zero-external- requests rule. Both must be undone on import: 1. Drop the four woff2 files into `conf/site/fonts/` (Space Grotesk variable, IBM Plex Sans variable, IBM Plex Mono 400 + 600 — all SIL OFL, self-hosted, no CDN). 2. Uncomment the four `@font-face` rules at the top of `conf/site/style.css`. Without these the page silently falls back to system fonts and looks wrong rather than broken, which is the failure mode you won't notice. ## Routing — and the healthcheck trap that looks like a routing bug Routers come from the compose labels: `phasefinal-web` serves `www.phasefinal.com`; `phasefinal-apex` 301s `phasefinal.com` to it. ⚠ **Traefik silently skips containers Docker reports as unhealthy.** There is no error, no log line, and no router — it looks exactly like a broken provider. The first deploy of this stack hit that: the healthcheck used `http://localhost/`, which resolves to `::1` in `nginx:alpine`, and nginx listens on IPv4 only, so the check got "Connection refused" forever and the container never left `unhealthy`. **Use `127.0.0.1`, never `localhost`, in a healthcheck for an IPv4-only listener** — and if a correctly-labelled container never appears in `/api/http/routers`, check `docker inspect --format '{{.State.Health.Status}}'` *before* suspecting Traefik. ## Deploy ```bash scripts/deploy-stack.sh ana-docker phasefinal-web ssh infra-ops@10.250.50.70 'cd /opt/docker/compose/phasefinal-web && docker compose up -d' ``` ## DNS `www.phasefinal.com` → A `38.120.12.44` (the Anaheim public IP, forwarded to ana-docker's Traefik). The apex `phasefinal.com` has **no** record — the site is www-only by operator decision. Cloudflare-proxied is the intended end state, for edge caching and the automatic email-address obfuscation the contact block relies on. ## Content constraints The copy is governed by hard legal and voice constraints — client naming rules, the never-"military"/"weapons" phrasing rule, no named individuals. **Read the design brief before editing any text.** Edits are made surgically in `conf/site/index.html`; there is no CMS and there will not be one.