Compare commits

...

3 Commits

Author SHA1 Message Date
claw fc2b0c9b53 fix(k8s): rename deployment/service/ingress to news-site
Build and Deploy / build-and-test (push) Failing after 25s
Build and Deploy / build-image (push) Has been skipped
Build and Deploy / deploy (push) Has been skipped
Align new manifest names with the live deployment so CI replaces
the existing news-site deployment instead of creating a parallel
signalledger one.

Changes:
- deployment name: signalledger -> news-site
- service name: signalledger -> news-site
- ingress name: signalledger -> news-site
- selector labels: app.kubernetes.io/name -> app: news-site
- ingress backend service: signalledger -> news-site
- ingress hosts: add news.claw.jopdorp.nl, keep signalledger.nl + www
- TLS secret: signalledger-tls -> news-site-tls (existing live secret)
- CI rollout target: deployment/signalledger -> deployment/news-site
2026-06-01 07:36:47 +00:00
claw 25545ee7ca fix(k8s): rename deployment/service/ingress to news-site
Align new manifest names with the live deployment so CI replaces
the existing news-site deployment instead of creating a parallel
signalledger one.

Changes:
- deployment name: signalledger -> news-site
- service name: signalledger -> news-site
- ingress name: signalledger -> news-site
- selector labels: app.kubernetes.io/name -> app: news-site
- ingress backend service: signalledger -> news-site
- ingress hosts: add news.claw.jopdorp.nl, keep signalledger.nl + www
- TLS secret: signalledger-tls -> news-site-tls (existing live secret)
- CI rollout target: deployment/signalledger -> deployment/news-site
2026-06-01 07:35:40 +00:00
claw 24d0ab736c fix(ingress): migrate from nginx to Traefik ingress controller
- Change ingressClassName from nginx to traefik
- Replace nginx configuration-snippet annotations with Traefik router annotations
- Extract security headers into dedicated Traefik Middleware CRD
- Update CI/CD pipeline to apply middleware manifest
- Document migration decision and deployment steps in README

ADR-002: Ingress Controller Migration (nginx → Traefik)
Migration strategy: in-place update
2026-05-31 16:25:41 +00:00
6 changed files with 102 additions and 19 deletions
+1
View File
@@ -82,6 +82,7 @@ jobs:
- name: Apply Kubernetes manifests
run: |
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/middleware.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
+59 -1
View File
@@ -1,3 +1,61 @@
# signalledger.nl
Signal Ledger news site
Signal Ledger — an independent news publication, a subsidiary of Jopdorp.
## Architecture Decision Record (ADR)
### ADR-002: Ingress Controller Migration (nginx → Traefik)
**Status:** Accepted
**Context:**
The cluster uses Traefik as its ingress controller. The initial K8s manifests were written with `ingressClassName: nginx` and nginx-specific annotations. This caused a mismatch: the Ingress resource was never picked up by any controller, leaving the site unreachable via the configured domains.
**Decision:**
Migrate all ingress configuration to Traefik-native resources.
1. **Ingress class:** Changed from `nginx` to `traefik`.
2. **Annotations:** Replaced nginx-specific `configuration-snippet` with Traefik `router.entrypoints`, `router.tls`, and `router.middlewares` annotations.
3. **Security headers:** Extracted from inline nginx snippets into a dedicated `Middleware` CRD (`k8s/middleware.yaml`). This keeps header policy declarative and reusable.
**Migration strategy:** In-place update
- The namespace `openclaw-private` already exists.
- The deployment, service, and TLS secret are unchanged.
- We apply the new Ingress and Middleware manifests; Traefik picks them up immediately.
- Rolling back is a single `kubectl apply` of the previous manifest version.
**Consequences:**
- Positive: Aligns with cluster infrastructure. No extra ingress controller needed.
- Positive: Middleware CRD is cleaner and version-controllable than inline snippets.
- Risk: Traefik middleware syntax errors will cause 404/500 until fixed. Mitigated by validating manifests in CI before deploy.
## Deployment
### Prerequisites
- Kubernetes cluster with Traefik and cert-manager installed.
- `registry.claw.jopdorp.nl` push access.
- `KUBECONFIG_BASE64` and `REGISTRY_TOKEN` secrets configured in Gitea.
### CI/CD Pipeline
Gitea Actions workflow (`.gitea/workflows/build-and-deploy.yaml`):
1. Build and test on every PR/push.
2. Build and push Docker image on merge to `main`.
3. Apply K8s manifests and wait for rollout.
### Manual Deploy
```bash
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/middleware.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
kubectl rollout status deployment/news-site -n openclaw-private --timeout=120s
```
### Domains
- `signalledger.nl`
- `www.signalledger.nl`
### Contact
- Email: signalledger@jopdorp.nl
- Owner: Signal Ledger is a subsidiary of Jopdorp.
+3 -3
View File
@@ -4,7 +4,7 @@ metadata:
name: news-site
namespace: openclaw-private
labels:
app.kubernetes.io/name: signalledger
app: news-site
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: signalledger
app.kubernetes.io/managed-by: gitea-actions
@@ -17,11 +17,11 @@ spec:
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: signalledger
app: news-site
template:
metadata:
labels:
app.kubernetes.io/name: signalledger
app: news-site
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: signalledger
spec:
+15 -13
View File
@@ -4,21 +4,33 @@ metadata:
name: news-site
namespace: openclaw-private
labels:
app.kubernetes.io/name: signalledger
app: news-site
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: signalledger
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.entrypoints: "websecure"
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.middlewares: "openclaw-private-security-headers@kubernetescrd"
spec:
ingressClassName: traefik
tls:
- hosts:
- news.claw.jopdorp.nl
- signalledger.nl
- www.signalledger.nl
secretName: signalledger-tls
secretName: news-site-tls
rules:
- host: news.claw.jopdorp.nl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: news-site
port:
number: 80
- host: signalledger.nl
http:
paths:
@@ -39,13 +51,3 @@ spec:
name: news-site
port:
number: 80
- host: news.claw.jopdorp.nl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: news-site
port:
number: 80
+22
View File
@@ -0,0 +1,22 @@
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: security-headers
namespace: openclaw-private
labels:
app: news-site
app.kubernetes.io/component: middleware
app.kubernetes.io/part-of: signalledger
spec:
headers:
customRequestHeaders:
X-Forwarded-Proto: "https"
customResponseHeaders:
Strict-Transport-Security: "max-age=31536000; includeSubDomains; preload"
X-Frame-Options: "DENY"
X-Content-Type-Options: "nosniff"
Referrer-Policy: "strict-origin-when-cross-origin"
Content-Security-Policy: "default-src 'self'; script-src 'self' 'unsafe-inline' https://pagead2.googlesyndication.com https://partner.googleadservices.com https://tpc.googlesyndication.com; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; font-src 'self'; connect-src 'self'; frame-src https://googleads.g.doubleclick.net; object-src 'none'; base-uri 'self'; form-action 'self';"
X-XSS-Protection: "1; mode=block"
Permissions-Policy: "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()"
sslRedirect: true
+2 -2
View File
@@ -4,12 +4,12 @@ metadata:
name: news-site
namespace: openclaw-private
labels:
app.kubernetes.io/name: signalledger
app: news-site
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: signalledger
spec:
selector:
app.kubernetes.io/name: signalledger
app: news-site
ports:
- port: 80
targetPort: 80