Home > Software engineering >  Setting up Django static with Docker/Nginx
Setting up Django static with Docker/Nginx

Time:12-24

I am Dockerizing my Django/React app but having issues getting the static files to show up on the prod server.

Project Directory:

.
├── README.md
├── backend
│   ├── Dockerfile
│   ├── Dockerfile.prod
│   ├── backend
│   ├── entrypoint.prod.sh
│   ├── entrypoint.sh
│   ├── manage.py
│   ├── requirements.txt
│   └── static
├── docker-compose.ci.yml
├── docker-compose.prod.yml
├── docker-compose.yml
├── frontend
│   ├── Dockerfile
│   ├── Dockerfile.prod
│   ├── README.md
│   ├── build
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   ├── src
│   └── webpack.config.js
└── nginx
    ├── Dockerfile
    └── nginx.conf

nginx.conf

upstream backend {
    server backend:8000;
}

server {
    listen 80;

    location / {
        root "/var/www/frontend";
    }    

    location /api/ {
        proxy_pass http://backend;
        proxy_set_header Host $http_host;
    }

    location /admin/ {
        proxy_pass http://backend;
        proxy_set_header Host $http_host;
    }
    
    location /static/ {
        alias /backend/static;
    }
}

Django static setting:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

docker-compose.ci.yml (builds the images):

version: "3.8"

services:
  backend:
    build:
      context: ./backend
      dockerfile: Dockerfile.prod
    image: "${BACKEND_IMAGE}"
    command: gunicorn backend.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/backend/static
      - media_volume:/backend/media
    expose:
      - 8000
    env_file: .env
  frontend:
    build:
      context: ./frontend
      dockerfile: Dockerfile.prod
    image: "${FRONTEND_IMAGE}"
    volumes:
      - frontend_build:/frontend/build
  nginx:
    build:
      context: ./nginx
    image: "${NGINX_IMAGE}"
    ports:
      - 80:80
    volumes:
      - static_volume:/backend/static
      - frontend_build:/var/www/frontend
    depends_on:
      - backend
      - frontend

volumes:
  frontend_build:
  static_volume:
  media_volume:

In the network tab of Chrome Dev Tools it shows this URL when trying to load static:

Request URL: http://ipaddress/static/admin/css/nav_sidebar.cs

CodePudding user response:

Static files collected inside the backend container during the build are hidden by static_volume which is mounted when you run docker-compose.

When you mount a volume on top of a directory, you only see the contents of the volume, not the files that were in the directory before.

To fix this you could

  • Run collectstatic after the volume is mounted. I.e. after the server is up
  • Copy static files produced by Django into the nginx container at build time (no need to use the volume anymore)
  • Related