How to serve static files in Django application running inside Kubernetes

8/15/2019

I have a small application built in Django. it serves as a frontend and it's being installed in one of out K8S clusters.

I'm using helm to deploy the charts and I fail to serve the static files of Django correctly.

Iv'e searched in multiple locations, but I ended up with inability to find one that will fix my problem.

That's my ingress file:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: orion-toolbelt
  namespace: {{ .Values.global.namespace }}
  annotations:
    #    ingress.kubernetes.io/secure-backends: "false"
    #    nginx.ingress.kubernetes.io/secure-backends: "false"
    ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/rewrite-target: /
    ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    ingress.kubernetes.io/ingress.allow-http: "true"
    nginx.ingress.kubernetes.io/ingress.allow-http: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: 500m
spec:
  rules:
    - http:
        paths:
          - path: /orion-toolbelt
            backend:
              serviceName: orion-toolbelt
              servicePort: {{ .Values.service.port }}

the static file location in django is kept default e.g.

STATIC_URL = "/static"

the user ended up with inability to access the static files that way..

what should I do next?

attached is the error: HTML-static_files-error -- EDIT: 5/8/19 -- The pod's deployment.yaml looks like the following:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  namespace: {{ .Values.global.namespace }}
  name: orion-toolbelt
  labels:
    app: orion-toolbelt
spec:
  replicas: 1
  selector:
    matchLabels:
      app: orion-toolbelt
  template:
    metadata:
      labels:
        app: orion-toolbelt
    spec:
      containers:
        - name: orion-toolbelt
          image: {{ .Values.global.repository.imagerepo }}/orion-toolbelt:10.4-SNAPSHOT-15
          ports:
            - containerPort: {{ .Values.service.port }}
          env:
            - name: "USERNAME"
              valueFrom:
                secretKeyRef:
                  key:  username
                  name: {{ .Values.global.secretname }}
            - name: "PASSWORD"
              valueFrom:
                secretKeyRef:
                  key:  password
                  name: {{ .Values.global.secretname }}
            - name: "MASTER_IP"
              valueFrom:
                secretKeyRef:
                  key:  master_ip
                  name: {{ .Values.global.secretname }}
          imagePullPolicy: {{ .Values.global.pullPolicy }}
      imagePullSecrets:
        - name: {{ .Values.global.secretname }}

EDIT2: 20/8/19 - adding service.yam

apiVersion: v1
kind: Service
metadata:
  namespace: {{ .Values.global.namespace }}
  name: orion-toolbelt
spec:
  selector:
    app: orion-toolbelt
  ports:
    - protocol: TCP
      port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.port }}
-- ForMartha
django
kubernetes
kubernetes-helm

2 Answers

8/16/2019

You should simply contain the /static directory within the container, and adjust the path to it in the application. Otherwise, if it must be /static, or you don't want to contain the static files in the container, or you want other containers to access the volume, you should think about mounting a Kubernetes volume to your Deployment/ Statefulset.

@Edit

You can test, whether this path exists in your kubernetes pod this way:

kubectl get po <- this command will give you the name of your pod

kubectl exec -it <name of pod> sh <-this command will let you execute commands in the container shell.

There you can test, if your path exists. If it does, it is fault of your application, if it does not, you added it wrong in the Docker.

You can also add path to your Kubernetes pod, without specifying it in the Docker container. Check this link for details

-- Marcin Ginszt
Source: StackOverflow

8/23/2019

As described by community member Marcin Ginszt

According to the informatiom applied in the post. It's difficult to quess where is the problem with your django/app config/settings.

Please refer to Managing static files (e.g. images, JavaScript, CSS)

NOTE:

Serving the files - STATIC_URL = '/static/'

In addition to these configuration steps, you’ll also need to actually serve the static files. During development, if you use django.contrib.staticfiles, this will be done automatically by runserver when DEBUG is set to True (see django.contrib.staticfiles.views.serve()). This method is grossly inefficient and probably insecure, so it is unsuitable for production.

See Deploying static files for proper strategies to serve static files in production environments.

Django doesn’t serve files itself; it leaves that job to whichever Web server you choose.

We recommend using a separate Web server – i.e., one that’s not also running Django – for serving media. Here are some good choices:

  • Nginx

  • A stripped-down version of Apache

Here you can find example how you can serve static files using collectstatic command.

Please let me know if it helped.

-- Hanx
Source: StackOverflow