There are 3 ways to run a django application with gunicorn:
Standard gunicorn
+ wsgi
(ref django doc)
gunicorn project.wsgi:application
Using gunicorn django integration (ref gunicorn doc and django doc):
python manage.py run_gunicorn
Using gunicorn_django
command (ref gunicorn doc)
gunicorn_django [OPTIONS] [SETTINGS_PATH]
Django's documentation suggests using 1., which is not even listed as an option on Gunicorn documentation.
Is there any best practice on the best way to run a django app with gunicorn, and what are the foreseable advantages/disadvantages of these different solutions?
Taking a glimpse at gunicorn's code it looks like they pretty much all do the same: 2. seems to be creating a wsgi app using django's internals, and 3. uses 2.
If that's the case, I wouldn't even understand what's the reason for not simply using "1." all the time, especially since a wsgi.py
file is autocreated for you since django 1.4; if that's true maybe simply a documentation improvement should be suggested...
Also, best practice for gunicorn settings with django would be great. Using 1., does it make sense to set some defaults in the wsgi file and avoid additional settings?
gunicorn -c configfile
and configfile will point to django_settings to djangowsgi.py
is used only with 1.Gunicorn is a WSGI server This way, when coding up your a Django application you don't need to find your own solutions for: communicating with multiple web servers. reacting to lots of web requests at once and distributing the load. keepiung multiple processes of the web application running.
Running Django in Gunicorn as a generic WSGI application This will start one process running one thread listening on 127.0. 0.1:8000 . It requires that your project be on the Python path; the simplest way to ensure that is to run this command from the same directory as your manage.py file.
Running a local server of Django is not a recommended way in production because it's just a test server not a production ready server. So to run Django in production is to run with Gunicorn and use Nginx as a reverse proxy so it gives more security to our application.
Gunicorn relies on the operating system to provide all of the load balancing when handling requests.
After checking out I'd say that the best way is using gunicorn
+ wsgi
$ gunicorn project.wsgi:application
It's now both confirmed in gunicorn docs: if you run Django 1.4 or newer, it’s highly recommended to simply run your application with the WSGI interface using the gunicorn command and django as linked above.
It also avoids adding gunicorn as installed app, which means it's not a requirement to install gunicorn to test your app which might be useful from time to time.
About Settings
The Django settings file to be used can be passed through an ENV variable, or customized in the wsgi.py
file. I sometimes create several wsgi.py
files if I have multiple settings (eg. multiple websites) that have to run from the same project - See Django Doc for more info.
A one-liner solution that does not require any new file from Carl's comment:
DJANGO_SETTINGS_MODULE=project.settings.prod gunicorn project.wsgi:application
sounds like a nicer way (though I'll probably end up writing it in some shell commands to make it easy to "remember").
Gunicorn settings can be passed as -c settings_file
, but I'm exploring other ways and will try to update this answer if I find any. Using environment variables seems a workaroud, but only for limited cases
In particular it would be nice to get/share some settings between django and gunicorn; gunicorn documentation says:
Currently, only Paster applications have access to framework specific settings. If you have ideas for providing settings to WSGI applications or pulling information from Django’s settings.py feel free to open an issue to let us know.
(Update: haven't found any smarter way, but after all env variables are enough for my most-common cases).
I guess using run_gunicorn
is the way to go, it's also the simplest way to use it.
It's basically the same as usign gunicorn project.wsgi:application
but needs gunicorn to be added to INSTALLED_APPS
so that django recognizes the run_gunicorn
command, therefore it's probably not the default way...
Using gunicorn_django
is more or less deprecated, as the documentation also states here...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With