The main Ingress is websecure-only per the forgejo pattern, so port 80 was unrouted for this host and plain http:// returned Traefik's default 404. Adds a redirectScheme Middleware plus a web-entrypoint Ingress, following the reuse-surface pattern. Pins router.priority: "1" on the redirect. cert-manager solves HTTP-01 by creating a solver Ingress on this same host and entrypoint, so a catch-all "/" redirect competes with it directly. Traefik would normally settle that by rule length, but reuse-surface's 2026-07-07 report is exactly a case of a specific rule losing to a catch-all when precedence was left implicit -- and here the symptom would not be a visible 404 but a silently failed renewal ~60 days out, surfacing as an expired certificate on the origin backing an OIDC redirect URI. Verified by probe twice: with a solver-shaped Ingress present the challenge path returns 200 (solver wins) while "/" still redirects; with it absent the redirect correctly catches both. Probe was throwaway and is not committed; the runbook carries the table to recreate it. GET returns 301 and HEAD 308. That split is Traefik's own behaviour on this cluster, not a defect here -- reuse.coulomb.social does the same. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EJbh7o7UWF4tQ5jxygnNGu Assistant: claude-code Assistant-Model: opus Assistant-Process: 2072522@bnt-lap001 Assistant-Session: 46173adf-7302-4ede-99d6-963b61359928
62 lines
2.5 KiB
YAML
62 lines
2.5 KiB
YAML
# HTTP -> HTTPS redirect for decisions.coulomb.social.
|
|
#
|
|
# manifests/informed-decision-ingress.yaml is websecure-only (forgejo pattern),
|
|
# which leaves port 80 unrouted for this host: plain http:// returned Traefik's
|
|
# default 404 rather than redirecting. This adds the redirect, following the
|
|
# reuse-surface pattern (reuse/reuse-surface-http-redirect + a redirectScheme
|
|
# Middleware).
|
|
#
|
|
# ROUTER PRIORITY IS LOAD-BEARING. cert-manager solves HTTP-01 by creating a
|
|
# temporary solver Ingress on this same host and this same `web` entrypoint,
|
|
# serving /.well-known/acme-challenge/<token>. A catch-all `/` redirect on the
|
|
# same entrypoint competes with it. Traefik would normally resolve that by rule
|
|
# length -- the solver's Path rule is far longer than PathPrefix(`/`) -- but
|
|
# reuse-surface reported on 2026-07-07 that relying on implicit precedence is
|
|
# exactly how a specific rule ends up swallowed by a catch-all, and there the
|
|
# symptom was a 404 someone noticed. Here the symptom would be a silently failed
|
|
# renewal roughly 60 days out, i.e. an expired certificate on the origin backing
|
|
# an OIDC redirect URI.
|
|
#
|
|
# So priority is pinned explicitly and low. Traefik gives the highest-priority
|
|
# matching router the request; any cert-manager solver (which uses the default
|
|
# computed priority, an order of magnitude larger) outbids this one. Verified by
|
|
# probe on 2026-09-10 -- see docs/informed-decision-origin.md.
|
|
apiVersion: traefik.io/v1alpha1
|
|
kind: Middleware
|
|
metadata:
|
|
name: informed-decision-redirect-https
|
|
namespace: informed-decision
|
|
labels:
|
|
app.kubernetes.io/name: informed-decision
|
|
app.kubernetes.io/component: redirect
|
|
spec:
|
|
redirectScheme:
|
|
scheme: https
|
|
permanent: true
|
|
---
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: informed-decision-http-redirect
|
|
namespace: informed-decision
|
|
labels:
|
|
app.kubernetes.io/name: informed-decision
|
|
app.kubernetes.io/component: redirect
|
|
annotations:
|
|
traefik.ingress.kubernetes.io/router.entrypoints: web
|
|
traefik.ingress.kubernetes.io/router.middlewares: informed-decision-informed-decision-redirect-https@kubernetescrd
|
|
# Deliberately low: ACME solver routers must win on this entrypoint.
|
|
traefik.ingress.kubernetes.io/router.priority: "1"
|
|
spec:
|
|
ingressClassName: traefik
|
|
rules:
|
|
- host: decisions.coulomb.social
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: informed-decision
|
|
port:
|
|
number: 80
|