Assumption –
Server – Ubuntu 14.04 with non-root user and sudo access (user django in this example)
Setup django project –
Clone/copy your django project in home directory. in this example I am putting it in /home/django/myproject (myproject is django project directory)
Install virtualenv –
To keep python dependencies for different projects separate we use tool called virtualenv. It create virtual environment for your project and keeps all dependencies required by it in separate place. This helps us to use different versions of packages in different projects without any effect on global python site-packages.
To install virtual environment type below command on console and hit return key –
$ pip install virtualenv
Now virtualenv is installed, lets see how create virtual environment.
Create new virtualenv –
Go to your project directory. And run below command.
$ virtualenv
Here is the name of the environment. It can be anything of your choice. virtualenv will create folder named in current directory where Python executable, pip and all packages installed will be saved.
Which python executable to use ? – Currently there are 2 main virsions of python python2 and python3. While creating the virtualenv you can give path of python executable of your choice.
$ virtualenv -p /usr/bin/python3.4
If path is not provided global python interpreter will be used. We have created virtual environment with python3.4. To start using it we need to activate it.
$ source /bin/activate
Here is the name of virtual environment. After this you can install required dependencies in this vrtualenv. I am assuming that all project dependencies are in requirements.txt file which is general practice.
pip install -r requirements.txt
Create DB and configure it in settings.py file – After all the dependencies are installed you can create the DB and configure it in settings.py file.
Run migrations – Assuming that all your migrations are tracked using git or any other VCS, You can apply them directly to DB by running command –
python manage.py migrate
After this load fixtures if any by running loaddata command –
python manage.py loaddata
Now at this step your django project is setup on server and running. Lets move to gunicorn part –
Install gunicorn – install gunicorn if its not already done through requirements.txt
pip install gunicorn
Mozilla circus – circus is used to supervise the gunicorn workers and make sure gunicorn is up and running. Install it using below command.
pip install circus
Create circus.ini configuration file – Below is sample circus.ini configuration file. Create it in /home/django directory with below contents. Check comments for more info.
[circus] check_delay = 5 endpoint = tcp://127.0.0.1:5555 pubsub_endpoint = tcp://127.0.0.1:5556 statsd = true [watcher:myproject] working_dir = /home/django/myproject # your project directory # gunicorn command and arguments myproject.wsgi is wsgi file for django app cmd = gunicorn args = -w 3 -t 60 --pythonpath=. -b 127.0.0.1:8000 myproject.wsgi uid = django numprocesses = 1 autostart = true send_hup = true stdout_stream.class = FileStream stdout_stream.filename = /home/django/logs/gunicorn.stdout.log stdout_stream.max_bytes = 10485760 stdout_stream.backup_count = 4 stderr_stream.class = FileStream stderr_stream.filename = /home/django/logs/gunicorn.stderr.log stderr_stream.max_bytes = 10485760 stderr_stream.backup_count = 4 [env:myproject] # IMP - add your virtual envirnments bin directory path here PATH = /home/django/myproject//bin:$PATH TERM=rxvt-256color SHELL=/bin/bash USER=django LANG=en_US.UTF-8 HOME=/home/django # site packages path of your virtual env PYTHONPATH=/home/django/myproject//lib/python3.4/site-packages
Create ubuntu service for circus to make sure circus is up and running on server startup – Create a file in /etc/init with name circus.conf and copy below contents in it. Make sure path to circus.ini is correct.
start on filesystem and net-device-up IFACE=lo stop on runlevel [016] respawn exec /usr/local/bin/circusd /home/django/circus.ini
At this point your django project should be running on port 8000. Now lets install nginx and reverse proxy it to gunicorn for dynamic content. All the static content like django media files and static files will be served by nginx directly. This will reduce the load on gunicorn.
sudo apt-get install nginx
Create virtual host file for site in /etc/nginx/sites-available directory. I am naming it as my-django-site. Put below contents in the file.
server { listen 80 default_server; server_name _; large_client_header_buffers 4 32k; client_max_body_size 50M; charset utf-8; # make sure you have created these directories access_log /home/django/logs/nginx.access.log; error_log /home/django/logs/nginx.error.log; # Main site location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8000; proxy_redirect off; } # Django admin access (/admin/) location /admin { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Scheme $scheme; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8000$request_uri; proxy_redirect off; } # Static files location /static { alias /home/django/myproject/static; } # Media files location /media { alias /home/django/myproject/media; } }
Create symlink to site in etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/my-django-site /etc/nginx/sites-enabled/my-django-site.
Now restart nginx and your site will be available at http://www.example.com. Make sure port 80 is open and accessible externally.
Very useful information.
Thanks for Sharing this.
LikeLike