Ingress and redirects
ingress:
enabled: true
hostname: wordpress.example.com
ingressClassName: nginx
tls: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prodTLS ends at the Ingress. The pod serves the site over HTTP on the port http: the image has no listener on port 443 and serves no certificate, and the chart renders no HTTPS port on the container, the Service or the NetworkPolicy. wordpressScheme: https sets the scheme of the URLs WordPress writes; the probes ask the pod over HTTP whatever it says.
Supported ingressClassName values
Since 7.0.0-2 the chart renders correctly under all three values relevant for the nginx → Traefik migration arc:
| Class | Served by | nginx-style annotations | Use when |
|---|---|---|---|
nginx | rke2-ingress-nginx / upstream ingress-nginx | interpreted natively | legacy path, nginx-ingress is your only controller |
nginx-traefik | Traefik kubernetesIngressNGINX bridge provider | translated on the fly (proxy-body-size, whitelist-source-range, auth-url, backend-protocol, cors-*, …) | transition — same kind:Ingress manifest, swap controllers without touching annotations |
traefik | Traefik native kubernetesIngress provider | silently ignored | steady state — manage behaviour via traefik.ingress.kubernetes.io/router.middlewares: … annotations and Middleware CRDs |
The chart itself emits no nginx.ingress.kubernetes.io/* annotations on the primary Ingress; everything in ingress.annotations and top-level commonAnnotations is the user's responsibility. Under traefik the user is expected to attach a middleware chain (e.g. body size limit, IP allowlist, forward auth) via the standard Traefik annotation rather than expecting the chart to translate.
A secondary ingress can be configured for /wp-admin with separate annotations (e.g., IP restrictions):
secondaryIngress:
enabled: true
hostname: wordpress.example.com
path: /wp-admin
annotations:
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/8"Redirects (vanity / backup domains, www variants)
The redirect: block emits a permanent redirect from a list of source hostnames to a single targetUrl. Works across all three supported IngressClasses (nginx, nginx-traefik, traefik) — the chart picks the right resource shape per class automatically (an Ingress with the permanent-redirect annotation on nginx, a Middleware + IngressRoute + optional Certificate on the Traefik variants).
Example: apex example.com is the primary site; example.org, example.net, and the www. variants of each should all redirect to https://example.com:
ingress:
enabled: true
hostname: example.com
ingressClassName: traefik # or nginx-traefik / nginx
tls: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
redirect:
enabled: true
targetUrl: https://example.com
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- example.org
- example.net
- www.example.org
- www.example.net
tls:
- hosts:
- example.org
- example.net
- www.example.org
- www.example.net
secretName: example-aliases-tlsPath preservation differs by class:
| Class | Resource emitted | Path-preserving? | Notes |
|---|---|---|---|
nginx | kind:Ingress with nginx.ingress.kubernetes.io/permanent-redirect | No | Annotation issues a static-target 308; path is dropped. https://www.example.org/foo?x=1 → https://example.com/ |
nginx-traefik | kind:Middleware (redirectRegex with capture group) + kind:IngressRoute (the IngressRoute itself sets ingressClassName: traefik regardless of the primary's class — only the chart's main Ingress goes through the bridge provider) | Yes | https://www.example.org/foo?x=1 → https://example.com/foo?x=1 |
traefik | identical to nginx-traefik (the IngressRoute / Middleware shape is the same) | Yes | same as above |
When a cert-manager cluster-issuer annotation is set on the redirect: block, the chart additionally emits a free-standing kind:Certificate for the redirect hosts (cert-manager's ingress-shim doesn't watch IngressRoute resources). The Certificate is owned only by the Helm release — independent of any Ingress lifecycle, survives chart upgrades.
Retired in 7.0.0-2: the bitnami-compatible
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"annotation is no longer honoured. Useredirect:for the actual redirect (works on every class, supports arbitrary host lists, path-preserving on Traefik), and setingress.tlsWwwPrefix: trueseparately when the primary cert should also cover thewww.variant.
Retired domains (redirect.goneHosts)
redirect.hosts is for aliases: the content lives on at targetUrl under the same path, so everyone — crawlers included — should follow a permanent redirect, and search engines consolidate onto the canonical name.
A retired domain is the opposite case: the content does not exist anywhere any more (a shut-down forum, a dropped subproject), only the hostname still resolves. Redirecting a crawler there keeps the dead URLs alive in its index and in its crawl queue indefinitely — some crawlers replay a years-old link graph and never stop. What actually ends this is a 410 Gone on every path of the host.
redirect:
enabled: true
targetUrl: https://example.com
hosts:
- www.example.com # alias: everyone is redirected
goneHosts:
- forum.example.com # retired: crawlers 410, browsers 301A goneHosts entry behaves per client:
- Crawlers (matched by User-Agent keywords —
bot,crawl,spider,curl,python, an empty User-Agent, …) are answered410 Goneon every path of the host, including.phppaths — the response is made in the rewrite phase ahead of the PHP execution allowlist, which would otherwise answer 403 for exactly the URLs a crawler keeps replaying.deniedPathsstill ranks first, so ahoneypotpath answers 418 on a retired host too. - Browsers get a courtesy
301totargetUrl's root. Deliberately not path-preserving: the old paths do not exist at the target, and a preserved path would only trade the 410 for a 403/404 there. - A hostname starting with a dot (
.old.example.com) also covers every subdomain of it (NGINXhostnamesmap semantics).
Mechanically, goneHosts are not wired to the controller-level redirect resources at all — a redirect answered at the ingress would keep NGINX from ever making the 410 call. Instead the chart routes them to the backend through the primary Ingress (so ingress.enabled is required) and renders the host list into a ConfigMap mounted at /etc/nginx/gone-hosts.d/10-chart.conf. When the primary Ingress carries a cert-manager issuer annotation, the chart adds a TLS entry (<fullname>-gone-tls) so the retired hostnames get a certificate through ingress-shim — a 410 served over a broken certificate convinces nobody.
Verifying after deployment (crawlers and browsers see different answers, so test both):
curl -s -o /dev/null -w '%{http_code}\n' -A 'Mozilla/5.0 (compatible; PetalBot)' https://forum.example.com/viewtopic.php # 410
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' -A 'Mozilla/5.0 (X11; Linux x86_64) Chrome/126.0' https://forum.example.com/anything # 301 https://example.com/Once the crawl volume has died down, delete the DNS record and remove the entry.