Skip to content

EXP-2086: Add K8s/nginx container deployment (pattern-prover) - #75

Merged
pmckinney-codat merged 4 commits into
mainfrom
feat/k8s-deployment
Jul 30, 2026
Merged

EXP-2086: Add K8s/nginx container deployment (pattern-prover)#75
pmckinney-codat merged 4 commits into
mainfrom
feat/k8s-deployment

Conversation

@pmckinney-codat

@pmckinney-codat pmckinney-codat commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Jira

EXP-2086 (pattern-prover for EXP-2076)

What

Adds the standard containerised-frontend deployment shape so legal.codat.io can move from GitHub Pages onto a container on the Argo workload clusters. Mirrored from codat-internal/admin-ui:

  • Dockerfilenginx:1.29.6-alpine-slim final stage serving the Docusaurus build/ output. No run-app.sh: there is no runtime env injection here, nginx starts directly.
  • nginx.conf — admin-ui's config minus the SPA fallback: unknown paths return a real 404 via Docusaurus's generated 404.html (try_files $uri $uri/ =404 + error_page 404 /404.html).
  • deployment/docker/build.dockerfile on base-images/node-build:24-bookworm-slim (Node 24 matches the Pages workflow). Installs git and keeps .git in the build context so showLastUpdateAuthor/Time read real history (same reason deploy.yml uses fetch-depth: 0).
  • deployment/charts/codat.legal chart on codat-classic-app (>=2.6.1). Hosts: legal-integration.codat.io (intg) / legal.codat.io (prod). Small footprint (intg 1–2 replicas, prod 2–3, PDB 1) — traffic is minimal.
  • deployment/build.azure-pipelines.yamlHelm/build.frontend.job.yaml + Helm/deploy.job.yaml, ArgoApplicationName: legal.

GitHub Pages keeps serving prod — the Pages workflows still run on every merge. Cutover is a one-line DNS change in infrastructure-as-code once the intg hostname verifies; Pages decommission is a separate cleanup after a soak.

npm feed (decided: keep codat-npm)

Staying on the ADO feed for supply-chain control. The committed .npmrc is now credential-less (registry + always-auth, matching admin-ui/link-amex) because the old ${NPM_TOKEN} substitution lines break any npm run where the var is unset — including npm ci inside the image build. Credentials are injected at build time instead:

  • ADO pipeline: the npm authenticate step writes creds into .npmrc before the bake — the same mechanism admin-ui and link-amex rely on.
  • Pages workflows: a new "Authenticate to codat-npm feed" step writes the same three lines to ~/.npmrc from secrets.NPM_TOKEN.

Fork-PR behaviour is unchanged (no secret → npm ci fails, as before).

Still outside this PR

  • ADO pipeline registration + CustomCapabilities for this repo on the managed pool, and confirming the codat-tech service connection reaches the codatio org — tracked on EXP-2086.

Companion PRs

  • codat-internal/argocd-state#41 — Applications/legal.yaml ApplicationSet
  • codat-internal/infrastructure-as-code#1479 (staging DNS) / #1480 (held cutover)

Note on owningTeam: Pepper: the team is now Client & Customer Experience, but the full name is not a valid k8s label value (the codat-classic-app chart writes metadata.owningTeam straight into the owningTeam label). Keeping Pepper for consistency with admin-ui / connectors / admin-site until the team picks a label-safe name and renames them in one sweep.

🤖 Generated with Claude Code

Adds the standard containerised-frontend deployment shape, mirrored from
codat-internal/admin-ui:

- Dockerfile: nginx:alpine-slim final stage serving the Docusaurus build
- nginx.conf: static serving with real 404s via Docusaurus's 404.html
  (no SPA fallback), same hardening headers as admin-ui
- deployment/docker: node-build:24 build stage (git installed and .git
  kept in context so showLastUpdateAuthor/Time stay real) + docker-bake
- deployment/charts: codat.legal chart on codat-classic-app;
  legal-integration.codat.io (intg) / legal.codat.io (prod)
- deployment/build.azure-pipelines.yaml: Helm/build.frontend.job.yaml +
  Helm/deploy.job.yaml, ArgoApplicationName legal

GitHub Pages deploy stays live and untouched; cutover is a DNS-only
change in infrastructure-as-code once the intg hostname verifies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pmckinney-codat
pmckinney-codat marked this pull request as ready for review July 28, 2026 12:36
pmckinney-codat and others added 2 commits July 28, 2026 14:00
Decision: stay on the ADO codat-npm feed (supply-chain controls) rather
than switching to registry.npmjs.org.

The committed .npmrc previously carried `${NPM_TOKEN}` env-substitution
credential lines, which break any npm invocation where NPM_TOKEN is
unset — including npm ci inside the docker build stage. Match the
admin-ui/link-amex shape instead: registry + always-auth only, with
credentials injected at build time by whoever runs the build:

- ADO pipeline: npm authenticate against the feed before the bake
  (the mechanism admin-ui and link-amex already rely on)
- GH Pages workflows: new "Authenticate to codat-npm feed" step writes
  the same three credential lines to ~/.npmrc from secrets.NPM_TOKEN

Behaviour for fork PRs is unchanged: no secret, so npm ci still fails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
add_header only applies to 2xx/3xx responses by default, so the real-404
behaviour this config introduces was serving unknown paths without HSTS,
X-Frame-Options etc. `always` keeps the headers on every response.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread .npmrc Outdated
npm >=7 always sends URI-scoped credentials to the matching registry,
so the flag is a no-op for this npm-only repo and npm on Node 24 warns
it will stop working. Raised by Rachel on the PR (and previously in
Slack, Mar 2026).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pmckinney-codat
pmckinney-codat merged commit ecace4a into main Jul 30, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants