skip to Main Content

I have created a django app and running it using docker and docker compose, but the static files are not getting served by nginx, instead the request get passed to django server. Please help, I was trying docker compose for first time🥲

Folder Structure

docker_insta(root folder)

  • insta_backend
    • insta_backend
    • manage.py
    • requirements.txt
    • Dockerfile
    • entrypoint.sh
  • nginx
    • default.conf
    • Dockerfile
  • docker-compose.yml

Files

  • docker-compose.yml
version: '3.9'
services:
  db:
    image: postgres:13.3
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    ports:
      - 5432:5432
    volumes:
      - db:/var/lib/postgresql/data
  redis:
    image: redis:6.2.4
    ports:
      - 6379:6379
  django:
    volumes:
      - static:/app/static
      - media:/app/media
    build: ./insta_backend
    ports:
      - 8000:8000
    depends_on:
      - db
      - redis
  nginx:
    build: ./nginx
    volumes:
      - static:/app/static
      - media:/app/media
    ports:
      - 80:80
    depends_on:
      - django

volumes:
  static:
  media:
  db:
  • Dockerfile(django)
FROM python:3.9-alpine

RUN pip install --upgrade pip

COPY ./requirements.txt .
RUN pip install -r requirements.txt

COPY . /app
WORKDIR /app

ENTRYPOINT [ "sh", "entrypoint.sh" ]

-entrypoint.sh

#!/bin/sh

python manage.py migrate --no-input
python manage.py collectstatic --no-input

gunicorn insta_backend.wsgi:application --bind 0.0.0.0:8000
  • Dockerfile(nginx)
FROM nginx:1.19.0-alpine

COPY ./default.conf /etc/nginx/conf.d/default.conf
  • default.conf
upstream django_server {
    server django:8000;
}

server {
    listen 80;

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

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

    location / {
        proxy_pass http://django_server;
    }
}
  • settings.py
...

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

...

Observations

  • all containers started successfully
  • upon visiting to localhost i saw the django app but without static files
  • by checking logs i came to see that /static/..... requests were passed on to django instead of being served by nginx
  • i checked that volumes are mounted correctly between django and nginx, I also cross checked by creating a file from django’s interactive shell in static folder and it was visible in nginx’s /app/static folder and vice versa
  • django logs

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution, By including proxy headers in nginx conf file, requests were handled correctly.

    upstream django_server {
        server django:8000;
    }
    
    server {
        listen 80;
    
        location /static/ {
            alias /app/static/;
        }
    
        location /media/ {
            alias /app/media/;
        }
    
        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_pass http://django_server;
        }
    }
    

  2. So I’m not sure but maybe instead of alias you could use root and rewrite the request on NGINX. It can be like:

    location /static{
        rewrite /static/(.*) /static/$1 break;
        root /path/to/project;
    }
    

    First try without the rewrite, just setting the root for the static files, if it doesn’t work try to set the root to the path of the project and rewrite to static.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search