diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ead4454..426c4564 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support for annotations on the PgSTAC bootstrap job via `pgstacBootstrap.jobAnnotations` in values.yaml [#381](https://github.com/developmentseed/eoapi-k8s/pull/381) +### Changed + +- Moved to traefik for the default ingress solution [#384](https://github.com/developmentseed/eoapi-k8s/pull/384) + ### Fixed - Fixed Helm template to check queryables `file` field with schema validation [#380](https://github.com/developmentseed/eoapi-k8s/pull/380) diff --git a/charts/eoapi/README.md b/charts/eoapi/README.md index f7ea9f21..7e2fe50e 100644 --- a/charts/eoapi/README.md +++ b/charts/eoapi/README.md @@ -98,7 +98,7 @@ apiServices: # Configure ingress ingress: enabled: true - className: "nginx" # or "traefik" + className: "traefik" # Or "nginx" for legacy setups host: "your-domain.com" # Optional # Database options @@ -130,7 +130,7 @@ pgstacBootstrap: | `postgresql.type` | Database deployment type | `postgrescluster` | | `postgrescluster.enabled` | Enable PostgreSQL cluster. Must be set to `false` when using external databases | `true` | | `ingress.enabled` | Enable ingress | `true` | -| `ingress.className` | Ingress controller class | `nginx` | +| `ingress.className` | Ingress controller class | `traefik` | | `browser.enabled` | Enable STAC Browser interface | `true` | | `pgstacBootstrap.enabled` | Enable database initialization | `true` | | `notifications.sources.pgstac` | Enable PostgreSQL notification triggers for STAC item changes | `false` | diff --git a/charts/eoapi/profiles/core.yaml b/charts/eoapi/profiles/core.yaml index c401ed92..5798ab29 100644 --- a/charts/eoapi/profiles/core.yaml +++ b/charts/eoapi/profiles/core.yaml @@ -167,7 +167,7 @@ observability: ###################### ingress: enabled: true - className: "nginx" + className: "traefik" pathType: "Prefix" host: "" tls: diff --git a/charts/eoapi/profiles/experimental.yaml b/charts/eoapi/profiles/experimental.yaml index 943843d5..ef68ea2d 100644 --- a/charts/eoapi/profiles/experimental.yaml +++ b/charts/eoapi/profiles/experimental.yaml @@ -358,7 +358,7 @@ autoscaling: ###################### ingress: enabled: true - className: "nginx" + className: "traefik" pathType: "Prefix" host: "localhost" tls: diff --git a/charts/eoapi/profiles/production.yaml b/charts/eoapi/profiles/production.yaml index 042ae4a6..ec5fa95a 100644 --- a/charts/eoapi/profiles/production.yaml +++ b/charts/eoapi/profiles/production.yaml @@ -343,7 +343,7 @@ knative: ###################### ingress: enabled: true - className: "nginx" + className: "traefik" pathType: "Prefix" host: "eoapi.example.com" # CHANGE THIS to your domain tls: diff --git a/charts/eoapi/templates/networking/ingress-browser.yaml b/charts/eoapi/templates/networking/ingress-browser.yaml index 35eccc23..f57f5737 100644 --- a/charts/eoapi/templates/networking/ingress-browser.yaml +++ b/charts/eoapi/templates/networking/ingress-browser.yaml @@ -13,17 +13,17 @@ metadata: labels: app: {{ .Release.Name }}-ingress-browser annotations: - {{- if .Values.ingress.annotations }} -{{ toYaml .Values.ingress.annotations | indent 4 }} - {{- end }} {{- if eq .Values.ingress.className "nginx" }} nginx.ingress.kubernetes.io/rewrite-target: /browser/$2 nginx.ingress.kubernetes.io/use-regex: "true" - {{- end }} - # Temporary annotations for Traefik until uvicorn support real prefix in ASGI: https://github.com/encode/uvicorn/discussions/2490 - {{- if eq .Values.ingress.className "traefik" }} + {{- else if eq .Values.ingress.className "traefik" }} + # Traefik with NGINX provider supports nginx annotations + nginx.ingress.kubernetes.io/rewrite-target: /browser/$2 + nginx.ingress.kubernetes.io/use-regex: "true" traefik.ingress.kubernetes.io/router.entrypoints: web - traefik.ingress.kubernetes.io/router.middlewares: {{ $.Release.Namespace }}-{{ $.Release.Name }}-strip-prefix-middleware@kubernetescrd + {{- end }} + {{- if .Values.ingress.annotations }} +{{ toYaml .Values.ingress.annotations | indent 4 }} {{- end }} spec: {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} @@ -36,8 +36,8 @@ spec: http: paths: {{- if and $.Values.browser.enabled (or (not (hasKey $.Values.browser "ingress")) $.Values.browser.ingress.enabled) }} - - pathType: {{ if eq $.Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: "/browser{{ if eq $.Values.ingress.className "nginx" }}(/|$)(.*){{ end }}" + - pathType: {{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: "/browser{{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}(/|$)(.*){{ end }}" backend: service: name: {{ .Release.Name }}-browser @@ -52,8 +52,8 @@ spec: http: paths: {{- if and .Values.browser.enabled (or (not (hasKey .Values.browser "ingress")) .Values.browser.ingress.enabled) }} - - pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: "/browser{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }}" + - pathType: {{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: "/browser{{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}(/|$)(.*){{ end }}" backend: service: name: {{ .Release.Name }}-browser diff --git a/charts/eoapi/templates/networking/ingress.yaml b/charts/eoapi/templates/networking/ingress.yaml index dc49bb70..b8ff3fdb 100644 --- a/charts/eoapi/templates/networking/ingress.yaml +++ b/charts/eoapi/templates/networking/ingress.yaml @@ -15,15 +15,15 @@ metadata: {{- if eq .Values.ingress.className "nginx" }} nginx.ingress.kubernetes.io/rewrite-target: /$2 nginx.ingress.kubernetes.io/use-regex: "true" + {{- else if eq .Values.ingress.className "traefik" }} + # Traefik with NGINX provider supports nginx annotations + nginx.ingress.kubernetes.io/rewrite-target: /$2 + nginx.ingress.kubernetes.io/use-regex: "true" + traefik.ingress.kubernetes.io/router.entrypoints: web {{- end }} {{- if .Values.ingress.annotations }} {{ toYaml .Values.ingress.annotations | indent 4 }} {{- end }} - # Temporary annotations for Traefik until uvicorn support real prefix in ASGI: https://github.com/encode/uvicorn/discussions/2490 - {{- if eq .Values.ingress.className "traefik" }} - traefik.ingress.kubernetes.io/router.entrypoints: web - traefik.ingress.kubernetes.io/router.middlewares: {{ $.Release.Namespace }}-{{ $.Release.Name }}-strip-prefix-middleware@kubernetescrd - {{- end }} spec: {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} ingressClassName: {{ .Values.ingress.className }} @@ -35,8 +35,8 @@ spec: http: paths: {{- if and $.Values.raster.enabled (or (not (hasKey $.Values.raster "ingress")) $.Values.raster.ingress.enabled) }} - - pathType: {{ if eq $.Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ $.Values.raster.ingress.path }}{{ if eq $.Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ $.Values.raster.ingress.path }}{{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ $.Release.Name }}-raster @@ -45,8 +45,8 @@ spec: {{- end }} {{- if and $.Values.stac.enabled (or (not (hasKey $.Values.stac "ingress")) $.Values.stac.ingress.enabled) }} - - pathType: {{ if eq $.Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ $.Values.stac.ingress.path }}{{ if eq $.Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ $.Values.stac.ingress.path }}{{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: {{- if index $.Values "stac-auth-proxy" "enabled" }} @@ -59,8 +59,8 @@ spec: {{- end }} {{- if and $.Values.vector.enabled (or (not (hasKey $.Values.vector "ingress")) $.Values.vector.ingress.enabled) }} - - pathType: {{ if eq $.Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ $.Values.vector.ingress.path }}{{ if eq $.Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ $.Values.vector.ingress.path }}{{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ $.Release.Name }}-vector @@ -69,8 +69,8 @@ spec: {{- end }} {{- if and $.Values.multidim.enabled (or (not (hasKey $.Values.multidim "ingress")) $.Values.multidim.ingress.enabled) }} - - pathType: {{ if eq $.Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ $.Values.multidim.ingress.path }}{{ if eq $.Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ $.Values.multidim.ingress.path }}{{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ $.Release.Name }}-multidim @@ -79,8 +79,8 @@ spec: {{- end }} {{- if and $.Values.mockOidcServer.enabled $.Values.mockOidcServer.ingress.enabled }} - - pathType: {{ if eq $.Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ $.Values.mockOidcServer.ingress.path }}{{ if eq $.Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ $.Values.mockOidcServer.ingress.path }}{{ if or (eq $.Values.ingress.className "nginx") (eq $.Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ $.Release.Name }}-mock-oidc-server @@ -105,8 +105,8 @@ spec: http: paths: {{- if and .Values.raster.enabled (or (not (hasKey .Values.raster "ingress")) .Values.raster.ingress.enabled) }} - - pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ .Values.raster.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ .Values.raster.ingress.path }}{{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ .Release.Name }}-raster @@ -115,8 +115,8 @@ spec: {{- end }} {{- if and .Values.stac.enabled (or (not (hasKey .Values.stac "ingress")) .Values.stac.ingress.enabled) }} - - pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ .Values.stac.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ .Values.stac.ingress.path }}{{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: {{- if index .Values "stac-auth-proxy" "enabled" }} @@ -129,8 +129,8 @@ spec: {{- end }} {{- if and .Values.vector.enabled (or (not (hasKey .Values.vector "ingress")) .Values.vector.ingress.enabled) }} - - pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ .Values.vector.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ .Values.vector.ingress.path }}{{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ .Release.Name }}-vector @@ -139,8 +139,8 @@ spec: {{- end }} {{- if and .Values.multidim.enabled (or (not (hasKey .Values.multidim "ingress")) .Values.multidim.ingress.enabled) }} - - pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ .Values.multidim.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ .Values.multidim.ingress.path }}{{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ .Release.Name }}-multidim @@ -149,8 +149,8 @@ spec: {{- end }} {{- if and .Values.mockOidcServer.enabled .Values.mockOidcServer.ingress.enabled }} - - pathType: {{ if eq .Values.ingress.className "nginx" }}ImplementationSpecific{{ else }}Prefix{{ end }} - path: {{ .Values.mockOidcServer.ingress.path }}{{ if eq .Values.ingress.className "nginx" }}(/|$)(.*){{ end }} + - pathType: {{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}ImplementationSpecific{{ else }}Prefix{{ end }} + path: {{ .Values.mockOidcServer.ingress.path }}{{ if or (eq .Values.ingress.className "nginx") (eq .Values.ingress.className "traefik") }}(/|$)(.*){{ end }} backend: service: name: {{ .Release.Name }}-mock-oidc-server diff --git a/charts/eoapi/values.yaml b/charts/eoapi/values.yaml index c936cc5c..e04a7339 100644 --- a/charts/eoapi/values.yaml +++ b/charts/eoapi/values.yaml @@ -32,9 +32,10 @@ service: ingress: # Unified ingress configuration for both nginx and traefik + # Traefik 3.5+ supports nginx annotations via the nginx provider enabled: true # ingressClassName: "nginx" or "traefik" - className: "nginx" + className: "traefik" rootPath: "" # Root path for doc server # Single host domain configuration (default) host: "" diff --git a/docs/argocd.md b/docs/argocd.md index 0cf662a9..0efea414 100644 --- a/docs/argocd.md +++ b/docs/argocd.md @@ -136,7 +136,7 @@ spec: # Ingress setup ingress: enabled: true - className: "nginx" + className: "traefik" host: "eoapi.example.com" destination: diff --git a/docs/autoscaling.md b/docs/autoscaling.md index 1bcf6be4..64c6f503 100644 --- a/docs/autoscaling.md +++ b/docs/autoscaling.md @@ -408,19 +408,19 @@ metadata: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing spec: - ingressClassName: nginx + ingressClassName: traefik rules: - host: your-domain.com http: paths: [...] -# For nginx ingress +# For traefik ingress apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: eoapi-ingress spec: - ingressClassName: nginx + ingressClassName: traefik rules: - host: abc5929f88f8c45c38f6cbab2faad43c-776419634.us-west-2.elb.amazonaws.com http: diff --git a/docs/configuration.md b/docs/configuration.md index a0362589..72eb7031 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -269,7 +269,7 @@ Unified ingress configuration supporting both NGINX and Traefik: | **Values Key** | **Description** | **Default** | **Choices** | |:--------------|:----------------|:------------|:------------| | `ingress.enabled` | Enable ingress | true | true/false | -| `ingress.className` | Ingress controller | "nginx" | "nginx", "traefik" | +| `ingress.className` | Ingress controller | "traefik" | "traefik", "nginx" | | `ingress.host` | Ingress hostname | "" | valid hostname | | `ingress.rootPath` | Doc server root path | "" | valid path | diff --git a/docs/unified-ingress.md b/docs/unified-ingress.md index 6a41b78e..6d4bfd48 100644 --- a/docs/unified-ingress.md +++ b/docs/unified-ingress.md @@ -1,13 +1,15 @@ --- title: "Unified Ingress Configuration" -description: "NGINX and Traefik ingress setup with TLS and cert-manager integration" +description: "Traefik ingress setup with NGINX compatibility, TLS and cert-manager integration" external_links: - name: "eoapi-k8s Repository" url: "https://github.com/developmentseed/eoapi-k8s" - - name: "NGINX Ingress Controller" - url: "https://kubernetes.github.io/ingress-nginx/" - name: "Traefik Documentation" url: "https://doc.traefik.io/traefik/" + - name: "Traefik NGINX Provider" + url: "https://doc.traefik.io/traefik/routing/providers/kubernetes-ingress-nginx/" + - name: "NGINX Ingress Controller" + url: "https://kubernetes.github.io/ingress-nginx/" - name: "cert-manager" url: "https://cert-manager.io/" --- @@ -18,23 +20,26 @@ This document describes the unified ingress approach implemented in the eoAPI He ## Overview -eoAPI includes a streamlined ingress configuration with smart defaults for different controllers. This approach: +eoAPI defaults to **Traefik** as the ingress controller, leveraging Traefik's NGINX provider for seamless compatibility with NGINX ingress annotations. This approach: +- Uses Traefik 3.5+ with NGINX provider support for zero-drama migration from ingress-nginx +- Maintains compatibility with existing NGINX ingress annotations - Eliminates manual pathType and suffix configurations -- Uses controller-specific optimizations for NGINX and Traefik - Provides separate configuration for STAC browser -- Maintains backward compatibility while improving usability +- Maintains backward compatibility with NGINX ingress controller ## Configuration -The ingress configuration has been simplified in the `values.yaml` file: +The ingress configuration defaults to Traefik with NGINX provider support: ```yaml ingress: # Unified ingress configuration for both nginx and traefik + # Traefik 3.5+ supports nginx annotations via the nginx provider + # Set --experimental.kubernetesIngressNGINX and --providers.kubernetesIngressNGINX when deploying Traefik enabled: true - # ingressClassName: "nginx" or "traefik" - className: "nginx" + # ingressClassName: "traefik" (default) or "nginx" + className: "traefik" # Root path for doc server rootPath: "" # Host configuration @@ -47,44 +52,64 @@ ingress: secretName: eoapi-tls ``` +## Deploying Traefik with NGINX Provider + +To use Traefik as a drop-in replacement for ingress-nginx, deploy Traefik with the NGINX provider enabled: + +```bash +helm repo add traefik https://traefik.github.io/charts +helm repo update + +helm upgrade --install traefik traefik/traefik \ + --namespace traefik \ + --create-namespace \ + --version ~v37.3.0 \ + --set providers.kubernetesGateway.enabled=true \ + --set 'additionalArguments[0]=--providers.kubernetesIngressNGINX' \ + --set 'additionalArguments[1]=--experimental.kubernetesIngressNGINX=true' \ + --wait +``` + +This enables Traefik to understand and process NGINX ingress annotations, allowing you to migrate from ingress-nginx with minimal changes. + ## Controller-Specific Behavior -### NGINX Ingress Controller +### Traefik Ingress Controller (Default) -For NGINX, the system automatically: -- Uses `ImplementationSpecific` pathType -- Adds regex-based path matching -- Sets up proper rewrite rules +Traefik is now the default ingress controller. When using Traefik with the NGINX provider: +- Uses `ImplementationSpecific` pathType (same as NGINX) +- Supports NGINX ingress annotations natively +- Handles regex-based path matching via NGINX annotations +- Automatically processes rewrite rules from NGINX annotations + +The eoAPI chart automatically applies NGINX annotations when using Traefik, which are understood by Traefik's NGINX provider: -Basic NGINX configuration: ```yaml ingress: enabled: true - className: "nginx" + className: "traefik" # Default + host: "example.domain.com" annotations: - # Additional custom annotations if needed + # NGINX annotations work with Traefik's NGINX provider nginx.ingress.kubernetes.io/enable-cors: "true" nginx.ingress.kubernetes.io/enable-access-log: "true" ``` -### Traefik Ingress Controller +### NGINX Ingress Controller (Legacy) -For Traefik, the system: -- Uses `Prefix` pathType by default -- Automatically configures strip-prefix middleware -- Handles path-based routing appropriately +For backward compatibility, NGINX ingress controller is still supported: -Basic Traefik configuration: ```yaml ingress: enabled: true - className: "traefik" - # When using TLS, setting host is required - host: "example.domain.com" + className: "nginx" annotations: - traefik.ingress.kubernetes.io/router.entrypoints: web + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/enable-access-log: "true" ``` +**Note:** With ingress-nginx entering maintenance mode (EoL March 2026), migrating to Traefik is recommended. + ## STAC Browser Configuration The STAC browser now uses a separate ingress configuration to handle its unique requirements: @@ -131,7 +156,7 @@ spec: solvers: - http01: ingress: - class: nginx # or traefik, depending on your setup + class: traefik # or nginx for legacy setups ``` 3. After testing with staging, create the production issuer: @@ -149,14 +174,14 @@ spec: solvers: - http01: ingress: - class: nginx # or traefik, depending on your setup + class: traefik # or nginx for legacy setups ``` 4. Configure your eoAPI ingress to use cert-manager: ```yaml ingress: enabled: true - className: "nginx" # or "traefik" + className: "traefik" # Default, or "nginx" for legacy setups host: "eoapi.example.com" annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" @@ -165,14 +190,44 @@ ingress: secretName: eoapi-tls # cert-manager will create this secret ``` -## Migration from 0.7.0 +## Migration from ingress-nginx to Traefik + +### Why Migrate? + +With ingress-nginx entering maintenance mode (EoL March 2026), migrating to Traefik provides: +- **Security**: Traefik's secure-by-design architecture eliminates template injection vulnerabilities +- **Future-proof**: Gateway API leadership and modern cloud-native design +- **Zero-drama migration**: NGINX provider allows using existing annotations without changes +- **Production-ready**: Battle-tested at scale with 3.4+ billion downloads + +### Migration Steps + +1. **Deploy Traefik with NGINX provider** (see [Deploying Traefik](#deploying-traefik-with-nginx-provider) above) + +2. **Update your values.yaml**: + ```yaml + ingress: + className: "traefik" # Changed from "nginx" + ``` + +3. **No annotation changes needed**: Your existing NGINX annotations will work with Traefik's NGINX provider + +4. **Verify the migration**: + ```bash + kubectl get ingress + kubectl get pods -n traefik + ``` + +5. **Test your endpoints** to ensure everything works as expected + +### Migration from 0.7.0 If you're upgrading from version 0.7.0: 1. Remove any `pathType` and `pathSuffix` configurations from your values 2. The system will automatically use the appropriate settings for your chosen controller -3. For NGINX users, regex path matching is now enabled by default -4. For Traefik users, strip-prefix middleware is automatically configured +3. NGINX annotations work with both NGINX and Traefik (via NGINX provider) +4. Regex path matching is enabled by default for both controllers ## Path Structure diff --git a/scripts/deployment.sh b/scripts/deployment.sh index d9e769a2..1310bd00 100755 --- a/scripts/deployment.sh +++ b/scripts/deployment.sh @@ -115,6 +115,13 @@ EOF testing_mode=true fi + # Allow overriding ingress className via environment variable (optional, for special cases) + # Default is traefik, which works with Traefik's NGINX provider + if [[ -n "${INGRESS_CLASS_NAME:-}" ]]; then + log_info "Overriding ingress className to: ${INGRESS_CLASS_NAME}" + helm_cmd="$helm_cmd --set ingress.className=${INGRESS_CLASS_NAME}" + fi + helm_cmd="$helm_cmd --timeout $TIMEOUT" log_info "Deploying eoAPI..."