Skip to content

Instantly share code, notes, and snippets.

@panuta
Last active October 11, 2016 10:41
Show Gist options
  • Save panuta/04dc95b7661043ca734b59ab12e36436 to your computer and use it in GitHub Desktop.
Save panuta/04dc95b7661043ca734b59ab12e36436 to your computer and use it in GitHub Desktop.
Deploy Django application with virtualenv on Ubuntu Server 16.04 using Nginx and uWSGI

Fix locale problem

Open file /etc/default/locale to add or change LC_ALL to the following

LC_ALL="en_US.UTF-8"

Then logout and login again. (I've tried to find a better way to do this but failed. If you can, please tell me.)

Install necessary packages

Update aptitude

$ apt-get update
$ apt-get upgrade

Install necessary packages

$ apt-get install build-essential

Install Python

$ apt-get install python2.7-dev python-setuptools
$ easy_install pip

Setup Git

Install git

$ apt-get install git-core

Generate a new SSH key

$ ssh-keygen -t rsa -C "[email protected]"

Then add the key from ~/.ssh/id_rsa.pub to your git provider website as a deployment key

Install Virtualenv

Install virtualenv

$ pip install virtualenv
  • I don't like using virtualenvwrapper in production server because I want to isolate everything for the web under one directory (in this case, all Python libraries).

Install Postgresql Server

Install Postgresql Server and Python library

$ apt-get install postgresql python-psycopg2 libpq-dev

Create a new database and database's user

$ sudo -u postgres createdb [database_name]
$ sudo -u postgres createuser -SDRP [database_user_name]

Config pg_hba.conf file (you may need to change postgresql version number)

$ vim /etc/postgresql/9.5/main/pg_hba.conf

Then add the following to pg_hba.conf file let database user authenticated using password

local [database_name] [database_user_name]  md5

Reload Postgresql server

$ service postgresql reload

Install nginx

Install nginx

$ apt-get install nginx

Install PCRE library (necessary for rewrite module, if you need it)

$ apt-get install libpcre3-dev

Install uWSGI

Install uWSGI

$ apt-get install uwsgi uwsgi-plugin-python

Configuration

Example website is example.com

Setup folder structure

Create folders

$ mkdir -p /web/example.com/
$ cd /web/example.com/
$ mkdir logs public_html source run

Get source code

$ cd /web/example.com/source/
$ git clone [repositoty clone url]

Set owner to www-data

$ chown -R www-data:www-data /web

Setup virtualenv

$ cd /web
$ virtualenv example.com

Config nginx

    $ cd /etc/nginx/sites-available
    $ vim example.com

Add the following configuration to the file

server {
    listen          80;
    server_name     $hostname;
    access_log /web/example.com/logs/access.log;
    error_log /web/example.com/logs/error.log;

    location / {
        uwsgi_pass      unix:///web/example.com/run/example.sock;
        include         uwsgi_params;
        uwsgi_param     UWSGI_SCHEME $scheme;
    }

    location /static {
        root   /web/example.com/public_html/;
    }
}

Then create a symlink to enable website

$ ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

Then you may want to delete default site

$ rm /etc/nginx/sites-enabled/default

It's also a good practice to enable Gzip compression on Nginx.

$ vim /etc/nginx/nginx.conf

Search for Gzip settings within the file and remove comment on the following settings

gzip_vary
gzip_types

Config uwsgi

$ vim /etc/uwsgi/apps-available/example.com.ini

Add the following configuration to the file

[uwsgi]
plugin = python
vhost = True
pythonpath = /web/example.com/source/example_project/
chdir = /web/example.com/source/example_project/
virtualenv = /web/example.com
wsgi-file = /web/example.com/source/example_project/config/wsgi.py
processes = 10
socket = /web/example.com/run/example.sock
chmod-socket = 664
chown-socket = www-data
vacuum = true
daemonize = /web/example.com/logs/uwsgi.log
logto2 = /web/example.com/logs/uwsgi.log

Then create a symlink

$ ln -s /etc/uwsgi/apps-available/example.com.ini /etc/uwsgi/apps-enabled/example.com.ini

Install python packages

Activate virtualenv

$ cd /web/example.com/
$ . bin/activate

Install python packages from your requirements.txt file

$ pip install -r requirements.txt

Setup Django

  1. Set necessary Django settings such as

     ALLOWED_HOSTS
     SECRET_KEY
     DATABASES
    
  2. (If applicable) Set DJANGO_SETTINGS_MODULE environment variable to point to production settings

     export DJANGO_SETTINGS_MODULE='config.settings.production'
    
  3. Migrate database

     $ python manage.py migrate
    
  4. Collect static and symlink to public_html

     $ python manage.py collectstatic
     $ ln -s [path_to_staticfiles] /web/example.com/public_html/static
    

If you're using django-compressor with offline mode on, you have to manually static files.

$ python manage.py compress

Restart server

$ service uwsgi restart
$ service nginx restart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment