How to deploy django with uwsgi and nginx using Ansible play book

Ansible is a scripting language mostly used to automate installing applications, deploying apps etc..

Why Ansible:

You may think why to learn a new language if I can do the same using shell scripts, well that's ok but in my opinion ansible doesn't take much time to learn and shell scripts could become complex as the projects scale up. You can read further details over here(https://news.ycombinator.com/item?id=6431552).

Before we start it's important that you have an overview of uwsgi and Nginx configurations to deploy a project. You can look over this(http://uwsgi-docs.readthedocs.org/en/latest/tutorials/Django_and_nginx.html) beautiful and simple docs.

Lets start:

1. Install ansible:

Recomended: pip install ansible

Archlinux: pacman -S ansible   Note: archlinux uses python3 as default so you need to create a file /etc/ansible/group_vars/all and paste:         ---         ansible_python_interpreter: /usr/bin/python2

Ubuntu:

sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install ansible

2. Check if it's working:

Create /etc/ansible/hosts file with

[server1]
your_server_ip_address_here

and execute: ansible all -m ping

you will get a response as pong. The above command executes ping over all servers to specify any group(specific servers) then execute: ansible server1 -m ping

3. Example ansible playbook.

Note: Here I assume Ubuntu 14.04 server and ssh permission to it.

Let's install vim over the server.

First provide the IP address in /etc/ansible/hosts file

[my_server]
my_server_ip_address

Now create a task file. Ansible uses yml language.

create script.yml and paste the following

---
- name: install vim package
  apt: name=vim state=latest force=yes

Now create a playbook which runs above created role over specified hosts:

create playbook.yml with the following

---
- hosts: my_server
  remote_user: root
  roles:
    - script

Now run:

ansible-playbook playbook.yml

The above script installs latest vim package with apt-get package manager.

4. Update your ubuntu server:

First, before updating we have to create grub file as some packages require it. So create update_ubuntu.yml file with

---
- name: check grub file  # task name
  shell: test -f  /boot/grub/menu.lst  # shell module is no different than executing a command in shell eg: /bin/sh
  register: grub_file  # store the result of a shell command in grub_file
  failed_when: False  # silently fail when there are errors

- name: update grub
  command: "sudo update-grub -y"  # different from shell module as this does not have access to variables like $HOME etc..
  environment:
    DEBIAN_FRONTEND: noninteractive  # suppress debconf questions
  when: grub_file.rc != 0

- name: update apt-packages
  apt: "upgrade=dist update_cache=yes"  # uses apt module to upgrade distribution

Now as before creating a playbook with required configs:

In playbook.yml:

---
- hosts: my_server
  remote_user: root
  roles:
    - update_ubuntu

5. Create Django project:

Create file django_project.yml and paste:

Note: project_name is provided in the playbook.yml file.

---
- name: Install required apt-packages
  apt: "name='{{ item }}' state=present force=yes"  # this is like looping through all the items provided and install each respectively.

  with_items:
    - python-dev
    - python-virtualenv
    - python-pip
    - openjdk-7-jre-headless
    - libjpeg8-dev
    - zlib1g-dev
    - libfreetype6-dev
    - liblcms2-dev
    - libwebp-dev
    - libtiff-dev
    - tcl-dev
    - tk-dev
    - python-tk
    - redis-server
    - git
    - ruby

- name: Creates directory
  file: "path=/home/{{project_name}} state=directory"  # similar to mkdir this creates directory given by project_name

- name: create virtualenv and install django in it
  pip: "name=django virtualenv=/home/{{project_name}}/env virtualenv_command=virtualenv"

- name: install a django project
  command: "/home/{{project_name}}/env/bin/django-admin.py startproject {{project_name}} chdir=/home/{{project_name}}/"

Now create playbook.yml file:

---
- hosts: my_server
  remote_user: root
  roles:
    - { role: django_project, project_name: 'mysite' }

run ansible-playbook playbook.yml

That's it, your django project is created.

6. Create templates for uwsgi, Nginx and supervisor

The supervisor is just a process control system like it starts or stops an instance. Here we control uwsgi service using su

Things that we need here are the configuration files, ansible uses jinja2 template for configurations.

First create uwsgi template:

create uwsgi.j2 file and paste:

[uwsgi]

chdir           = /home/{{project_name}}/{{project_name}}/
module          = {{project_name}}.wsgi
home            = /home/{{project_name}}/env

master          = true
processes       = 4
socket          = /home/{{project_name}}/{{project_name}}.sock
chmod-socket    = 666
vacuum          = true
harakiri        = 60
max-requests    = 5000

For running uwsgi in emperor mode we use supervisor.

Create configuration for supervisor, so create uwsgi_server.j2 jinja2 template and paste:

[program:uwsgi-runner]
stdout_logfile = /var/log/supervisor/uwsgi-runner-out.log
stderr_logfile = /var/log/supervisor/uwsgi-runner-err.log
logfile_maxbytes = 50MB
logfile_backups = 10
command = /usr/local/bin/uwsgi --emperor /etc/uwsgi/vassals

Now create nginx templates:

In nginx.j2 paste:

upstream {{project_name}} {
    server unix:///home/{{project_name}}/{{project_name}}.sock;
}

server {
    listen       {{ server_port }};
    server_name  {{ server_name }};
    charset     utf-8;
    client_max_body_size 75M;
    error_log {{nginx_error_log}};

    location / {
        uwsgi_pass  {{project_name}};
        include     uwsgi_params;
    }

    location /static {
        alias /home/{{project_name}}/{{project_name}}/static;
        expires 365d;
    }

    location /media {
        alias /home/{{project_name}}/{{project_name}}/media;
        expires 365d;
    }

    location /player/private/media/ {
       alias /home/{{project_name}}/{{project_name}}/media/;
    }

location /robots.txt { root /home/{{project_name}}/{{project_name}}/static/; }
location /favicon.ico { root /home/{{project_name}}/{{project_name}}/static/; }
}

In step 7 we create roles using these templates.

7. uWSGI and Nginx roles:

Create uwsgi_django_setup.yml file and include:

---

- name: Install python-dev
  apt: "name='python-dev' state=present force=yes"

- name: Install python-pip
  apt: "name='python-pip' state=present force=yes"

- name: install uwsgi
  pip: name=uwsgi

- name: Install supervisor

  apt: name=supervisor state=present force=yes
  when: is_installed.rc != 0

- name: Create UWSGI vassals directory
  file: "path={{vassals_dir}}  state=directory"

- name: setup uwsgi in supervisor
  template: "src=uwsgi-server.j2 dest={{supervisor_conf_dir}}/uwsgi-runner.conf"

- name: update supervisor
  supervisorctl: name=uwsgi-runner state=restarted

- name: setup project uwsgi configuration file
  template: "src=uwsgi.j2 dest=/home/{{project_name}}/{{project_name}}_uwsgi.ini"

- name: create a symlink of uwsgi in vassals
  file: "src=/home/{{project_name}}/{{project_name}}_uwsgi.ini dest=/etc/uwsgi/vassals/{{project_name}}_uwsgi.ini state=link"

- name: touch the symlink file
  command: "touch /etc/uwsgi/vassals/{{project_name}}_uwsgi.ini"

Nginx Django setup role:

create file nginx_django_setup.yml and paste:

---

- name: Install nginx
  apt: "name='nginx' state=present force=yes"

- name: copy nginx config of project
  template: "src=nginx.j2 dest={{nginx_conf_dir}}/{{project_name}}.conf"

- name: copy nginx conf from sites-available to sites-enabled
  file: "src={{nginx_conf_dir}}/{{project_name}}.conf dest={{nginx_sites_dir}}/{{project_name}}.conf state=link"

- name: create project log directory
  file: "path=/home/{{project_name}}/logs state=directory"

- name: start nginx
  service: "name=nginx state=started"

Finally, create a playbook.yml:

---
- hosts: my_server
  remote_user: root
  roles:
      - { role: uwsgi_django_setup, project_name: 'mysite'}
      - { role: nginx_django_setup, project_name: 'mysite' }

Run ansible-playbook playbook.yml, your project will be deployed.

Note: We have hosted these scripts over ansible galaxy. You can pull using:

ansible-galaxy pull micropyramid.django

Posted On 11 January 2016 By MicroPyramid


Need any Help in your Project?Let's Talk

Latest Comments
Understand Deep Learning and how it works with a simple example

Deep Learning is a part of Machine Learning, it mimics the way our brains fundamentally work. We all know that our brain consists of billions …

Continue Reading...
Letsencrypt wildcard - Setup wildcard subdomain using letsencrypt and certbot

To get wildcard supported certificates, we need to pass the challenge which requires adding TXT records in your dns records.
To get certificates for single domains, …

Continue Reading...
Deploying Wordpress blog with Django using Docker Containers.

Containers run services in an isolated environment, if we deploy our applications using containers then the host system on which these containers are running will …

Continue Reading...
How to setup http password authentication with nginx

HTTP Authentication is used to allow access limit to a site or particular directories by validating the username and password. HTTP basic authentication can also …

Continue Reading...
Gitlab and Docker - Continuous Integration, Deployment and Continuous Delivery

In this blog post, we will learn how to setup and use gitlab container registry to implement, test build and deploy your code automatically with …

Continue Reading...
How to backup and restore mysql, postgresql and mongodb databases

Data loss can happen when we accidentally delete the files, or when server crashes or system fails, or when we applied migrations to the data …

Continue Reading...
Kubernetes Installation on BareMetal(Fedora)

Kubernetes manages containerized applications across multiple hosts. With years of experience in managing highly scalable products, google has released kubernetes an open source project which …

Continue Reading...
php7 hosting on Ubuntu Server with Nginx(LEMP stack)

PHP7 is the latest version with lot of performance improvements and every one want to update their servers and code to it. Lets see how …

Continue Reading...
Clustering of Docker Containers using Docker Swarm

There are many available ways of Docker clustering. Kubernetes, Docker cloud, Docker Swarm etc., In this Tutorial we will learn setting up a cluster using …

Continue Reading...
Setting Up Gitlab container Registry on own Domain.

GitLab Container Registry is a secure and private registry for Docker images integrated completely in Gitlab. In this tutorial we will setup and use GitLab …

Continue Reading...
HTTP2 and SPDY Protocols - Make HTTP Faster and Safer

HTTP/2, next version of HTTP/1, http/1 can not handle the present web which has become more resource intensive, it cannot processes multiple requests in an …

Continue Reading...
Understanding Logstash Parsing Configurations and options

In This Tutorial we will learn to customize Logstash to parse any type of Log Files. Logstash helps us to process logs and other event …

Continue Reading...
How to Deploy Django Project into Docker Container

Docker, has captured the hearts and minds of the Devops community, with its platform for delivering distributed applications in containers. In this Blog Post, Lets …

Continue Reading...
Django Testing Automated with Self Hosted Gitlab CI and Docker

It is a bit pricy if you want to host code for collaboration using bitbucket or github on your own VPS or On-Premisis servers. Gitlab …

Continue Reading...
How to deploy django with uwsgi and nginx using Ansible play book

Ansible is a scripting language mostly used to automate installing applications, deploying apps etc..
Why Ansible:
You may think why learn new language if I can do …

Continue Reading...
Setting Up Sentry - Web Application Event Tracking platform

When you want to track your exception and log mesages in a UI rather than storing it in a file(which we usually do), we can …

Continue Reading...
Configure SSL with LetsEncrypt and nginx

Configuring SSL is beneficial not only for security purpose but also for SEO too.
Linuxsoftware foundation's initiated a program called Let’s Encrypt to give ssl certificates …

Continue Reading...
Automate Django Deployments with fabfile

Fabric is a Python library and command-line tool with the ability to execute commands on a remote server. It is designed to use SSH to …

Continue Reading...
Ansible for Server Process Automation

Ansible is one of the few automation tools which uses an agentless architecture, where you dont need to install daemons in client nodes for interacting …

Continue Reading...
Ansible Galaxy Introduction.

Ansible Galaxy is the hub of ansible scripts contributed by users. To follow this article its important that you know about ansible. We have a …

Continue Reading...
Securing Elastic search Instance with Shield

Shield allows you to protect elastic search data with a username and password. It provides additional functionalities like encryption, role-based access control, IP filtering. It …

Continue Reading...
ELK Stack for Parsing your Logs- Part 2

In Previous Tutorial we looked into Setting up EL Server which can ingest your Syslog files. In this Post, you will learn about pushing your …

Continue Reading...
ELK Stack for Parsing your Logs

In This Tutorial we will look onto parsing your syslog files and store and display it in interactable website. We will be using ELK Stack …

Continue Reading...
Web Hooks for Gitlab using PHP and Shell Scripts

Web-hooks play vital role if you are in Continuous Integration(CI). Higher Level organizations follow GitLab for CI purposes if they operate on open source solutions …

Continue Reading...
Elastic Search Security Measures

After Installing Elastic Search in production, many new developers leave it unconfigured. In this Post, we will look into important config file changes and its …

Continue Reading...
Configuring WordPress Blog as sub-directory alongside Django in Nginx

Using regular expressions within Nginx we can bind urls to particular application servers, below we will configure wordpress blog and django site to be deployed …

Continue Reading...
How to Do Page Redirections with Nginx.

Here we learn how to redirect a www to non-www or vice-versa also we see how to redirect pages. We will see differences between 301 …

Continue Reading...
Basics of Linux File System Heirarchy

In 1994, FHS(File System Hierarchy Standard) was proposed, it describes the directory structure of UNIX and UNIX-like systems(Linux). Before FHS was proposed, there had been …

Continue Reading...
Postgresql Installation and management basics.

PostgreSQL or simply postgres is the most advanced, SQL-compliant and open-source objective-RDBMS. In This Article, you will learn how to Install, Connect and Manage a …

Continue Reading...
Fabric - Learning part1

Using Fabric, we can configure Linux production server with uwsgi, nginx, vsftpd, mysql, mongodb, postfix, php, python tools, and other relevant pieces of software single-handedly …

Continue Reading...
MySQL Setup and Security

In This Post you'll learn to install and secure your MYSQL Setup to interact with external applications.

Continue Reading...
TMUX - Sharing terminal between Users

More Often you wouldve come across sharing screens with applications like Teamviewer, Windows Remote Desktop Connection or remmina (if you're a linux user). But if …

Continue Reading...
Django hosting on Nginx with uwsgi for high performance

Quick guide to host django application using uwsgi and nginx which offers better resource utilization and performance.

Continue Reading...
Celery With Supervisor

Celery is a task queue with focus on real-time processing, while also supports task scheduling. Task queues are used as mechanisms to distribute work across …

Continue Reading...
Django on GAE (google app engine)

Google App Engine (often referred to as GAE or simply App Engine) is a platform as a service (PaaS) cloud computing platform for developing and …

Continue Reading...
Daemonizing any command with SUPERVISOR

Daemonizing a command means to make it run as a background process.

so when we have a command that we want to daemonize there are …

Continue Reading...

Subscribe To our news letter

Subscribe and Stay Updated about our Webinars, news and articles on Django, Python, Machine Learning, Amazon Web Services, DevOps, Salesforce, ReactJS, AngularJS, React Native.
* We don't provide your email contact details to any third parties