How to convert this Nginx config to Kubernetes Nginx Ingress?
I have a django application which is served as wsgi with gunicorn
.
gunicorn --workers=4 --bind :8000 backend.wsgi
In my local development environment I used docker-compose
to setup an Nginx reverse-proxy in front of it to serve static files, like the following (I've omitted env files and other irrelevant stuff). I'm setting DJANGO_ROOT_URL
to use a custom path (e.g. "/be/") in front of the requests. The WORKDIR
for every Django files is /backend
on the Docker container and collecting the static files during build time they're placed as expected inside /backend/static
.
backend:
image: backend-image
volumes:
- ./data/backend/static:/backend/static
ports:
- "9999:8000"
environment:
- DJANGO_ROOT_URL=/be/
nginx:
image: nginx
volumes:
- ./django/nginx.conf:/etc/nginx/templates/default.conf.template
- ./data/backend/static:/static
ports:
- "8000:80"
environment:
- DJANGO_ROOT_URL=/be/
# To show Nginx logs
- ACCESS_LOG=${ACCESS_LOG:-off}
depends_on:
- backend
And this is the configuration:
upstream django {
server backend:8000;
}
server {
listen 80;
# Max upload size
client_max_body_size 100M;
# Suppress log (on/off)
access_log ${ACCESS_LOG};
location ${DJANGO_ROOT_URL} {
rewrite ${DJANGO_ROOT_URL}(.*) /$1 break;
proxy_pass http://django;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host; # to add port to DRF resources and allow CSRF
proxy_set_header Connection "";
}
location ${DJANGO_ROOT_URL}static {
rewrite ${DJANGO_ROOT_URL}(.*) /$1 break;
root /;
}
}
This works as expected, when going for instance to http://localhost:8000/be/admin I see that the static files are correctly served.
Now, I need to put this together on a Kubernetes environment. Since I've already set up the Nginx Ingress Controller, I thought it would be unnecessary to put another nginx instance inside the pod since I can use directly an Ingress resource. This is my k8s script which should deploy the Django app:
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-config
data:
DJANGO_ROOT_URL: "/be/"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
labels:
app: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
serviceAccountName: cluster-manager
containers:
- name: backend
image: backend-test
imagePullPolicy: "Always"
envFrom:
- configMapRef:
name: backend-config
---
apiVersion: v1
kind: Service
metadata:
name: backend
labels:
app: backend
spec:
type: LoadBalancer
ports:
- name: http
port: 8000
protocol: TCP
targetPort: 8000
selector:
app: backend
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: backend
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/app-root: /backend
spec:
tls:
- hosts:
- backend.192.168.49.2.nip.io
rules:
- host: backend.192.168.49.2.nip.io
http:
paths:
- path: /be(/|$)(.*)
pathType: Prefix
backend:
service:
name: backend
port:
number: 8000
- path: /be/static(/|$)(.*)
pathType: Prefix
backend:
service:
name: backend
port:
number: 8000
This works but static files are not served at all and cannot be found. Is there a better/correct way to convert the docker-compose
setup on Kubernetes?