Search code examples
djangohttphttp-redirectkubernetes-ingress

Ingress routing misses prefix for django redirects


I deployed a Django app in a K8s cluster and have some issues with the routing by Ingress.

Ingress config:

apiVersion: projectcontour.io/v1
kind: HTTPProxy
metadata:
  name: main
  namespace: ${namespace}
spec:
  routes:
    - conditions:
        - prefix: /my-app
      services:
        - name: my-app-backend
          port: 80
      timeoutPolicy:
        response: 60s
  pathRewritePolicy:
    replacePrefix:
      - replacement: /

my-app/urls.py

from django.urls import include, path
from overview import views

app_name = "overview"

urlpatterns = [
    path("", views.index),
    path("overview", views.overview)
    ...
]

I have a url like example.com where the paths are redirected to several K8s services.

URL example.com/my-app/ should be resolved to my service my-app. So far so good, I can see the entry page of my app.

But if I start clicking buttons from here, the relative redirects done by Django are not working as expected:

A Button click which is expected to navigate me to example.com/my-app/overview, targets to example.com/overview which results in 404 obviously.

I would expect a /my-app/ prefix for all redirects in my-app. I'm an Ingress rookie, but I would assume that my-app shouldn't be responsible for this information, as I would have to change two repos when the domain path changes eventually (and I want to avoid routers or hardcoding the url prefixed to /my-app/).

Can I achieve this expected behavior with Ingress, or whats the best practice here?


Solution

  • I'm an Ingress rookie, but i would assume that my-app shouldn't be responsible for this information, as I would have to change two repos when the domain path changes eventually (and i want to avoid routers or hardcoding the url prefixed to /my-app/).

    This is not an application task. You rightly said that it should be taken care of by ingress. Your ingress is not configured properly. First look at the official documentation:

    If a prefix field is present, the replacement is applied only to routes that have an exactly matching prefix condition

    In a situation where you want to open example.com/my-app/overview , you are redirected to example.com/overview, because my-app was replaced by /. It looks like you don't need to change the paths at all.

    But if you want to change your yaml a bit, take the following as an example and adapt it to your needs by providing the appropriate prefixes and replacements.

    apiVersion: projectcontour.io/v1
    kind: HTTPProxy
    metadata:
      name: rewrite-example
      namespace: default
    spec:
      virtualhost:
        fqdn: rewrite.bar.com
      routes:
      - services:
        - name: s1
          port: 80
        conditions:
        - prefix: /v1/api
        pathRewritePolicy:
          replacePrefix:
          - prefix: /v1/api
            replacement: /app/api/v1
          - prefix: /
            replacement: /app
    

    If no prefix field is present, the replacement is applied to all prefix matches made against the route. If a prefix field is present, the replacement is applied only to routes that have an exactly matching prefix condition. Specifying more than one replacePrefix entry is mainly useful when a HTTPProxy document is included into multiple parent documents.