Files

42 lines
1.9 KiB
Markdown
Raw Permalink Normal View History

# 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
```bash
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
```