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>
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:
- Build site:
npm ci && npm run build, and renders the kustomization to catch manifest errors. - Build and push image:
tea.jesseinit.dev/jesseinit/personal-site:latest. - Deploy: runs
kubectl apply -k k8s/, thenkubectl rollout restartso 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-sitenamespacedeployment.yaml: 1 replica, zero-downtime rolling updates, non-root, health checksservice.yaml: ClusterIP on port 80 → container port 3000ingress.yaml: nginx ingress + TLS forjesseinit.dev/www.jesseinit.devconfigmap.yaml: optional environment variableskustomization.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