skip to Main Content

When i try to access http://127.0.0.1:8000/admin, i get this.

enter image description here

my folder structure is :

django-react-nginx
|
|_ _ docker-compose.yml
|
  > backend
        |
        |_ Dockerfile
        |
        |_ entrypoint.sh

     > languages
          |
          |_ settings.py
     > media
     > static # This folder appears after running docker-compose -d --build
  > nginx
      |
      |_ default.conf
      |
      |_ Dockerfile

now

here is the files

Django

settings.py

DEBUG = True

ALLOWED_HOSTS = ['*']

STATIC_URL = '/static/'

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

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')        

MEDIA_URL = '/media/'

Docker file

FROM python:3.8

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /backend

COPY  requirements.txt /backend/

RUN pip install -r requirements.txt && 
    pip install --upgrade pip

COPY ./entrypoint.sh /

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

entrypoint.sh

#!/bin/sh

python manage.py migrate --no-input

python manage.py collectstatic --no-input

gunicorn languages.wsgi:application --bind 0.0.0.0:8000

Nginx

default.conf

upstream django {
    server backend:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
    }

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

    location /media/ {
        autoindex on;
        alias /backend/static;
    }

}

Dockerfile

FROM nginx:1.19.8-alpine

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

Root Folder

Docker-compose

version: "3.7"

services:
  backend:
    build: ./backend/languages
    stdin_open: true # interactive
    tty: true        # interactive
    restart: "on-failure"
    env_file:
      .env
    volumes:
      - ./backend/languages:/backend
      - ./backend/languages/static:/backend/static
    ports:
      - 8000:8000
    networks:
      - nginx_network
      - db_network
    depends_on:
      - db
  db:
    image: postgres:11
    restart: "on-failure"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    networks:
      - db_network
  
  nginx:
    build: ./nginx
    restart: always
    volumes:
      - ./backend/languages:/backend
      - ./backend/languages/static:/static
    ports:
      - 80:80
    networks:
      - nginx_network
    depends_on:
      - backend

networks:
  nginx_network:
    driver: bridge
  db_network:
    driver: bridge

volumes:
  postgres_data:

As mentioned above i am not sure how to make the static files work, they been copied to the folder mentioned above because when i can see the folder created and when i check the logs i get this 165 static files copied to '/backend/static'.

2

Answers


  1. Nginx config

    Nginx config looks fine. Container is mapped to /backend/languages/static with /static and the alias points to the same folder inside container – /static.

    nginx.conf

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

    upd issue detected: an alias must have the same ending slash to work properly. so it has to be alias /static/

    nginx in compose

      nginx:
        ...
        volumes:
          - ./backend/languages:/backend
          - ./backend/languages/static:/static
    

    Django config

    But Django config looks broken. Here you’ve configured to collect static to static folder within BASE_DIR

    settings.py

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

    and this is exactly what collectstatic is reporting to you:

    165 static files copied to '/backend/static'

    files are in the /backend/static, not /static. Hovewer the container is configured to root folder /static:

    django in compose

      backend
        ...
        volumes:
          - ./backend/languages:/backend
          - ./backend/languages/static:/static
    

    looks like the issue can be fixed by pointing to

        volumes:
          - ./backend/languages/static:/backend/static
    

    Nevertheless there is still some work to do: media files are not supposed to be served by Django as well, so it is recommended to configure Nginx to serve media files too.

    Django Dockerfile

    I believe the mapping ./backend/languages:/backend works but what’s the point of dockerizing then? There is no app in this docker image, just dependencies. It is "better" to include sources in the image so the deployment in the end would require to update images and restart containers only.

    So, as a side note, I’d suggest to (at least try to):

    • update configs to serve media files with Nginx
    • include django app sources inside your docker image
    • collect static files during the build and not to include them into docker image
    • remove collectstatic from the entrypoint
    • supply static files and treat them as a separate product, think of them if you were going to deliver them to a CDN, a separate hosting – it is a very common solution
    • whilst they are still on the same hosting, keep mapping them to the container as you do now, but in a "reversed" way: deliver static files to the host folder, access them from the container in ro mode
    Login or Signup to reply.
  2. You can use whitenoise by configuring it in your settings file. Set up Whitenoise with Django here

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