Have been trying to troubleshoot static file errors with no luck.

Hello,

I have been trying to solve a issue serving static files. At one point the files were located, wsgi:error message in error_log, but the css still wasn’t loaded. So I’ve renamed /static/ to /staticfiles/ and reran python ./manage.py collectstatic. The files are there. The path seems correct i.e. I can see the plaintext via localhost:8000/path/to/static/style.css. The same path apache should be looking for, seems to be.

The issue I’m at now is a MIME type error in the browser, a 404, but also the ‘file not found’ errors in apache logs for ‘style/style.css’.

I am running apache server.

path to ‘staticfiles’

/var/www/html/CRM/python3.12.1-venv/nserpvenv312/nserp/staticfiles

settings.py

from ensurepip import bootstrap
from pathlib import Path

import os


import mimetypes
mimetypes.add_type("text/css", ".css", True)


# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/


# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['domain.tld', 'www.domain.tld', 'localhost']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'nserp',

]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',

    ]

ROOT_URLCONF = 'nserp.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'nserp.wsgi.application'


# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases

DATABASES = {
    'default': {
        
    }
}


# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'America/Chicago'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/

#for dev
#STATIC_URL = '/nserp/nserp_static/'

#for prod
STATIC_URL = '/staticfiles/'

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'nserp/nserp_static'),
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')

# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

TEMPLATE_CONTEXT_PROCESSORS = "django.template.context_processors.request"

my vhost.conf


<VirtualHost *:443>

ServerName www.domain.tld
ServerAlias domain.tld

Alias /static "/var/www/html/CRM/python3.12.1-venv/nserpvenv312/nserp/staticfiles"
<Directory /var/www/html/CRM/python3.12.1-venv/nserpvenv312/nserp/staticfiles>
        Require all granted
</Directory>

<Directory /var/www/html/CRM/python3.12.1-venv/nserpvenv312/nserp/nserp>
        <Files wsgi.py>
                Require all granted
        </Files>
</Directory>

WSGIDaemonProcess domain.tld python-path=/var/www/html/CRM/python3.12.1-venv/nserpvenv312/nserp/
WSGIScriptAlias / /var/www/html/CRM/python3.12.1-venv/nserpvenv312/nserp/nserp/wsgi.py process-group=domain.tld
WSGIProcessGroup domain.tld


# Other directives here


</VirtualHost>

the errors

[Sun May 19 12:02:00.092929 2024] [wsgi:error] [pid 3444429:tid 3444613] [remote 172.70.127.159:55842] Not Found: /staticfiles/style/style.css
[Sun May 19 12:02:00.203598 2024] [wsgi:error] [pid 3444429:tid 3444589] [remote 172.70.127.86:63502] Not Found: /staticfiles/img/IMG_7137.jpg

browser console

The resource from “https://domain.tld/staticfiles/style/style.css” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).

The resource from “https://domain.tld/staticfiles/style/style.css” was blocked due to MIME type (“text/html”) mismatch (X-Content-Type-Options: nosniff).
|GET|https://domain.tld/staticfiles/style/style.css|

Status

404

VersionHTTP/2

Transferred754 B (0 B size)

Referrer Policysame-origin

DNS ResolutionDNS over HTTPS

I have 755 on dirs and 644 on files, root:apache for all.

The venv is nserpvenv312 running python3.12, that is also the interpreter I’m using in dev.

Willing to do whatever it takes to get this right. I thought I had an understanding because I’ve launched this app 3 times now, each time with different errors but Ive been able to solve them with the internet. I just cannot for the life of me figure this one out. Hopefully after this I will understand where I am going wrong and have smooth deployments for future versions.

Thank you!

For what you currently have posted here, you have:

But your log shows:

which doesn’t match the path in the alias directive.

Thanks for your reply, Ken.

What would be the proper way to correct this?

I had the previous app set up the same, so I thought. But clearly I am not setting it up the same way because it no longer works with the css.

This (above) needs to match this (below)

It doesn’t matter what they are - they just need to agree. (You could even set them both to “blah”.) The STATIC_URL creates the references in the HTML, and the alias maps those HTML references to physical directories.

If there are issues beyond this, we can investigate further.

Wow. That was incredibly simple. I will remember the relationship these two have for the future.

Thanks a million!

Everything is working now :smile: