Static files are not found when running django + gunicorn + nginx on docker

11,962

The problem was with settings of django application and not nginx after all. I've specified STATIC_URL as STATIC_ROOT which was pointing at absolute path to folder which was containing static files. As I understand, when page was loaded and tried to resolve urls of scripts based on {{ static }} tag it ended up looking for this absolute path which obviously could not be process by nginx. I've changed it so STATIC_URL = '/static/' and everything works as should.

Share:
11,962

Related videos on Youtube

kebie
Author by

kebie

Updated on September 18, 2022

Comments

  • kebie
    kebie over 1 year

    I know it's well answered question but non of ones I've found seems to work for me. I have simple django project and I'm trying to run it on Docker with gunicorn and nginx. Below is my configuration

    Dockerfile

    # Pull base image
    FROM python:3.6-slim
    
    # Set environment varibles
    ENV PYTHONDONTWRITEBYTECODE 1
    ENV PYTHONUNBUFFERED 1
    ENV DATABASE_HOST db
    
    # Set work directory
    ARG PROJECT=my_project
    ARG PROJECT_DIR=/var/www/${PROJECT}
    
    RUN mkdir -p $PROJECT_DIR
    
    # Copy project
    COPY my_project $PROJECT_DIR/
    COPY docker-entrypoint.sh /
    RUN chmod u+x /docker-entrypoint.sh
    # give permission for nginx to read static files
    RUN chown -R "$USER":www-data /var/www/my_project/allstatic && chmod -R 0755 /var/www/my_project/allstatic
    
    WORKDIR $PROJECT_DIR
    EXPOSE 8000
    ENTRYPOINT ["/docker-entrypoint.sh"]
    

    docker-entrypoint.sh

    #!/bin/bash
    
    apt-get update
    apt-get install -y git 
    pip install --upgrade pip
    pip install -r requirements.txt
    python manage.py collectstatic --noinput
    python manage.py migrate --no-input
    touch ./logs/gunicorn.log
    touch ./logs/gunicorn-access.log
    tail -n 0 -f ./logs/gunicorn*.log &
    
    gunicorn --bind 0.0.0.0:8000 my_project.wsgi:application --log-level=info --log-file=./logs/gunicorn.log --access-logfile=./logs/gunicorn-access.log 
    
    exec "$@"
    

    docker-compose.yml

    version: '3.6'
    
    services:
      db:
      image: postgres:10.5-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=some_some
      - POSTGRES_DB=database
    networks:
      - database_network
    
    app:
      build: .
      volumes:
        - .:/var/www
        - static_volume:/var/www/my_project/allstatic
      depends_on:
        - db
      networks:
        - nginx_network
        - database_network
    
    nginx:
      image: nginx:1.13
      ports:
        - 8000:8000
      volumes:
        - ./config/nginx/conf.d:/etc/nginx/conf.d
        - static_volume:/var/www/my_project/allstatic
      depends_on:
        - app
      networks:
        - nginx_network
    
    networks:
      nginx_network:
        driver: bridge
      database_network:
        driver: bridge
    
    volumes:
      postgres_data:
      static_volume:
    

    nginx config

    upstream develop_server {
        server app:8000;
    }
    
    server {
        listen 8000;
        server_name localhost;
    
        location / {
            proxy_read_timeout 300;
            proxy_pass http://develop_server;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_redirect off;
        }
    
        location /static/ {
            autoindex on;
            alias /var/www/my_project/allstatic;
        }
    }
    

    in project settings I've defined STATIC_URL and STATIC_ROOT as

    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    STATIC_ROOT = os.path.join(BASE_DIR, 'allstatic/')
    STATIC_URL = STATIC_ROOT
    

    And here is error I'm getting

    app_1  | Not Found: /var/www/my_project/allstatic/really_important_file.js
    nginx_1    | 172.22.0.1 - - [23/Sep/2018:11:55:26 +0000] "GET /var/www/my_project/allstatic/really_important_file.js HTTP/1.1" 404 3132 "http://localhost:8000/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0" "-"
    

    Beside this error whole page loads without problem. Also, when I run server with manage.py runserver statics are served propertly, hence I suspect my nginx configuration is somehow wrong. Answers I was able to find suggested to change a permission for nginx on static directory what is done in Dockerfile (or maybe it's done wrong?).

    I'd be very grateful for pointing out what I've missed.

    UPDATE

    It's definetly not a permission issue - I'm able to reach this file by going to localhost:8000/static/really_important_file.js in my webbrowser. Now I really have no idea what may be causing those errors.