Nikko
Nikko

Reputation: 1572

Django static files are not found inside docker container

I am building a Django app with Docker. I run the command collectstatic in my entrypoint when database is ready. When I check my container, the /static/ folder is empty. Thus, Nginx cannot load the static files.

# settings.py
STATIC_URL = '/static/'
STATIC_ROOT = '/static/'

Here is my docker-compose file

version: "3.9"

services:
  db:
    image: postgis/postgis:14-3.3
    container_name: db
    volumes:
      - ./data/db:/var/lib/postgresql/data
    env_file:
    - prod.env

  backend:
    container_name: backend
    build:
      dockerfile: ./django/Dockerfile
    command: gunicorn api.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static:/usr/src/app/static
    ports:
      - "8000:8000"
    env_file:
    - prod.env
    depends_on:
      - db
  
  nginx:
    container_name: nginx
    build:
      dockerfile: ./nginx/Dockerfile
    volumes:
      - static:/usr/src/app/static
    ports:
      - "80:80"
    depends_on:
      - backend
    restart: always

  redis:
    container_name: redis
    restart: unless-stopped
    image: redis:alpine 
    expose:
      - 6379

  worker:
    container_name: worker
    build:
      dockerfile: ./django/Dockerfile
    command: celery -A api worker -l INFO
    volumes:
      - static:/usr/src/app/static
    env_file:
    - prod.env
    depends_on:
      - db
      - backend
      - redis
  
volumes:
  static:

My Nginx configuration:

upstream api {
    server backend:8000;
}

server {
    listen 80;

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

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

backend Dockerfile:

# syntax=docker/dockerfile:1
FROM python:3
WORKDIR /usr/src/app
RUN apt-get update
RUN apt-get install -y libgdal-dev gdal-bin netcat

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
COPY /django/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY /django/django-entrypoint.sh /django-entrypoint.sh
RUN chmod +x /django-entrypoint.sh

COPY django /usr/src/app

ENTRYPOINT ["/django-entrypoint.sh"]

And the entrypoint:

#!/bin/sh

if [ "$POSTGRES_NAME" = "postgres" ]
then
    echo "Waiting for Postgres..."

    while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do
      sleep 0.1
    done

    echo "PostgreSQL started"
fi

ls
# python manage.py flush --no-input
python manage.py migrate --no-input
python manage.py collectstatic --no-input

exec "$@"

In my files (local), I do not seem to see the '/static/' folder to be generated. How is this? I have check that static in backend and nginx by ssh in the container and the static folders were empty. In the logs, collectstatic was executed without an error with this message:

backend | 173 static files copied to '/static'.

Upvotes: 3

Views: 1680

Answers (2)

David Maze
David Maze

Reputation: 159761

You use a Docker named volume to hold the static files

    volumes:
      - static:/usr/src/app/static
      # ^^^^^^
      #   a volume name, not a host path

This named volume only exists inside Docker's storage; you will not see its content on your host system or in your local source tree.

This isn't a problem for the setup you're describing here: since you're re-running collectstatic every time the container starts up, and the volume contents hide the image contents in this directory, there's no particular need for the files to exist in source control or your host filesystem. If you did need them, you could presumably run manage.py collectstatic in a non-Docker virtual environment.

Upvotes: 3

iihsan
iihsan

Reputation: 347

Try by adding the following command in Dockerfile and re-build image.

RUN python manage.py collectstatic --noinput

You can place it after RUN pip install --no-cache-dir -r requirements.txt

Upvotes: 0

Related Questions