简体   繁体   中英

serving Django static files with Docker, nginx and gunicorn

I am setting us a Django 2.0 application with Docker , nginx and gunicorn .

It's running the server but static files are not working.

Here is the settings.py content

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static_my_project')
]

STATIC_ROOT = os.path.join(BASE_DIR, 'static_cdn', 'static_root')

While developing, I put my static files inside static_my_project , which on running collectstatic copies to static_cdn/static_root

The directory structure is like

app
 |- myapp
    |- settings.py
 |- static_my_project
 |- static_cdn
    |- static_root
 |- config
    |- nginx
       |- nginx.conf
 |- manage.py
 |- Docker
 |- docker-compose.yml

on running

docker-compose up --build

on running collectstatic , it gives path where static files will be copied

koober-dev | --: Running collectstatic
koober-dev |
koober-dev | You have requested to collect static files at the destination
myapp-dev | location as specified in your settings:
myapp-dev |
myapp-dev | /app/static_cdn/static_root
myapp-dev |
myapp-dev | This will overwrite existing files!
myapp-dev | Are you sure you want to do this?
myapp-dev |
myapp-dev | Type 'yes' to continue, or 'no' to cancel:
myapp-dev | 0 static files copied to '/app/static_cdn/static_root', 210 unmodified.

the config/nginx/nginx.conf file contains following settings

upstream web {
    ip_hash;
    server web:9010;
}

server {
    location /static {
        autoindex on;
        alias /static/;
    }

    location / {
        proxy_pass http://web;
    }
    listen 10080;
    server_name localhost;
}

docker-compose.yml

version: '3'

services:
  nginx:
    image: nginx:latest
    container_name: "koober-nginx"
    ports:
      - "10080:80"
      - "10443:43"
    volumes:
      - .:/app
      - ./config/nginx:/etc/nginx/conf.d
      - ./static_cdn/static_root/:/static
    depends_on:
      - web
  web:
    build: .
    container_name: "koober-dev"
    command: ./start.sh
    volumes:
      - .:/app
      - ./static_cdn/static_root/:/app/static_cdn/static_root
    ports:
      - "9010:9010"
    depends_on:
      - db
  db:
    image: postgres
    container_name: "koober-postgres-db"

Dockerfile

FROM ubuntu:18.04

# -- Install Pipenv:
FROM python:3
ENV PYTHONUNBUFFERED 1

ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

# -- Install Application into container:
RUN set -ex && mkdir /app

WORKDIR /app
ADD requirements.txt /app/

RUN pip install -r requirements.txt

# -- Adding dependencies:
ADD . /app/

But it is not loading static files.

You need to have a shared volume to the STATIC_ROOT directory so that your nginx container can reverse proxy to both web server and static files generated by your web server.

In docker-compose.yml :

services:
  nginx:
    image: nginx:alpine
    volumes:
      - ./static_cdn/static_root/:/static
    ports:
      - 80:80
  web:
    build: .
    volumes:
      - ./static_cdn/static_root/:/app/static_cdn/static_root

Now in your nginx.conf add:

location /static/ {
    alias /static/;
}

Nginx Dockerfile:

FROM nginx:stable-alpine

COPY default.conf /etc/nginx
COPY default.conf /etc/nginx/conf.d

EXPOSE 80

default.conf referred to in the above Dockerfile:

server {

    listen 80 default_server;
    server_name _;

    location / {
        proxy_pass http://web:8000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
    }

    location /static/ {
        alias /app/static/;
    }

    location /media/ {
        alias /app/static/;
    }

}

Note: The default.conf and Dockerfile mentioned above is under the same folder, build that image and use it as the Nginx image in the below docker-compose file.

The docker-compose file would look like this:

version: '3.8'

services:
  web:
    image: <django-image-name>
    command: gunicorn --bind 0.0.0.0:8000 licensing_platform.wsgi --workers=4
    volumes:
      - static_volume:/app/static
      - media_volume:/app/media
    expose:
      - "8000"
    networks:
      - django-network

  nginx:
    image: <nginx-image-name>
    restart: always
    volumes:
      - static_volume:/app/static
      - media_volume:/app/media
    ports:
      - "80:80"
    depends_on:
      - web
    networks:
      - django-network

networks:
  django-network:
    name: django-network

volumes:
  media_volume:
  static_volume:

The app/ path referenced depends on the working directory: The django application Dockerfile would start with:

FROM ubuntu:20.04
ADD . /app
WORKDIR /app
EXPOSE 8000

Code reference: https://github.com/addu390/licensing-as-a-platform

The code reference mentioned above is an open-source project I'm working on with no commercial benefits.

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