Django css not rendering in Production
In my Django5 app everything works fine in development under venv but once I load the application into a Docker container with Debug=False I don't seem to get my CSS rendered properly. Whats really wierd is the CSS loading appears to be correct, I just don't get my custom css hero image and colors, and the admin css is also broken. I'm using gunicorn with nginx serving static data. I do see my favicon.ico which is served from the same /static/ folder and the css, js, etc. folders all exist in the nginx container as expected. I view source and click on the links and they're all there.
In Django settings.py I have:
from pathlib import Path
import os
import environ
env = environ.Env(
DEBUG=(bool, False)
)
BASE_DIR = Path(__file__).resolve().parent.parent
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
SECRET_KEY = env('SECRET_KEY')
DEBUG = env('DEBUG')
ALLOWED_HOSTS = ['*']
.
.
.
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Changing STATIC_ROOT to the actual container path '/usr/share/nginx/html/static/' didn't change the behaviour.
In my root urls.py:
urlpatterns = [
path("admin/", admin.site.urls),
.
.
.
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
My dockerfile-compose.yaml includes collectstatic:
web:
build:
context: .
dockerfile: Dockerfile
command: >
sh -c "python manage.py collectstatic --noinput
&& python manage.py migrate
&& supervisord -c /etc/supervisor/conf.d/supervisord.conf"
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
- rabbitmq
environment:
- DATABASE_URL=postgres://mysite:fakepassword@db:5432/mysite
- CELERY_BROKER_URL=amqp://guest@rabbitmq//
My Dockerfile.nginx includes copying the static data to a folder on it's (seperate) container:
# Use the official Nginx image from the Docker Hub
FROM nginx:latest
# Copy the Nginx configuration file to the container
COPY nginx.conf /etc/nginx/nginx.conf
# Copy the SSL certificates to the container
COPY certificate.crt.pem /etc/nginx/ssl/certificate.pem
COPY certificate.key.pem /etc/nginx/ssl/private_key.pem
# Copy the static files from the Django container
COPY staticfiles /usr/share/nginx/html/static
COPY media /usr/share/nginx/html/media
# Expose port 443 for HTTPS
EXPOSE 443
In the nginx container (site URL replaced by mysite) I see:
nginx-1 | 172.18.0.1 - - [18/Feb/2025:20:39:49 +0000] "GET / HTTP/1.1" 200 6030 "https://mysite/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
nginx-1 | 172.18.0.1 - - [18/Feb/2025:20:39:49 +0000] "GET /static/css/styles.css HTTP/1.1" 304 0 "mysite" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
nginx-1 | 172.18.0.1 - - [18/Feb/2025:20:39:59 +0000] "GET / HTTP/1.1" 200 6030 "https://mysite/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
nginx-1 | 172.18.0.1 - - [18/Feb/2025:20:39:59 +0000] "GET /static/css/styles.css HTTP/1.1" 200 2269 "https://mysite/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
nginx-1 | 172.18.0.1 - - [18/Feb/2025:20:39:59 +0000] "GET /static/images/favicon.ico HTTP/1.1" 200 5879 "https://mysite/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
nginx-1 | 172.18.0.1 - - [18/Feb/2025:20:39:59 +0000] "GET /static/images/favicon.ico HTTP/1.1" 200 5879 "https://mysite/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"
So I appear to be getting 200s on my actual css files but they're not being reflected in my program. None of the admin css files are being rendered, yet they are being loaded. I'm stumped, any assistance would be appreciated thanks!