All checks were successful
CI / ci (push) Successful in 1m56s
- ADR-0008: private package, External-Secrets pull over public HTTPS (no k3s restart); CI auth via CI_TOKEN PAT; Playwright dropped from CI. Marks ADR-0007 partially superseded. - gitops-deployment-strategy + deployment.md updated to as-built flow + operate/troubleshoot runbook - content-deviations: detail-page heroes are text-only (no image) - service/focus detail pages: clean text hero (drop shared photo/icon)
4.0 KiB
4.0 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 (as-built — deployed & serving in-cluster since 2026-07-17)
Live GitOps flow (all working; see docs/gitops-deployment-strategy.md + ADR-0001/0007/0008):
local edit -> git push (Gitea main) -> Gitea Actions: build + seo:lint -> push image (internal
10.66.15.22:3000) -> bump DEPLOY_IMAGE tag + commit back [skip ci] -> ArgoCD reconciles k3s ->
k3s pulls git.7tl-homelab.com/... (private, ES pull secret, public HTTPS) -> pods serve
- ArgoCD is the reconciler (not Flux); the CI runner never gets kubeconfig or cluster access.
- Not yet public — the ingress names
bluecapstrategies.com/wwwbut DNS still points at the old WordPress site. Going public = the DNS Cutover below, a deliberate step. See thekeep-old-site-liverule: do nothing that affects the old site until cutover.
Operate
# Review the running site locally (no cluster/DNS impact):
kubectl -n bluecap-strategies port-forward svc/bluecap-website 18080:80 # then http://localhost:18080
# or purely off-cluster from source: npm run dev
# Health / status:
kubectl -n argocd get application bcs-website # Synced / Healthy
kubectl -n bluecap-strategies get pods,deploy # 2/2 Running
kubectl -n bluecap-strategies get externalsecret gitea-registry # SecretSynced
# Rollback: `git revert` the tag-bump commit and push (ArgoCD reconciles), or use ArgoCD history.
Troubleshoot (things that actually bit us)
- CI job never runs / "no matching runner" → runner offline or mis-scoped. Must be a global
(owner_id=0) runner on
gitea_networkwith instance URLhttp://gitea:3000; token must be an instance-level registration token (Site Admin → Actions → Runners). - Push: "server gave HTTP response to HTTPS client" → runner host dockerd missing
insecure-registries: ["10.66.15.22:3000"](gitea Ansible role handles it). - Push:
unauthorized→CI_TOKENrepo secret missing/insufficient (write:package+write:repository). - Pod
ImagePullBackOff→ ExternalSecret not synced (check OpenBaocluster/bluecap-registryfields) or theread:packagePAT. git pushrejected (fetch first) → CI committed a tag bump tomain;git pull --rebasefirst (git config pull.rebase true).
Manual kubectl apply -k k8s/ is for emergency/bootstrap only, not normal deploys.
Ingress/TLS items to confirm before cutover: whether Pangolin/Newt terminates/passes/proxies TLS
to Traefik and preserves Host headers; whether cert-manager's Cloudflare DNS-01 token can issue
for bluecapstrategies.com; whether the canonical host is 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-strategiesworkload from Git. - Confirm the ingress or edge route answers for
www.bluecapstrategies.comandbluecapstrategies.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.txtafter DNS propagation.