Configuring Completely Fresh Ubuntu 12.04 Server for Django Apps

Are you configuring a completely fresh Ubuntu 12.04 server, in particular by using Amazon Web Services EC2 servers? Well here is some good flow for setting it up in a somewhat principled manner.  This info is compiled from here and here and here, as well as my own notes from setting up an earlier Ubuntu box.  Feel free to contact me (check the about)!

Considering we are already super user, start with the basics:

sudo apt-get update

sudo apt-get upgrade

Install build essential to get some good libraries for compiling other libraries:

sudo apt-get install build-essential

Amazon Web Services already locks down specific ports, and yes it requires that key-pair file, but that SSH port will still gets pinged.

So now a security daemon (pun intended) that monitors and blocks suspicious login attempts:

apt-get install fail2ban

Get Apache:

sudo apt-get install apache2-mpm-worker apache2-dev

Get Python Dev

apt-get install python python-dev python-setuptools

Get Pip, VirtualEnv, VirtualEnv Wrapper:

sudo easy_install virtualenv virtualenvwrapper pip

Now modify the bashrc file:

vim ~/.bashrc

and add the following for the virtualenvwrapper:

# Virtual Env Wrapper Initializer and Settings
if [ `id -u` != ‘0’ ]; then
export VIRTUALENV_USE_DISTRIBUTE=1        # <– Always use pip/distribute
export WORKON_HOME=$HOME/.virtualenvs       # <– Where all virtualenvs will be stored
source /usr/local/bin/virtualenvwrapper.sh
export PIP_VIRTUALENV_BASE=$WORKON_HOME
export PIP_RESPECT_VIRTUALENV=true
fi

as well as:

export PYTHONPATH=/usr/local/lib/python2.7:$PYTHONPATH

Let’s now get git, but first get some of its dependencies:

sudo apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev

And now get git:

sudo apt-get install git

Let’s use git now to grab a vimrc file (mine in this case) so vim is better! Clone it and move the vimrc to ~/.vimrc and the directories to ~/.vim/

git clone https://github.com/aburnap/Vim-Config.git

Next, install mod WSGI so python can talk with our server.  The latest release as of this writing is 3.4, but check here to see if it’s later and change the link accordingly.

We start by first getting the installation package, and then unpacking it.

wget http://modwsgi.googlecode.com/files/mod_wsgi-3.4.tar.gz

tar xvfz mod_wsgi-3.4.tar.gz

Now configure, make, and make install it:

cd mod_wsgi-3.3

./configure

make

make install

Now add the load file for apache to here:

cd /etc/apache2/mods-available/

sudo vim wsgi.load

and add the line

LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so

Now activate the mod_wsgi with:

sudo a2enmod wsgi

Great, let’s check that apache is running by going to your site’s IP address at it’s root. You should be seeing the standard apache “it works” page, but now we have mod_wsgi enabled.

Ok now that we’ve seen it working, let’s remove the default page:

sudo a2dissite default

sudo service apache2 reload

Now we start getting the actual Django going. First reload the shell:

source ~/.bashrc

and create a virtualenv for Django and other packages your web app uses

mkvirtualenv <virtualenv name>

Let’s now get our Django app to the home directory.  Mine is on github in a private repo.  You can also transfer it with scp or sftp.

cd ~

git clone https://github.com/aburnap/<repo_name.git&gt;

Install all the package requirements of your django project in the current virtualenv with:

pip -r install requirements.txt

We now want the user that runs apache to be able to access the your Django app’s packages in the virtualenv.  For example with the AWS server, the username is “ubuntu”. To do this, run:

sudo chown -R <username>:<username> /home/ubuntu/.virtualenvs/<your_virtualenv_name>/lib/python2.7/site-packages

Now we need to make the WSGI file that the server points to:

cd /var/www

And create a file called “index.wsgi” here with the following.  Note that it points to the libraries used with our virtual environment, you’re might be different so check the location!

import os
import sys
import site

# Add the site-packages of the chosen virtualenv to work with
site.addsitedir('~/.virtualenvs/myprojectenv/local/lib/python2.7/site-packages')

# Add the app's directory to the PYTHONPATH
sys.path.append('/path/to/MyProject')
sys.path.append('/path/to/MyProject/myproject')

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

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

While we are here, make a static directory to host all your sites static files:
sudo mkdir static

Now configure the Apache server's virtual host for your website.  The default will be used otherwise, so first get to the sites-available directory:
cd /etc/apache2/sites-available

and make a file with your domain's name:
sudo vim <yourdomain>.conf
with the following contents (change to your settings)
<VirtualHost *:80>
        ServerName <yourdomain>.com
        ServerAlias www.<yourdomain>.com
        WSGIScriptAlias / /var/www/index.wsgi

        Alias /static/ /var/www/static/
        <Location "/static/">
            Options -Indexes
        </Location>
</VirtualHost>

And now we enable this new virtual host configuration with:
sudo a2ensite <yourdomain>.com

So to recap, we've installed Django and your app's required packages in a virtualenv.  The main Django app is located in the home directory.
We've setup apache2 as our server with mod_wsgi as our interface layer.  We've configured apache's virtual host to point our domain name to a custom wsgi script in /var/www, which itself points to the django app.
Our next step is to actually configure the settings.py file of the Django app!
cd ~/<app_name>/<app_name>/
sudo vim settings.py

and change:

STATIC_ROOT = '/var/www/static/'
Now that we've declared the location of the static directory, run the built in Django collector command to move all files there:
cd ..
python manage.py collectstatic

Don't use sudo for this operation, since we want to use the Django utilities in the virtualenv.
If you get a permission error like I did when copying, just temporarily change the permissions of the static director.
chmod 777 /var/www/static
and when you are done with collectstatic, change it back:
chmod 755 /var/www/static

Now navigate to your IP address in a web browser (or your domain if you've already assigned it to your IP).  It should be working!
If not, check the apache error logs with:
tail /var/log/apache2/error.log

For example, since I'm using sqlite3 as a database backend, I needed to install it:
sudo apt-get install sqlite3
and also set the permissions on my database for the apache user, as well as the path of the virtualenvs

chown ubuntu:ubuntu /path/to/database/database.db
chown -R ubuntu:ubuntu ~/.virtualenvs/<virtualenv_name>

as well as set the permissions on that folder to writable for the user (since sqlite stores its hidden journal file in the same directory)
chmod 755 /that/same/directory

Finally you might still have an error importing Django (if you check the error logs for apache).
In that case, add the WSGIPythonHome command to you apache config file:

cd /etc/apache2

add to the file httpd.conf

WSGIPythonHome /home/ubuntu/.virtualenvs/<virtualenv_name>



 

3 Comments on “Configuring Completely Fresh Ubuntu 12.04 Server for Django Apps”

  1. Steve says:

    Brilliant post. One of the best I found on the topic. There were a couple of gotchas along the way. Like this should be . But mostly it was bang on. Thanx a ton for taking the time to post.

  2. Ashok says:

    really best post . keep your articles churning out 🙂
    if your articles writing skills are so good and clear, then I am eagerly waiting for your next django articles


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s