Files
Jesse EgbosionuandClaude Opus 5.5 5365bcdf82
CI and Deploy / Build site (push) Successful in 20s
CI and Deploy / Build and push image (push) Successful in 16s
CI and Deploy / Deploy to Kubernetes (push) Successful in 12s
ci: deploy :latest with rollout restart, single replica
Drop the sha-pinned overlay and automatic rollback. The deployment now
runs 1 replica with imagePullPolicy Always, and CI restarts it after
apply so the new :latest image is pulled.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 22:02:08 +02:00

1.9 KiB

Kubernetes deployment

The site runs on the personal k3s cluster in the personal-site namespace and is served at https://jesseinit.dev (www. redirects to the apex). TLS comes from cert-manager (letsencrypt-prod).

How deploys work

.github/workflows/deploy.yml (run by Gitea Actions) on every push to master:

  1. Build site: npm ci && npm run build, and renders the kustomization to catch manifest errors.
  2. Build and push image: tea.jesseinit.dev/jesseinit/personal-site:latest.
  3. Deploy: runs kubectl apply -k k8s/, then kubectl rollout restart so the pod pulls the new :latest (imagePullPolicy: Always), and waits for the rollout. There is no automatic rollback.

Pull requests run step 1 only. Old images are cleaned up by the nightly gitea-package-prune cronjob.

Required secrets (repo or production environment in Gitea)

Secret Value
REGISTRY_TOKEN Gitea token with write:package for jesseinit
KUBE_CONFIG base64-encoded kubeconfig for the personal cluster

Files

  • namespace.yaml: personal-site namespace
  • deployment.yaml: 1 replica, zero-downtime rolling updates, non-root, health checks
  • service.yaml: ClusterIP on port 80 → container port 3000
  • ingress.yaml: nginx ingress + TLS for jesseinit.dev / www.jesseinit.dev
  • configmap.yaml: optional environment variables
  • kustomization.yaml: ties it together and sets the image

Manual operations

kubectl --context personal-cluster -n personal-site get pods,ingress,certificate
kubectl --context personal-cluster -n personal-site logs -l app=jesseinit-portfolio -f
# Deploy by hand (uses :latest)
kubectl --context personal-cluster apply -k k8s/
kubectl --context personal-cluster -n personal-site rollout restart deployment/jesseinit-portfolio