Moves the production deploy from AWS to the Frostmoln production cluster (namespace `sites`).
- `deploy-prod` (AWS) has failed since CI left AWS: the runners have no `k8s.unbound.se` context, so the site on AWS still runs an older image. It's replaced by `deploy-prod-frostmoln`, the same pattern as Shiny's `deploy-frostmoln-staging`: `FROSTMOLN_PRODUCTION_DEPLOY_KEY` + `FROSTMOLN_PRODUCTION_CLUSTER_ID` (org), `BUILDTOOLS_FROSTMOLN_PRODUCTION` (org, target `prod-frostmoln`), `deploy prod-frostmoln -n sites`.
- Frostmoln enforces restricted Pod Security: the served image is `nginxinc/nginx-unprivileged` (uid 101, port 8080), with a matching securityContext; the Service is ClusterIP.
- `ingress-prod.yaml` (ALB) → `ingress-prod-frostmoln.yaml` (Traefik, Let's Encrypt).
Checked locally: the image serves `/health` and `/` (200) as uid 101 with all capabilities dropped.
**Merge after** infra's `feat/frostmoln-production-sites` is applied (namespace + org secret). The hostnames keep pointing at AWS until the Route 53 switch, a separate step; the certificate is issued after that.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Ma8eHhW59hLAJuLzBnLvUu
Reviewed-on: #86
## Summary
`k8s/deploy.yaml` takes the image from build-tools: `image: ${IMAGE}` instead of the hard-coded `oci.unbound.se/unboundsoftware/lingonpaj-site:${COMMIT}`.
`deploy` substitutes `${IMAGE}` with `<registry>/<owner>/<name>:<tag>`, where the registry comes from the build-tools config and the tag is the value `${COMMIT}` gets today. The rendered reference is unchanged. Moving off `oci.unbound.se` later becomes one change in infra.
Validated on shiny/time-service#864: merged and deployed to AWS staging and Frostmoln staging with the same image. Prerequisites, all merged:
- unboundsoftware/infra#1808: registry in `BUILDTOOLS_FROSTMOLN_STAGING`
- shiny/acctest#952: acctest pins build-tools to the Gitea registry
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed-on: https://gitea.unbound.se/unboundsoftware/lingonpaj-site/pulls/84
Remove cpu from resource limits while keeping memory limits and all
requests intact. CPU limits cause unnecessary throttling and
overcommit alerts when actual usage is far below limits.
Refactor Kubernetes deployment and service labels to follow
the recommended label format. Change all occurrences of
"app: lingonpaj-site" to "app.kubernetes.io/name: lingonpaj-site"
for improved consistency and compliance with Kubernetes best
practices.
Reduce CPU and memory requests from 10m to 5m and from 10Mi to 5Mi to
optimize resource usage for the application deployment. This change
aims to improve overall efficiency without compromising performance.