2026-10-24 21:19:22 +02:00
|
|
|
# Kubernetes deployment
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
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`).
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
## How deploys work
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
`.github/workflows/deploy.yml` (run by Gitea Actions) on every push to `master`:
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
1. **Build site**: `npm ci && npm run build`, and renders the kustomization to catch manifest errors.
|
2026-10-24 22:02:08 +02:00
|
|
|
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.
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
Pull requests run step 1 only. Old images are cleaned up by the nightly `gitea-package-prune` cronjob.
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
### Required secrets (repo or `production` environment in Gitea)
|
2025-12-24 16:37:50 +01:00
|
|
|
|
2026-10-24 21:19:22 +02:00
|
|
|
| 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
|
2026-10-24 22:02:08 +02:00
|
|
|
- `deployment.yaml`: 1 replica, zero-downtime rolling updates, non-root, health checks
|
2026-10-24 21:19:22 +02:00
|
|
|
- `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
|
2025-12-24 16:37:50 +01:00
|
|
|
|
|
|
|
|
```bash
|
2026-10-24 21:19:22 +02:00
|
|
|
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/
|
2026-10-24 22:02:08 +02:00
|
|
|
kubectl --context personal-cluster -n personal-site rollout restart deployment/jesseinit-portfolio
|
2025-12-24 16:37:50 +01:00
|
|
|
```
|