How to setup Django + mod_wsgi on Apache & Ubuntu

Django is a great Web Framework which complements the Python programming language. Having switched to Python development few months ago I was on the lookout for a MVC like Web Framework that emphasizes Convention over Configuration (CoC), Rapid Development Principle of Don’t Repeat Yourself (DRY), Separation of concerns has Python as the underlying core language. And lo and behold Django proved to be that beast.

What is Django

Django is a MVT (model-view-template) framework build on the Python language. The MVT is identical to MVC (model-view-controller) but where in the common MVC pattern the view here is the template and controller the view. They both perform the same function separating the business logic from the presentation from the data layer (model). However Django does goes one step further and provides a view/template without native core language polluting the HTML.

Django emphasizes Reusability and “Pluggability” of components, Rapid Development, and the Principle of DRY (Don’t Repeat Yourself). Stuff you hear a lot with Ruby on Rails – another great web framework built on a solid language, Ruby.

Ok, enough of my rambling about how great this framework is. If you want to read more about it I recommend the following 2 links:

The LAMP stack

Ok so everyone is talking about a LAMP stack and everyone wants to run their site on a LAMP stack. Why not when you can tap into great open source tools for free. The word LAMP is a bit over emphasised since most sites today run on a custom configured implementation using best of breed open source software.

“LAMP is an acronym for a solution stack of free, open source software, referring to the first letters of Linux (operating system), Apache HTTP Server, MySQL (database software) and PHP (or sometimes Perl or Python), principal components to build a viable general purpose web server” ~ Wikipedia

Few years ago when open source software was limited, LAMP had typically meant Linux, Apache, MySQL and PHP. Today Linux can take many flavours from CentOS, Red Hat or the popular Debian-derived Linux distribution Ubuntu. The web server Apache can be replaced with a super fast & lighter HTTP and reverse proxy server called nginx. MySQL, post Oracle acquisition is often replaced with PostgreSQL or a NoSQL version called MongoDB. And PHP by cleaner & concise languages like Python or Ruby.

In this post I will cover how to setup a LAMP stack where:

  • Linux = Ubuntu 11.10. This can also work with 10.xx version of Ubuntu.
  • Apache = we will leave it as is since it is still a great web server but hook in mod_wsgi – a Python WSGI adapter module for Apache. WSGI is nothing more than an interface specification by which server and application communicate. In this case with Python.
  • MySQL = will stay with MySQL but you can also install MongoDB.
  • PHP = will be replaced with Python and drop in the Django MVT framework.

Ok let’s get started.

How to Setup Django on Ubuntu

The following assumes you have already installed Ubuntu and LAMP. If not head over to my prior posts on how to:

  1. Install Ubuntu on EC2 and
  2. Install LAMP.

Installing pre-req components

1. Standard procedure is to always run update on your Ubuntu installation.

sudo apt-get update

2. Install mod_wsgi on Apache

sudo apt-get install libapache2-mod-wsgi

3. Install Python setup tools with pip. pip installs packages. Python packages. An easy_install replacement.

sudo apt-get install python-setuptools
sudo apt-get install python-pip

4. Install Django MVT framework using pip.

sudo pip install Django

Now that’s done. Easy hey. Now let’s configure your 1st Django site.
Assuming your site will be called “purpleblue.com

Configuring your 1st Django site

5. Recall from the LAMP setup that we were storing all web sites in /var/www/ folder. For example purposes, I will use purpleblue_com as my Django project. Notice the use of django-admin.py to create the Django site and the use of underscores vs decimal point. Only numbers, letters and underscores are allowed in the Django project name.

cd /var/www/
sudo django-admin.py startproject purpleblue_com

5.1 Verify new project by typing this in and hitting enter. ls lists the contents of a directory showing all files inc hidden ones, hence the -all option.

ls –all

If you see purpleblue_com listed, then change directory to it.

cd purpleblue_com

and verify you can see 4 .py files – init, manage, settings & urls. Those are Django new project default install files.

6. Now we create a wsgi file for the site so apache knows how to run this site.

sudo mkdir /var/www/purpleblue_com/apache
sudo nano /var/www/purpleblue_com/apache/django.wsgi

… and add this into django.wsgi

import os
import sys

path = '/var/www/purpleblue_com'
if path not in sys.path:
    sys.path.insert(0, '/var/www/purpleblue_com')

os.environ['DJANGO_SETTINGS_MODULE'] = 'purpleblue_com.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

TIP: It’s always a good idea to specify the actual application module.

6. Using webmin (ref our LAMP install) setup new apache site for this project.

6.1 Go to: https://YOUR_DEV_VM_IP:10000/
6.2 Servers > Apache Webserver > Create virtual host
6.3 Configure your new host
Document Root = /var/www/purpleblue_com/
Server Name = purpleblue.com
6.4 Click on “Create Now” button. And go back into the settings by clicking on “Virtual Server” button next to your new host.
6.4 Click on “Edit Directives” and paste the following in:

ServerName purpleblue.com
DocumentRoot /var/www/purpleblue_com

<Directory /var/www/purpleblue_com>
    Order allow,deny
    Allow from all
</Directory>

WSGIDaemonProcess purpleblue_com processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup purpleblue_com

WSGIScriptAlias / /var/www/purpleblue_com/apache/django.wsgi

The last 3 lines above allow this Django site to run in daemon mode.

TIP: When you make any .py changes in your Django site, rather then restarting/refreshing apache you can touch this wsgi and the changes will be picked up.

sudo touch /var/www/purpleblue_com/apache/django.wsgi

7. Restart apache to take new site & settings into effect.

sudo /etc/init.d/apache2 restart

8. Add the new domain purpleblue.com to your primary OS host file pointing to your VM where the Django project purpleblue_com resides.

9. Test your new project by going to the Server Name (http://purpleblue.com) you just setup. You should see a similar default Django installation page:

It worked! Congratulations on your first Django-powered page.

If you get an error or cannot see the default Django installation page make sure you check out apache log file. Common approach is to grab the tail end of the apache error log file to see what just happened.

tail /var/log/apache2/error.log

Bonus – Django CMS

If you have the time also check out Django CMS that is built on top of the Django Web Framework.

Django CMS site: https://www.django-cms.org/

Happy Django exploring & Python coding!

References

Building an Ubuntu LAMP Web Server

Recently I was setting up my Mac OS X with a kick ass development environment and jotted down all the cool steps I took to build an Ubuntu LAMP web server in a virtual machine environment. Here is this in-depth guide translated from paper to this digital copy. Hope you find this guide valuable and it saves you time when you need to do the same.

LAMP (Linux, Apache, MySQL and PHP)

Ubuntu Server

The flavor of Linux I like to use as a Web Server is Ubuntu.

What is Ubuntu

Ubuntu , is a secure, intuitive operating system that powers desktops, servers, netbooks and laptops. It is based on the Debian GNU/Linux distribution. Ubuntu is also named after the Southern African ethical ideology Ubuntu (“humanity towards others”) and is distributed as free and open source software with additional proprietary software available.

Why Ubuntu

  1. Reduce costs – free to use with no licensing fees.
  2. Visualization – it runs beautifully & fast in any VM environment (esp. Mac OS X)
  3. Build-in security – tight security, inbuilt firewall and encryption.
  4. It based on a Debian Distribution. A computer operating system composed of software packages released as free and open source software especially under the GNU General Public License and other free software licenses. Debian distributions are slower to release but this means they are extremely thorough.
  5. A lot of the big boys use Ubuntu. See case studies here: http://www.ubuntu.com/business/case-studies

Step by Step – your 1st web server

This guide assumes you have already installed Ubuntu Server. If not, go here and do it first. I recommend you install Ubuntu Server in a VM. I use VMware Fusion to run my instances when developing and Amazon EC2 for production. This guarantees that whatever I do locally in a VM will be compatible when pushed into production.

Ubuntu Server in a VMware Fusion

Goal:

  • Install LAMP – Linux (already done), Apache (web server), MySQL (mysql) and PHP (code compiler).
  • Install Webmin – a web-based interface for system administration for Unix.
  • Allow WWW for sFTP so you can remotely manage your website using a GUI.
  • Setup access to MySQL using MySQL Workbench.

1. Install LAMP

  • SSH into your box as root on Port 22 (default post install).
  • Update your OS software (just in case you are missing some dependencies):
    sudo apt-get update
  • From the terminal window, install LAMP using this 1 line of code (the caret (^) must be included):
    sudo apt-get install lamp-server^
  • The apt package manager will display what it is installing and ask you a bunch of standard questions. Just say yes to all. You will also be asked for a password for your new MySQL database. Type that in and note this down for future.
  • When this finishes you are done. Easy hey! Port 80 (default web server port) is now enabled and pointing to ‘/var/www’. ‘/var/www’ is where your site(s) should be placed.
  • Hit the Public DNS URL of your server (typically your IP) to verify that it’s up. It should show up a page with “It works!” If you are not sure what your box’s IP is, type this in and hit enter (similar to ipconfig on a Windows box).
    ip route
  • Before moving to the next step, you may want to know information about PHP’s configuration inc. installed extensions. You can grab this by creating a PHP file from your terminal window like this:
     sudo nano /var/www/phpinfo.php

    then adding this into it, save it, and quit nano (the editor your in):

    <?php phpinfo(); ?>

    restart Apache:

    sudo /etc/init.d/apache2 restart

    Hit the IP in your browser again with this new file name appended to the end eg. http://170.10.105.110/phpinfo.php – it should show you what is running.

2. Install Webmin

  • Edit “/etc/apt/sources.list” to add 2 new source:
    sudo nano /etc/apt/sources.list
  • … add these 2 new lines to the end, save and exit:
    deb http://download.webmin.com/download/repository sarge contrib
    deb http://webmin.mirror.somersettechsolutions.co.uk/repository sarge contrib
  • Now you can run this in your terminal window to install Webmin.
    sudo apt-get update
    sudo apt-get install webmin
  • Webmin should now be accessible from your browser using the server’s ip address followed by port 10,000 eg. https://170.10.105.110:10000
    Note that you do not have HTTPS cert so your browser will throw a warning since https is (and has to be) the protocol. Ignore it and move forward.
  • If you cannot login with your sudo account you may need to enable root. Follow the steps outlined here: https://help.ubuntu.com/community/WebminWithoutARootAccount
  • Or you can change the password of the root user in your terminal window. Then restart webmin.
    sudo /usr/share/webmin/changepass.pl /etc/webmin/ root foo
    sudo /etc/init.d/webmin restart
    
  • If you need to restart webmin run this:
    sudo /etc/init.d/webmin restart

3. Allow WWW for sFTP

  • You need to make sure the group www-data is added to “/var/www”. Run this in your terminal window:
    sudo chgrp www-data /var/www
  • Make “/var/www” writable for the group.
    sudo chmod 775 /var/www
  • Set the GID for www-data for all sub-folders.
    sudo chmod g+s /var/www
  • Your directory should look like this on an ‘ls -l’ output.
    drwxrwsr-x    root www-data
  • Last, add your user name to the www-data group (secondary group) where USERNAME is the “new” username you will use to sFTP. Note that we follow it by “passwd” to give new account a password.
    sudo useradd -G www-data NEW_USERNAME
    sudo passwd NEW_USER

    OR if the username is “existing” one use the command below. Also don’t forget to add “ubuntu” user if you have set this up on an EC2:

    sudo usermod -a -G www-data EXISTING_USERNAME
  • You should now be able to SFTP to your server using this USERNAME and upload data to “/var/www” with no problems.

4. Access to MySQL using MySQL Workbench

  • MySQL Workbench is a nice free GUI tool by the folks at mysql.com to manage your MySQL database. It can be downloaded from here: http://wb.mysql.com/
  • By default MySQL listens on localhost (127.0.0.1) so if you are going to manage your Ubuntu VM instance from say OS X, MySQL wont allow you entry. Here’s what to do to grant remote management of MySQL.
    1. Go to Webmin and login.
    2. In Webmin, navigate here: Servers > MySQL Database Server > MySQL Server Configuration
    3. Change “MySQL server listening address” to “Any”. By default it is 127.0.0.1. Save this.
    4. Now navigate here: Servers > MySQL Database Server > User Permissions
    5. Click on User “root” on the line where it says 127.0.0.1. And under Hosts change it to “Any”. This set the permissions on your db access.
    6. Save & Restart MySQL and you are done.
  • Remember that this is for “development” purposes only. You would not be allowing “Any” to your DB rather a specific static address and username.

5. Bonus – running multiple web applications on the LAMP instance

To save on time, money and managing multiple boxes, you may want to run multiple websites from this same box. I like to do this using ports as the separator. The following can be done in Webmin:

  1. Upload code to /var/www/mynewsite/
  2. Create a Virtual host for your new web application by navigating to:
    Servers > Apache Webserver > Create virtual host
  3. Fill out the form pointing ‘Document Root’ to the location of your code and assign a ‘Port’ number eg. 81, to this new host. Remember port 80 is your default.
  4. Save and click on ‘Apply Settings’ (link top right of the Webmin interface).
  5. Finally you need to tell Apache to listen to this new port. Navigate here:
    Servers > Apache Webserver > Global configuration > Networking and Addresses
  6. Add port 81 (where your new host is configured on) to ‘Listen on addresses and ports’.
  7. Save, apply changes and restart Apache.
  8. Done. You can now access your website via http://IP_DNS:81

Now go and build kick ass products!

There you have it folks. How simple is that. That’s why I love Ubuntu so much. It’s simple and powerful all under the 1 umbrella. That’s how software should be. All the complexities removed so us engineers can get to work and build kick ass products!

If you found this post useful let me know in comments section below. Super!!

~ Ernest