nginx / unit

NGINX Unit - universal web app server - a lightweight and versatile open source server that simplifies the application stack by natively executing application code across eight different programming language runtimes.
https://unit.nginx.org
Apache License 2.0
5.34k stars 322 forks source link

Serving django static files #249

Open R4z0R7 opened 5 years ago

R4z0R7 commented 5 years ago

Hello,

I noticed a problem with the static files in django applications. I have the following django app:

    "django": {
        "group": "djangotest",
        "home": "/home/djangotest/djenv",
        "module": "newtest.wsgi",
        "path": "/home/djangotest/newtest",
        "processes": 1,
        "type": "python 3.6",
        "user": "djangotest"
    }

This is a freshly-installed django 2.1 with no customisations. Python version is 3.6.8. The home page works fine but the stylesheets for the admin app return 404s. I observed the same behaviour with images and static files in another django application, and I decided to test it with a clean installation of django.

The static URLs seem to be treated like standard urls and if they don't match anything in the urls.py file, they return a 404 instead of retrieving the file.

This is the error message from Django:

"Request Method: | GET http://django.test/static/admin/css/base.css

Using the URLconf defined in newtest.urls, Django tried these URL patterns, in this order: admin/ The current path, static/admin/css/base.css, didn't match any of these."

In Nginx Unit's access log, I see this: "Not Found: /static/admin/css/base.css"

Static files are accessible when serving django with the built-in server for debugging and development. This only happens when the application is served by Unit.

I tried setting different environment variables for the application in Unit's configuration, such as STATIC_ROOT, STATIC_URL, STATIC_DIRS, DJANGO_SETTINGS_MODULE, etc., but none of these helped. Images and static files in the STATIC_ROOT directory would still not show.

Any ideas what might be wrong with the setup ?

VBart commented 5 years ago

Serving static files within Python application is very ineffective. Therefore Django serves static files only with internal development server, that isn't supposed for production use.

See: https://docs.djangoproject.com/en/stable/howto/static-files/deployment/

akshaybabloo commented 5 years ago

Use Nginx to serve static files

olivermussell commented 4 years ago

For a Django application you shouldn’t serve static files from the WSGI application directly. So for example if you were running Django in production you might use uWSGI to run the WSGI app and NGINX to serve static files.

However, since Unit 1.11.0 you can serve static files from Unit.

Here’s an example config that would serve static files from the /home/django/static/ directory for requests to example.com/static/. All other requests would be directed to the django application. Obviously you can change the matchers and static root path as necessary.

{
        "listeners": {
                "127.0.0.1:8000": {
                        "pass": "routes"
                }
        },

        "routes": [
            {
                "match": {
                    "host": [ “example.com” ],
                    "uri": "/static/*"
                },

                "action": {
                    "share": "/home/django/“
                }
            },
            {
                "action": {
                    "pass": "applications/django”
                }
            }
        ],

        "applications": {
        "django": {
            "group": "djangotest",
            "home": "/home/djangotest/djenv",
            "module": "newtest.wsgi",
            "path": "/home/djangotest/newtest",
            "processes": 1,
            "type": "python 3.6",
            "user": "djangotest"
        }
        }
}
rafsaf commented 3 years ago

Hi, I've recently moved somehow oldish Django app to docker-compose environment (web server is Nginx Unit). It works well, but Page Speed yells about "Serving static assets with an efficient cache policy". Is there an easy option to achieve that with Unit?

I don't really want to use Full Nginx as a proxy (or other option like that), there not so much static assets and eventually I will be probably totally fine with the current (the default I belive) behavior.

Maybe one can add something to the config.json to make it work (say for 7 days period)? Or in initial.sh file?

My config.json is almost copy-pasted from docs.

{
    "listeners": {
        "*:80": {
            "pass": "routes"
        }
    },
    "routes": [
        {
            "match": {
                "uri": "/static/*"
            },
            "action": {
                "share": "/build"
            }
        },
        {
            "action": {
                "pass": "applications/django"
            }
        }
    ],
    "applications": {
        "django": {
            "type": "python 3.9",
            "path": "/build/",
            "module": "application.wsgi"
        }
    }
}