The way production servers are setup with Django uses this kind of request workflow:
client /myapp1 --> nginx:8080 ---(proxy)---> gunicorn:8000 (runs python) client /myapp2 --> nginx:8080 ---(proxy)---> gunicorn:8000 (runs python) client /myapp3 --> nginx:8080 ---(proxy)---> gunicorn:8000 (runs python) client /static/somefile1.css ---> nginx:8080 (reads from the filesystem) client /static/somefile2.css ---> nginx:8080 (reads from the filesystem) Notice how everything first goes to nginx, and then your nginx either proxies/forwards the request to gunicorn for the python code, or it serves up the static file itself. That's what we want to do. gunicorn is very good at running dynamic python code but it's very bad at serving up static files. nginx is very good at serving static files but can't run python code. See how they work together? Here's another way to think about it. Take a look sometime at the number of requests a browser makes to a simple Django website that maybe has 10 images on it, 5 CSS files, and 5 JS files. The initial request fetches dynamic content and the python code, but then there are 20+ (!!) other requests that fetch all the static things. So in that case, only 5% of your requests need to run in gunicorn and the rest of them should be handled by nginx directly. If you did the bad thing and just let gunicorn handle it all then you'd need to provision x20 the resources for gunicorn to make your site have good response times under load! That's because you'd be handling x20 the connections just to serve static files. Therefore, every good sysadmin puts gunicorn behind nginx or apache or some other proxy technology. It says "Let the frontend server (nginx, apache, CloudFront, CDN, etc) do the easy task of serving up files from /static, and send everything else to the backend server (gunicorn) for the hard part of generating dynamic content." Now, you setup your nginx and gunicorn properly as far as I can tell. The only bad thing you did was talk to gunicorn directly instead of going through the nginx proxy like you should have. On Fri, Feb 21, 2020 at 11:49 AM Robert F. <robert.flaug...@gmail.com> wrote: > > > On Thursday, February 20, 2020 at 8:52:31 AM UTC-8, Stephen J. Butler > wrote: >> >> Django only serves up static files itself when run using runserver. This >> is meant for development and not production use. When you run it through >> gunicorn the Django framework won't serve up static files. That's why you >> connections to :8000 (gunicorn directly, bypassing nginx) don't work right. >> >> For running in production/gunicorn you need to run "collectstatic" after >> changes, and connect to nginx (probably port 80/443) so that the >> "location/alias" block works as intended and you get your static files. >> >> >>> I understand what you're saying but I don't understand specifically what >>> it is that I'm doing wrong. Should I not start Gunicorn with ":8000"? Do >>> I need to modify my Nginx configuration file? I don't quite see how all of >>> these pieces work together and which piece (or pieces) are wrong. Thanks. >> >> -- > You received this message because you are subscribed to the Google Groups > "Django users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-users+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-users/f1cd8e78-17ae-47c0-91e8-732a52ccccc9%40googlegroups.com > <https://groups.google.com/d/msgid/django-users/f1cd8e78-17ae-47c0-91e8-732a52ccccc9%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAD4ANxWga%2BXA4N%2BYTBxG9spDLUpXdcK3g9o0s2C54tdfpFZrGQ%40mail.gmail.com.