EDIT: I rewrote the question with a fully reproducible example.
I have a sample Django app with the base getting started https://docs.djangoproject.com/en/3.2/intro/tutorial01/, that is, there are two paths /admin
and /polls
.
If I deploy the app using NodePort, I can access both paths without issues. However, I haven't managed to do the same with Nginx ingress controller. I have tried several combinations of annotations and paths to no avail.
So, assume this yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: django
name: django
spec:
selector:
matchLabels:
app: django
template:
metadata:
labels:
app: django
spec:
containers:
- image: "ay0o/django-ingress:latest"
name: django
# ---
# apiVersion: v1
# kind: Service
# metadata:
# name: django
# spec:
# ports:
# - nodePort: 31000
# port: 8000
# targetPort: 8000
# selector:
# app: django
# type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: django
spec:
ports:
- port: 8000
selector:
app: django
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: django
spec:
rules:
- http:
paths:
- path: /django
pathType: Prefix
backend:
service:
name: django
port:
number: 8000
when I use NodePort, http://localhost:31000/admin
and http://localhost:31000/polls
work fine.
when I use Ingress, http://localhost/django
returns a 404 from django (because the path is neither admin nor polls), but http://localhost/django/admin
and http://localhost/django/polls
return a 404 from nginx, meaning the ingress is not properly routing.
so, what should I change so that http://localhost/django/admin
and http://localhost/django/polls
will not return 404?
I have come to the conclusion that it's not possible to use path-based Ingress for a Django app, probably due to something related to Django's internals.
Every example out there uses host-based rules, and indeed, that just work. For example, the Ingress above can be changed to the following, and it will work.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: django
spec:
rules:
- host: localhost
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: django
port:
number: 8000
If anyone come up with a solution using path-based routing, feel free to answer the question.