bcs-website/docs/deployment.md
Brad Rodgers cd91c4b97c Initial commit: BlueCap Strategies Astro site
Static Astro 5 site for BlueCap Strategies with exact live-site content
parity, deployed to k3s via GitOps (ArgoCD).

- Page copy in Markdown content collections (services, focus-areas, pages,
  insights) with a Zod SEO schema enforced at build time
- Homepage + About restored to exact live copy; real live-site imagery
- Build-time SEO linter (scripts/seo-lint.mjs) and Playwright e2e suite
- Multi-stage Dockerfile (nginx serves dist/) and Kustomize manifests (k8s/)
- Per-agent robots.txt; config-driven PostHog + Umami analytics scaffold
- ADRs and engineering docs under docs/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 17:40:46 -04:00

2.8 KiB

Deployment

Local Commands

npm install
npm run dev
npm run typecheck
npm run build
npm run preview

Configuration

Set these at build time:

PUBLIC_SITE_URL=https://www.bluecapstrategies.com
PUBLIC_CONTACT_FORM_ENDPOINT=https://your-form-endpoint.example

PUBLIC_CONTACT_FORM_ENDPOINT can point to Formspree, a webhook, ntfy, or a self-hosted form receiver. Without it, the contact form validates fields and opens an email draft to info@bluecapstrategies.com.

Container

docker build -t bluecap-strategies-website:latest .
docker run --rm -p 8080:80 bluecap-strategies-website:latest

k3s

Production deployment should use the pull-based GitOps model documented in docs/gitops-deployment-strategy.md.

The intended flow is:

local edit -> git push -> GitHub Actions test/build/publish -> Git manifest image tag update -> ArgoCD reconciles k3s

ArgoCD is already running in the homelab k3s cluster, so it is the reconciler (not Flux). GitHub Actions should not receive kubeconfig or direct access to the homelab cluster.

Manual kubectl use should be limited to bootstrapping the ArgoCD Application, read-only inspection, and emergency operations. If you intentionally choose to apply the current manifests by hand during a controlled bootstrap test, the command would be:

kubectl apply -k k8s/

Do not treat that as the normal production deployment process.

The manifests assume Traefik ingress is available. Read-only research confirmed Traefik and cert-manager are installed, with a ready letsencrypt-prod ClusterIssuer. However, TLS and ingress hardening should remain documented rather than applied until the Pangolin/Newt edge path is confirmed.

Items to confirm before production ingress changes:

  • Whether Pangolin/Newt terminates TLS, passes TLS through, or proxies HTTPS to Traefik.
  • Whether Pangolin/Newt preserves Host headers for the BlueCap hostnames.
  • Whether cert-manager's Cloudflare DNS-01 token can issue certificates for bluecapstrategies.com.
  • Whether the canonical production host should be apex or www.

DNS Cutover

Before cutover:

  • Build and push the final container image.
  • Confirm the GitHub Actions workflow publishes the GHCR image and updates the desired image tag.
  • Confirm ArgoCD reconciles the bluecap-strategies workload from Git.
  • Confirm the ingress or edge route answers for www.bluecapstrategies.com and bluecapstrategies.com.
  • Lower DNS TTL on the existing records.
  • Point BlueCap DNS to the existing Pangolin/Newt public edge, or to the chosen production edge if that architecture changes.
  • Configure apex-to-canonical redirect at the selected layer: Cloudflare, Pangolin/Newt, Traefik, or nginx.
  • Verify /, /services/, /about-us/, /contact/, /sitemap-index.xml, and /robots.txt after DNS propagation.