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

84 lines
2.8 KiB
Markdown

# Deployment
## Local Commands
```bash
npm install
npm run dev
npm run typecheck
npm run build
npm run preview
```
## Configuration
Set these at build time:
```bash
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
```bash
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:
```text
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:
```bash
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.