Compare commits

...

7 Commits

Author SHA1 Message Date
renovate 4f0115148d chore(deps): update cloudamqp/lavinmq docker tag to v2.7.0 (#260) 2026-04-19 11:07:49 +00:00
argoyle 73ccafab68 fix(postgres): remove memory limit and add document database (#259)
## Summary

- Remove the 600Mi memory limit on the local Postgres Deployment. With `shared_buffers=384MB` + `max_connections=300` the pod was being repeatedly OOMKilled under real workloads, leaving clients with intermittent `connect: connection refused`. Keep the 400Mi request for scheduling.
- Add `document` to the seeded database list in `initdb.sh`.

## Test plan

- [x] `kubectl --context kind-unbound apply -f k8s/infra/postgres.yaml` — rollout succeeds
- [x] Postgres pod stable (0 restarts) after apply
- [ ] On a fresh cluster (`./setup`), verify the `document` database is created (requires empty `data/postgres/`)

Reviewed-on: #259
2026-04-18 16:34:17 +00:00
renovate b6918819aa chore(deps): update cloudamqp/lavinmq docker tag to v2.6.11 (#258) 2026-04-18 13:06:24 +00:00
renovate eb3ca05bfb chore(deps): update postgres:18.3-alpine docker digest to 5209801 (#257) 2026-04-16 16:11:16 +00:00
renovate bf2332e1ac chore(deps): update postgres:18.3-alpine docker digest to c48f944 (#256) 2026-04-16 02:07:49 +00:00
renovate 8ed20f7e58 chore(deps): update postgres:18.3-alpine docker digest to b73cfac (#255) 2026-04-16 00:06:36 +00:00
argoyle a62ee9efb1 refactor: migrate from ingress-nginx to Traefik v3 (#254)
## Summary

- Replace ingress-nginx 4.15.1 with Traefik v3 (Helm chart 39.0.7) as ingress controller
- Convert nginx-specific annotations to Traefik Middleware CRDs
- Update setup script selectors, namespaces, and readiness checks
- Add `.claude/settings.local.json` to `.gitignore`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #254
2026-04-15 13:05:43 +00:00
9 changed files with 79 additions and 26 deletions
+1
View File
@@ -1,2 +1,3 @@
data
charts
.claude/settings.local.json
+22 -4
View File
@@ -24,9 +24,9 @@ kind: Ingress
metadata:
name: frontend
annotations:
nginx.ingress.kubernetes.io/upstream-vhost: "localhost:3300"
traefik.ingress.kubernetes.io/router.middlewares: default-frontend-host@kubernetescrd
spec:
ingressClassName: nginx
ingressClassName: traefik
tls:
- hosts:
- staging-shiny.unbound.se
@@ -59,9 +59,9 @@ kind: Ingress
metadata:
name: api
annotations:
nginx.ingress.kubernetes.io/upstream-vhost: "localhost:4444"
traefik.ingress.kubernetes.io/router.middlewares: default-api-host@kubernetescrd
spec:
ingressClassName: nginx
ingressClassName: traefik
tls:
- hosts:
- staging-shiny-api.unbound.se
@@ -77,3 +77,21 @@ spec:
name: api-external
port:
number: 4444
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: frontend-host
spec:
headers:
customRequestHeaders:
Host: "localhost:3300"
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: api-host
spec:
headers:
customRequestHeaders:
Host: "localhost:4444"
+1 -1
View File
@@ -28,7 +28,7 @@ spec:
app.kubernetes.io/name: lavinmq
spec:
containers:
- image: cloudamqp/lavinmq:2.6.10@sha256:e52866d61141b3bb61a3ae99acd7fac1c750ba86af50037864f9498c27fbd89a
- image: cloudamqp/lavinmq:2.7.0@sha256:521d49d60819a739f9323db47accb248502fca7bf79c9e0539e7b23a12e1413d
imagePullPolicy: Always
livenessProbe:
tcpSocket:
+2 -3
View File
@@ -23,6 +23,7 @@ data:
CREATE DATABASE authz WITH OWNER postgres ENCODING utf8;
CREATE DATABASE company WITH OWNER postgres ENCODING utf8;
CREATE DATABASE consumer WITH OWNER postgres ENCODING utf8;
CREATE DATABASE document WITH OWNER postgres ENCODING utf8;
CREATE DATABASE employee WITH OWNER postgres ENCODING utf8;
CREATE DATABASE invoice WITH OWNER postgres ENCODING utf8;
CREATE DATABASE notification WITH OWNER postgres ENCODING utf8;
@@ -52,7 +53,7 @@ spec:
spec:
containers:
- name: postgres
image: postgres:18.3-alpine@sha256:4da1a4828be12604092fa55311276f08f9224a74a62dcb4708bd7439e2a03911
image: postgres:18.3-alpine@sha256:52098013b4b64a746626437d38afc03cabff6cdeb4d3d92e2342aa95f0ce56ea
args:
- -c
- shared_buffers=384MB
@@ -62,8 +63,6 @@ spec:
resources:
requests:
memory: 400Mi
limits:
memory: 600Mi
ports:
- containerPort: 5432
env:
-12
View File
@@ -1,12 +0,0 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespaces.yaml
helmCharts:
- name: ingress-nginx
namespace: ingress-nginx
includeCRDs: true
releaseName: ingress-nginx
repo: https://kubernetes.github.io/ingress-nginx
version: 4.15.1
valuesFile: https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/hack/manifest-templates/provider/kind/values.yaml
+12
View File
@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespaces.yaml
helmCharts:
- name: traefik
namespace: traefik
includeCRDs: true
releaseName: traefik
repo: https://traefik.github.io/charts
version: 39.0.7
valuesFile: values.yaml
+4
View File
@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: traefik
+31
View File
@@ -0,0 +1,31 @@
deployment:
kind: DaemonSet
ports:
web:
hostPort: 80
websecure:
hostPort: 443
tolerations:
- key: "node-role.kubernetes.io/master"
operator: "Equal"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/control-plane"
operator: "Equal"
effect: "NoSchedule"
nodeSelector:
ingress-ready: "true"
providers:
kubernetesIngress:
publishedService:
enabled: false
service:
type: ClusterIP
ingressClass:
enabled: true
isDefaultClass: true
+6 -6
View File
@@ -12,20 +12,20 @@ kubectl create secret docker-registry gitlab \
kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": "gitlab"}]}'
kustomized="$(mktemp -t unboundnginx.yaml.XXXXXX)"
kustomized="$(mktemp -t unboundtraefik.yaml.XXXXXX)"
kubectl kustomize --enable-helm "k8s/nginx" >> "${kustomized}"
kubectl kustomize --enable-helm "k8s/traefik" >> "${kustomized}"
kubectl apply -f "${kustomized}" --server-side || true
printf "\nWait for pod app.kubernetes.io/component=controller to be created."
printf "\nWait for pod app.kubernetes.io/name=traefik to be created."
while :; do
sleep 2
[ -n "$(kubectl -n ingress-nginx get pod --selector=app.kubernetes.io/component=controller 2>/dev/null)" ] && printf "\n\n" && break
[ -n "$(kubectl -n traefik get pod --selector=app.kubernetes.io/name=traefik 2>/dev/null)" ] && printf "\n\n" && break
printf "."
done
echo "Wait for nginx to be available."
until [[ $(kubectl -n ingress-nginx get endpointslices -l 'kubernetes.io/service-name=ingress-nginx-controller' -o=jsonpath='{.items[*].endpoints[*].addresses[*]}') ]]; do sleep 5; done
echo "Wait for traefik to be available."
until [[ $(kubectl -n traefik get endpointslices -l 'kubernetes.io/service-name=traefik' -o=jsonpath='{.items[*].endpoints[*].addresses[*]}') ]]; do sleep 5; done
kustomized="$(mktemp -t unboundinfra.yaml.XXXXXX)"