http://agiliq.com/blog/2013/08/minimal-nginx-and-gunicorn-configuration-for-djang/
We'll have a deploy a Django project with Nginx and Gunicorn.
It is easier for me to understand Nginx and gunicorn in development machine and then move to a publicly accessible server . So, we'll cover this post in a similar sequence: on development machine with Django ' s runserver to serve the sit E. Stop runserver and start using Gunicorn instead. ADD Nginx to this configuration. On server Deploy the project on a publicly accessible server using same stack.
Use runserver
We use a minimal project with two apps and few static files. Can view this project at GitHub.
Project structure:
|--manage.py |
| other_app | | --__init__.py
| | --models.py
| | --Static
| | '--Other_app
| | '--styles.css
| | --tests.py
| | --urls.py
| '--views.py
| | project_static | '--base.css | requirements.txt | |
some_app
| | --__init__.py
| | --models.py
| | --Static
| | '--Some_app
| | '--styles.css
| | --tests.py
| | --urls.py
| '--views.py | | --Other_app
| | '--home.html
| '--Some_app
| '--home.html
|-test.db
'--test_project
|-__init__.py
| settings.py
| test_ settings.py
|-
-urls.py '--wsgi.py
This project am started using django-admin.py startproject test_project, so this structure is inside folder Te St_project.
Cloning and trying it out would for you follow along, so go ahead and clone this project.
We assumption is this are working from the same level as manage.py.
Runserver and verify that you can access
Http://localhost:8000/some_app/home
Http://localhost:8000/other_app/home
The should have a red background and the second one should have a blue background.
This is project uses some static resources, should check we post on serving the static file if you are confused about Servin g static files during development. Stop runserver and start using Gunicorn
Stop the Django development server.
Make sure your have Gunicorn installed, else install it with
Pip Install Gunicorn
Gunicorn is a WSGI compliant server and your need to pass your application object to it. Should read about basics of WSGI If you are are not comfortable with WSGI.
Django provides an application object. The default structure provided by Django-admin Startproject gives a wsgi.py file which the contains. You are need to the application to Gunicorn.
Run Gunicorn Passing it the application:
Gunicorn test_project.wsgi:application
Note:in The recent Django versions the Wsgi file extension has been changed it is a Python module (EX:TEST_PROJECT_WSGI.P Y) and I can serve it with just module name like below
Gunicorn test_project:application
Refresh your page at http://localhost:8000/some_app/home. Your page should be served, however the red background must have.
Red background vanished because the static files (stylesheets) are not being served. They are is not being served because we don't have any URL pattern for/static/in urls.py. Earlier they were served because we were using Django development server, i.e Runserver, which does some magical the things Hind the scence to serve static files. Add Nginx to this configuration
Gunicorn is meant to serve dynamic content, it should not being used to serve static files. We'll add Nginx to serve static files.
We want to serve static files from the port 8000 and so it are required that Gunicorn listens on some port. Stop Gunicorn and run it on Port 8001.
Gunicorn test_project.wsgi:application--bind=127.0.0.1:8001
Now you are not being able to the your page at http://localhost:8000/some_app/home/. It is available on port 8001 at http://localhost:8001/some_app/home.
Make sure your have Nginx installed or install it with:
sudo apt-get install Nginx
Nginx acts as a reverse proxy here. All our request would initially come to Nginx. It's for Nginx to decide what requests it wants to serve and what the IT requests to the wants to the other server.
In our case, we are want Nginx to serve requests for the static and to the.
We need to tell nginx the location's our "our" and "for", "we need to" make sure all our static resources are At a single location. Run python manage.py collectstatic to collect all of the static resources at location specified by Static_root.
Set Static_root in settings.py:
Static_root = Os.path.join (Project_dir, '. /staticfiles/')
Run collectstatic:
Python manage.py collectstatic
You should this directory Staticfiles gets created at the same level as manage.py. All your static files must have got copied to this directory. Get the path of this directory, we need it in the alias directive of Nginx cofiguration.
Create a file/etc/nginx/sites-enabled/example and add following content to it.
server {
listen localhost:8000;
Location/{
proxy_pass http://127.0.0.1:8001;
}
location/static/{
autoindex on;
alias/home/akshar/staticvirt/test_project/staticfiles/
}
}
Your alias directive would differ from mine.
Make sure Nginx is running:
sudo service nginx restart
Nginx is listening to requests now.
Refresh page at http://localhost:8000/some_app/home/, the page should is visible with red background which conforms tha t static files are being served properly. Explanation: listen directive tells that Nginx was listening for no request that comes at localhost:8000. There are two location directives. Bottom location can overide top location. Bottom'll have preference over top. When a request starting with/comes, it being passed to Port 8001.
Eg:if request comes for Http://localhost:8000/some_app/home, Nginx tries to match it and one of the location defined in The configuration file. In this case, the it matches with the location. Nginx sees that "a proxy_pass is defined" it passes this request to the Proxy_pass which is http://127.0.0.1 : 8001. Gunicorn is listening in Port 8001, so Gunicorn would repond to this request. When a request starting with/static/comes, bottom location is used as it has to the top preference.
When a request comes for HTTP://LOCALHOST:8000/STATIC/SOME_APP/STYLES.CSS, Nginx looks into the directory pointed to by Al IAS which is staticfiles. It tries to find some_app/styles.css inside this directory and if this file is available then serves the file.
Now we are comfortable with serving Django sites with Nginx. Deploy on a publicly accessible server.
I'll use domain pythoninternals.com for illustration. We following things on the server where A record of domain pythoninternals.com points. \ need
We don ' t need any change for gunicorn and can run it same way:
Gunicorn test_project.wsgi:application--bind=127.0.0.1:8001
Create file/etc/nginx/sites-enabled/example on the server and add content:
server {
listen;
server_name pythoninternals.com;
Location/{
proxy_pass http://127.0.0.1:8001;
}
location/static/{
alias/home/ubuntu/staticvirt/test_project/staticfiles/
}
}
This file is almost similar to the Nginx conf we had on development machine.
Make sure this you have collected the static files in directory Staticfiles.
Some differences in this nginx conf and Dev Machine's nginx conf are:it ' s listening on port 80. When a request is made to domain pythoninternal.com, it comes on the default port which is 80. So, Nginx must is listening for no request on port 80. Server_Name makes sure that this configuration file'll only is used for pythoninternals.com. There might is another domain called abcde.com being served from this same server, we don ' t want Used for abcde.com. That ' s why we specify the server_name.
After this is a request for Pythoninternals.com/some_app/home would is served properly from this server.
Running Gunicorn The way we did, 'll keep it in the foreground and we'll have to stop gunicorn to exit from the server. So, we are need to run it as a daemon.
Run Gunicorn as Daemon:
Gunicorn test_project.wsgi:application--bind=127.0.0.1:8001--daemon
With this, Gunicorn runs as a background process and we can quit from the server without affecting.
Till Now, we are have set various configurations for Gunicorn, like--bind and--daemon, on the terminal. The suggested way to does it is using configuration file. You are should read about it and should move this configurations to a separate file.