# Static files not found if SCRIPT\_NAME is defined?

**URL:** <https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520>\
**Category:** Deployment\
**Created:** [June 21, 2025, 11:08am UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520 "2025-06-21T11:08:54Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![petasis](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/petasis/32/6393_2.png) [@petasis](https://forum.djangoproject.com/u/petasis)\
**Post date:** [June 21, 2025, 11:08am UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/1 "2025-06-21T11:08:54Z")

</div>

Hi all,

I have a django application (containerised), which works and serves static files.  
I want to serve this application under a nginx proxy.  
But suddenly, the static files are not found by django.

In urls.txt, I have the following code:

```auto
urlpatterns = [
    path('admin/', admin.site.urls),
    path('scrape/', include('crawlerScrapy.urls')),
    path('api/', include('api.urls')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

print('STATIC_URL:', settings.STATIC_URL)
print('STATIC_ROOT:', settings.STATIC_ROOT)
print('URL Patterns:', urlpatterns)
import os
print(os.listdir(settings.STATIC_ROOT + 'rest_framework/js'))

```

When the code runs, I get the following:

```auto
STATIC_URL: /disinformation_data_server/static/
STATIC_ROOT: /app/static/
URL Patterns: [<URLResolver <URLPattern list> (admin:admin) 'admin/'>, <URLResolver <module 'crawlerScrapy.urls' from '/app/crawlerScrapy/urls.py'> (None:None) 'scrape/'>, <URLResolver <module 'api.urls' from '/app/api/urls.py'> (None:None) 'api/'>, <URLPattern '^disinformation_data_server/static/(?P<path>.*)$'>]
['load-ajax-form.js', 'jquery-3.7.1.min.js', 'bootstrap.min.js', 'prettify-min.js', 'coreapi-0.1.1.js', 'csrf.js', 'ajax-form.js', 'default.js']

```

So, everything seems fine from inside django. But when the static files are requested, I see in the logs:

```auto
Not Found: /disinformation_data_server/static/rest_framework/js/jquery-3.7.1.min.js
Not Found: /disinformation_data_server/static/rest_framework/js/ajax-form.js
Not Found: /disinformation_data_server/static/rest_framework/js/csrf.js

```

Since the files exist in the static folder, why I am getting that they are not found?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 21, 2025, 11:24am UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/2 "2025-06-21T11:24:41Z")

</div>

Please post your nginx configuration for project entries.

---

<div class="post-metadata">

**Author:** ![petasis](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/petasis/32/6393_2.png) [@petasis](https://forum.djangoproject.com/u/petasis)\
**Post date:** [June 21, 2025, 11:39am UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/3 "2025-06-21T11:39:49Z")

</div>

Here it is:

```auto
    location /disinformation_data_server/ {
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $http_host;
        proxy_set_header SCRIPT_NAME /disinformation_data_server/;
        proxy_pass http://127.0.0.1:8020;
        proxy_redirect off;
    }

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 21, 2025, 11:58am UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/4 "2025-06-21T11:58:01Z")

</div>

How are you running Django in its container? (gunicorn? uwsgi? something else?)

In the general case, for a production-quality deployment behind nginx, you will want to have `collectstatic` copy your files to a data volume that nginx also has mounted, and have a _separate_ nginx configuration paragraph to read the static files from that volume. You don’t want to have Django serving your static files.

---

<div class="post-metadata">

**Author:** ![petasis](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/petasis/32/6393_2.png) [@petasis](https://forum.djangoproject.com/u/petasis)\
**Post date:** [June 21, 2025, 12:09pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/5 "2025-06-21T12:09:35Z")

</div>

Here is my container entry point:

```auto
#!/bin/env bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
cd $SCRIPT_DIR

while ! nc -z $SQL_HOST $SQL_HOST_PORT; do
  sleep 0.1
done
echo "Database started"

case $* in
  *gunicorn* | *runserver*)
    echo "Appling database migrations..."
    python manage.py makemigrations 
    runuser -u appuser -- python manage.py migrate

    echo "Collect static files..."
    python manage.py collectstatic --no-input

    echo "Starting Celery Worker..."
    runuser -u appuser -- watchmedo auto-restart -d /app -p '*.py' -R -D -- celery --app disinformationDataServer worker --loglevel INFO -E &

    echo "Executing CMD with watchmedo: \"$@\""
    runuser -u appuser -- watchmedo auto-restart -d /app -p '*.py' -R -D -- $@
  ;;
  *)
    echo "Executing CMD: \"$@\""
    exec $@
  ;;
esac

```

The container logs are:

```auto
Database started
Appling database migrations...
STATIC_URL: /static/
STATIC_ROOT: /app/static
URL Patterns: [<URLResolver <URLPattern list> (admin:admin) 'admin/'>, <URLResolver <module 'crawlerScrapy.urls' from '/app/crawlerScrapy/urls.py'> (None:None) 'scrape/'>, <URLResolver <module 'api.urls' from '/app/api/urls.py'> (None:None) 'api/'>, <URLPattern '^static/(?P<path>.*)$'>]
['load-ajax-form.js', 'jquery-3.7.1.min.js', 'bootstrap.min.js', 'prettify-min.js', 'coreapi-0.1.1.js', 'csrf.js', 'ajax-form.js', 'default.js']
No changes detected
STATIC_URL: /static/
STATIC_ROOT: /app/static
URL Patterns: [<URLResolver <URLPattern list> (admin:admin) 'admin/'>, <URLResolver <module 'crawlerScrapy.urls' from '/app/crawlerScrapy/urls.py'> (None:None) 'scrape/'>, <URLResolver <module 'api.urls' from '/app/api/urls.py'> (None:None) 'api/'>, <URLPattern '^static/(?P<path>.*)$'>]
['load-ajax-form.js', 'jquery-3.7.1.min.js', 'bootstrap.min.js', 'prettify-min.js', 'coreapi-0.1.1.js', 'csrf.js', 'ajax-form.js', 'default.js']
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, crawlerScrapy, sessions
Running migrations:
  No migrations to apply.
Collect static files...

163 static files copied to '/app/static'.
Starting Celery Worker...
Executing CMD with watchmedo: "gunicorn --bind 0.0.0.0:8000 --workers 3 disinformationDataServer.wsgi:application"

```

If you look the logs in the original post, where I list a directory files, the files are there.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 21, 2025, 12:12pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/6 "2025-06-21T12:12:36Z")

</div>

> [@petasis](#):
>
> If you look the logs in the original post, where I list a directory files, the files are there.

Yes, but is that a separate data volume that nginx can access directly? You also didn’t show a separate location directive for nginx to do that.

Static files should _not_ be served by Django. They should be served by nginx like it would serve any other file.

---

<div class="post-metadata">

**Author:** ![petasis](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/petasis/32/6393_2.png) [@petasis](https://forum.djangoproject.com/u/petasis)\
**Post date:** [June 21, 2025, 12:22pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/7 "2025-06-21T12:22:36Z")

</div>

I want static data to be served by django. The static data are inside the container, nginx has no access to them. Nginx runs on a server, and serves 10+ other containers.

Actually, they are the static data of django rest framework.

The problem is why they are not found by django when proxied (the only change is the SCRIPT\_NAME env variable).

How can I debug the view that handles the static files, that says “not found”?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 21, 2025, 12:25pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/8 "2025-06-21T12:25:02Z")

</div>

> [@petasis](#):
>
> I want static data to be served by django.

You don’t.

> [@petasis](#):
>
> The static data are inside the container, nginx has no access to them.

That’s a mistake.

> [@petasis](#):
>
> Nginx runs on a server, and serves 10+ other containers.

Not a big deal.

> [@petasis](#):
>
> Actually, they are the static data of django rest framework.

This does not make a difference.

> [@petasis](#):
>
> The problem is why they are not found by django when proxied (the only change is the SCRIPT\_NAME env variable).

I suspect that the other difference is that you’re running this under gunicorn (production quality) instead of runserver (development only).

---

<div class="post-metadata">

**Author:** ![petasis](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/petasis/32/6393_2.png) [@petasis](https://forum.djangoproject.com/u/petasis)\
**Post date:** [June 21, 2025, 1:04pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/9 "2025-06-21T13:04:34Z")

</div>

In the same container, with gunicorn, static files are found and served, if env variable SCRIPT\_NAME is not defined.

On the other hand, I looked the code of the view that serves the static files, it does not print “Not Found:”. It just returns 404.

It may not be a django problem, but a gunicorn one. Needs more debugging.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 21, 2025, 1:48pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/10 "2025-06-21T13:48:54Z")

</div>

You might get it to “work”, but that’s still not how you _should_ be deploying in a production-quality environment.

---

<div class="post-metadata">

**Author:** ![petasis](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/petasis/32/6393_2.png) [@petasis](https://forum.djangoproject.com/u/petasis)\
**Post date:** [June 21, 2025, 3:12pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/11 "2025-06-21T15:12:42Z")

</div>

Its a django bug. To make it work, I had to do this:

```auto
urlpatterns = [
    path('admin/', admin.site.urls),
    path('scrape/', include('crawlerScrapy.urls')),
    path('api/', include('api.urls')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static('static/', document_root=settings.STATIC_ROOT)

```

Django will modify STATIC\_URL and prepend it with SCRIPT\_NAME if it does not start with /.  
But this will add SCRIPT\_NAME also in the regular expression that matches the request url.  
The rest of the patterns do not have the SCRIPT\_NAME prefix…

So the not found is more fundamental, there is no match between the urls and the request url, the file serve view is never called.

So, if SCRIPT\_NAME is defined, `static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)` is wrong.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [June 21, 2025, 6:58pm UTC](https://forum.djangoproject.com/t/static-files-not-found-if-script-name-is-defined/41520/12 "2025-06-21T18:58:38Z")

</div>

> [@petasis](#):
>
> Its a django bug.

Actually, it is **not** “a Django bug”, because you’re using Django in a situation for which it is neither designed nor intended to be used.

From the docs for [Serving static files in production](https://docs.djangoproject.com/en/5.2/howto/static-files/deployment/#serving-static-files-in-production):

> The basic outline of putting static files into production consists of two steps: run the [`collectstatic`](https://docs.djangoproject.com/en/5.2/ref/contrib/staticfiles/#django-admin-collectstatic) command when static files change, **then arrange for the collected static files directory ([`STATIC_ROOT`](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-STATIC_ROOT)) to be moved to the static file server and served.**

[Emphasis added]

And in the docs for [How to manage static files (e.g. images, JavaScript, CSS) | Django documentation | Django](https://docs.djangoproject.com/en/5.2/howto/static-files/) :

> Serving the files
> 
> In addition to these configuration steps, you’ll also need to actually serve the static files.
> 
> During development, if you use [`django.contrib.staticfiles`](https://docs.djangoproject.com/en/5.2/ref/contrib/staticfiles/#module-django.contrib.staticfiles), this will be done automatically by [`runserver`](https://docs.djangoproject.com/en/5.2/ref/django-admin/#django-admin-runserver) when [`DEBUG`](https://docs.djangoproject.com/en/5.2/ref/settings/#std-setting-DEBUG) is set to `True` (see [`django.contrib.staticfiles.views.serve()`](https://docs.djangoproject.com/en/5.2/ref/contrib/staticfiles/#django.contrib.staticfiles.views.serve)).
> 
> This method is **grossly inefficient** and probably **insecure** , so it is **unsuitable for production**.
> 
> See [How to deploy static files](https://docs.djangoproject.com/en/5.2/howto/static-files/deployment/) for proper strategies to serve static files in production environments.

And in the [Deployment](https://docs.djangoproject.com/en/5.2/howto/static-files/#deployment) section of that same page:

> 1. Use a web server of your choice to serve the files. [How to deploy static files](https://docs.djangoproject.com/en/5.2/howto/static-files/deployment/) covers some common deployment strategies for static files.

So while what you’ve found is technically accurate - it doesn’t matter, because you shouldn’t even be trying to do this.
