简体   繁体   中英

How to serve the static content in nginx + django + kubernetes?

I have a minikube running with the deployment of django app. Till today, we used server which django spins up. Now, I have added another Nginx container so that we can deploy django app cause I read django is not really for production. After reading some documentation and blogs, I configured the deployment.yaml file and it is running very much fine now. The problem is that no static content is being served. This is really because static content is in django container and not Nginx container. (Idk if they can share volume or not, please clarify this doubt or misconception) What will be the best way so I can serve my static content? This is my deployment file's spec:

spec:
            containers:
                - name: user-django-app
                  image: my-django-app:latest
                  ports:
                    - containerPort: 8000
                  env:
                    - name: POSTGRES_HOST
                      value: mysql-service
                    - name: POSTGRES_USER
                      value: admin
                    - name: POSTGRES_PASSWORD
                      value: admin
                    - name: POSTGRES_PORT
                      value: "8001"
                    - name: POSTGRES_DB
                      value: userdb
                - name: user-nginx
                  image: nginx
                  volumeMounts:
                    - name: nginx-config
                      mountPath: /etc/nginx/nginx.conf 
                      subPath: nginx.conf
            volumes:
              - name: nginx-config
                configMap:
                  name: nginx-config

I believe that

server {
    location /static {
        alias /var/www/djangoapp/static;
    }
}

needs to be changed. But I don't know what should I write? Also, how can I run python manage.py migrate and python manage.py collectstatic as soon as the deployment is made.

Kindly provide resource/docs/blogs which will assist me doing this. Thank you. Thank you.

After @willrof 's answer, this is my current YAML file.

apiVersion: apps/v1
kind: Deployment
metadata:
    name: user-deployment
    labels: 
        app: web
spec:
    replicas: 1
    selector:
        matchLabels:
            app: web
            micro-service: user
    template:
        metadata:
            name: user
            labels:
                app: web
                micro-service: user
        spec:
            containers:
                - name: user-django-app
                  image: docker.io/dev1911/drone_plus_plus_user:latest
                  ports:
                    - containerPort: 8000
                  env:
                    - name: POSTGRES_HOST
                      value: mysql-service
                    - name: POSTGRES_USER
                      value: admin
                    - name: POSTGRES_PASSWORD
                      value: admin
                    - name: POSTGRES_PORT
                      value: "8001"
                    - name: POSTGRES_DB
                      value: userdb
                  volumeMounts:
                    - name: shared
                      mountPath: /shared
                  command: ["/bin/sh", "-c"]
                  args: ["apt-get install nano"]
                - name: user-nginx
                  image: nginx
                  volumeMounts:
                    - name: nginx-config
                      mountPath: /etc/nginx/nginx.conf 
                      subPath: nginx.conf
                    - name: shared
                      mountPath: /var/www/user/static
            volumes:
              - name: nginx-config
                configMap:
                  name: nginx-config
              - name: shared
                emptyDir: {}

And nginx-config file is

worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
  worker_connections  4096;  ## Default: 1024
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format ltsv 'domain:$host\t'
                    'host:$remote_addr\t'
                    'user:$remote_user\t'
                    'time:$time_local\t'
                    'method:$request_method\t'
                    'path:$request_uri\t'
                    'protocol:$server_protocol\t'
                    'status:$status\t'
                    'size:$body_bytes_sent\t'
                    'referer:$http_referer\t'
                    'agent:$http_user_agent\t'
                    'response_time:$request_time\t'
                    'cookie:$http_cookie\t'
                    'set_cookie:$sent_http_set_cookie\t'
                    'upstream_addr:$upstream_addr\t'
                    'upstream_cache_status:$upstream_cache_status\t'
                    'upstream_response_time:$upstream_response_time';
    access_log  /var/log/nginx/access.log  ltsv;
    sendfile        on;
    tcp_nopush     on;
    server_names_hash_bucket_size 128; # this seems to be required for some vhosts
    keepalive_timeout  65;
    gzip  on;

    server {
        listen 80;
        server_name  example.com
            ;
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location /static {
            alias /var/www/user/static;
        }
    }
#    include /etc/nginx/conf.d/*.conf;
}

I did not write this config but found this and edited to my use.

After our chat in comments, you told me you are having difficulties with using cmd and args.

Here is an example called two-containers.yaml :

apiVersion: v1
kind: Pod
metadata:
  name: two-containers
spec:
  restartPolicy: Never

  containers:
  - name: python
    image: python
    volumeMounts:
    - name: shared-data
      mountPath: /pod-data
    command: ["/bin/sh"]
    args: ["-c", "apt-get update && apt-get install -y curl && mkdir /curl-folder && cp /usr/bin/curl /curl-folder && cp -r /curl-folder /pod-data/"]

  - name: user-nginx
    image: nginx
    volumeMounts:
      - name: shared-data
        mountPath: /tmp/pod-data

  volumes:
  - name: shared-data
    emptyDir: {}

python will start up, run apt-get update then apt-get install -y curl then mkdir /curl-folder then copy usr/bin/curl to /curl-folder then copy the folder /curl-folder to /pod-data shared mounted volume.

A few observations:

  • The container image has to have the binary mentioned in command (like /bin/sh in python).
  • Try using && to chain commands consecutively in the args field it's easier to test and deploy.

Reproduction:

$ kubectl apply -f two-container-volume.yaml 
pod/two-containers created

$ kubectl get pods -w
NAME             READY   STATUS    RESTARTS   AGE
two-containers   2/2     Running   0          7s
two-containers   1/2     NotReady  0          30s

$ kubectl describe pod two-containers
...
Containers:
  python:
    Container ID:  docker://911462e67d7afab9bca6cdaea154f9229c80632efbfc631ddc76c3d431333193
    Image:         python
    Command:
      /bin/sh
    Args:
      -c
      apt-get update && apt-get install -y curl && mkdir /curl-folder && cp /usr/bin/curl /curl-folder && cp -r /curl-folder /pod-data/
    State:          Terminated
      Reason:       Completed
      Exit Code:    0

  user-nginx:
    State:          Running
  • The python container executed and completed correctly, now let's check the files logging inside the nginx container.
$ kubectl exec -it two-containers -c user-nginx -- /bin/bash
root@two-containers:/# cd /tmp/pod-data/curl-folder/     
root@two-containers:/tmp/pod-data/curl-folder# ls
curl

If you need further help, post the yaml with the command+args as you are trying to run and we can help you troubleshoot the syntax.

If it's a django app, consider using whitenoise http://whitenoise.evans.io/en/stable/ to serve your static content from minikube or kubernetes.

This is straightforward advice, but I had to search quite a bit before someone mentioned it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM