Skip to content

Ingress and redirects ​

yaml
ingress:
  enabled: true
  hostname: wordpress.example.com
  ingressClassName: nginx
  tls: true
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod

TLS 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:

ClassServed bynginx-style annotationsUse when
nginxrke2-ingress-nginx / upstream ingress-nginxinterpreted nativelylegacy path, nginx-ingress is your only controller
nginx-traefikTraefik kubernetesIngressNGINX bridge providertranslated on the fly (proxy-body-size, whitelist-source-range, auth-url, backend-protocol, cors-*, …)transition — same kind:Ingress manifest, swap controllers without touching annotations
traefikTraefik native kubernetesIngress providersilently ignoredsteady 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):

yaml
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:

yaml
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-tls

Path preservation differs by class:

ClassResource emittedPath-preserving?Notes
nginxkind:Ingress with nginx.ingress.kubernetes.io/permanent-redirectNoAnnotation issues a static-target 308; path is dropped. https://www.example.org/foo?x=1 → https://example.com/
nginx-traefikkind: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)Yeshttps://www.example.org/foo?x=1 → https://example.com/foo?x=1
traefikidentical to nginx-traefik (the IngressRoute / Middleware shape is the same)Yessame 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. Use redirect: for the actual redirect (works on every class, supports arbitrary host lists, path-preserving on Traefik), and set ingress.tlsWwwPrefix: true separately when the primary cert should also cover the www. 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.

yaml
redirect:
  enabled: true
  targetUrl: https://example.com
  hosts:
    - www.example.com          # alias: everyone is redirected
  goneHosts:
    - forum.example.com        # retired: crawlers 410, browsers 301

A goneHosts entry behaves per client:

  • Crawlers (matched by User-Agent keywords — bot, crawl, spider, curl, python, an empty User-Agent, …) are answered 410 Gone on every path of the host, including .php paths — 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. deniedPaths still ranks first, so a honeypot path answers 418 on a retired host too.
  • Browsers get a courtesy 301 to targetUrl'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 (NGINX hostnames map 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):

bash
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.

Distributed under the Apache-2.0 license. WordPress, NGINX, Bitnami and other names are trademarks of their owners; this project is not affiliated with or endorsed by them.