Cache rule on www.phasefinal.com with edge and browser TTL both respect_origin, so cache policy stays declared once in nginx.conf rather than split between the repo and the dashboard. Always Online enabled, which is what actually survives an origin outage; a 300s document TTL alone would only mask five minutes. Verified: document and assets both reach cf-cache-status HIT, apex 301s to www, edge email obfuscation active.
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:
- 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). - Uncomment the four
@font-facerules at the top ofconf/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
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.