Setting up Django on SliceHost with Ubuntu Hardy, Postgres, Apache, and Nginx

Friday, May 2nd, 2008
Step by step process of setting up Django on an Ubuntu Hardy slice at Slicehost.

This week I setup Django on a slicehost slice using Ubuntu Hardy for the OS, Postgresql for the db, Apache for serving the django app, and Nginx for serving the media and proxying to apache. For my future reference and hopefully to help out others here is the process I went through.

Slicehost has some easy to follow and straight forward articles to start I just followed along with the articles.

Setting up Ubuntu

Start with the Ubuntu Hardy setup - page 1. You can follow this guide straight through. The only complicated part is when you do the “visudo” command to add yourself to the sudoers it puts you in the “vi” editor which isn’t very intuitive if you’re not use to it. To add your user to the list go to the end of the

root    ALL=(ALL) ALL
line and type “a” to start appending. Then hit return and enter the line as described in the article. Once the line is entered hit “esc” to enter back into command mode then type “ZZ” to exit and save the file. If you want more info here is a reference to vi commands.

Then move onto page 2 Ubuntu Hardy setup -page 2. Again just follow along with this article the only item I had to change was the locale setting as I’m in the US not the UK. As Cody mentioned in the comments for the article instead of entering:

sudo locale-gen en_GB.UTF-8
...
sudo /usr/sbin/update-locale LANG=en_GB.UTF-8
I used the following:
sudo locale-gen en_US.UTF-8 
...
sudo /usr/sbin/update-locale LANG=en_US.UTF-8

Setting up DNS

At this point if you haven’t setup your dns you’ll to point to your slice you’ll want to do that within the slice admin interface. You’ll want at least two domains or subdomains one for the media files and one for the actual django application. In this case we are doing a “media.yourdomain.com” and “app.yourdomain.com”. If the django app is the website instead of the “app.yourdomain.com” you can setup a “www.yourdomain.com” and just use that anywhere we mention the “app.yourdomain.com”.

Installing Nginx

Currently Slicehost doesn’t have an article for installing Nginx on Ubuntu Hardy, but they do have one for Ubuntu Gutsy (the previous version of Ubuntu) which will work for our purposes. Follow along with the Ubuntu Gutsy - Installing Nginx from source. There is a newer version of Nginx now from when the article was written, so just go to the Nginx site and get the current stable version. I also wanted the config files in a different location than the default so in the article where it does the following command:

./configure --sbin-path=/usr/local/sbin --with-http_ssl_module
I did the following:
sudo mkdir /etc/nginx
./configure --sbin-path=/usr/local/sbin --with-http_ssl_module --conf-path=/etc/nginx/nginx.conf
This puts the config scripts in the /etc/nginx directory instead of the /usr/local/nginx/conf/ directory. This also more closely matches the setup you’d get if you installed nginx via aptitude and helprs for following along in later articles Once you’ve gone through the configure, make, install process edit the nginx.conf file
sudo nano /etc/nginx/nginx.conf
and change the following line in the http section:
include       /usr/local/nginx/conf/mime.types;
to be
include       /etc/nginx/mime.types;

At this point Nginx should be installed and working. Next we want to create the init script for it, and lucky for us Slicehost has an article covering this (again it’s for Ubuntu Gutsy, but it’ll work for Hardy) Ubuntu Gutsy - adding an nginx init script. No changes are needed for that article so just follow along.

Configuring Nginx

Follow along with the Slicehost article Ubuntu Gutsy - Nginx configuration #1. There is only one slight difference we need to change for this article. As the article assumes Nginx was installed by aptitude and not via source. At the bottom of the article it talks about the “include”, but our conf file doesn’t have an include. To fix this add the following line just below the gzip settings within the /etc/nginx/nginx.conf file.

include /etc/nginx/sites-enabled/*;
Some of you may noticed that we don’t a “/etc/nginx/sites-enabled/” directory, so let’s create that and a “sites-available directory.
sudo mkdir /etc/nginx/sites-available
sudo mkdir /etc/nginx/sites-enabled
This sets it up so that any virtual host config files within the /etc/nginx/sites-enabled folder will automatically be included.

Setting up the Media Virtual Host

Now we need to setup some virtual hosts for our site. To start with right now we’ll just setup the “media” virtual host, we’ll come back to the virtual host for our django site later. So follow along with the Ubuntu Gutsy - Nginx Virtual Hosts. The only change here is where the article uses the “domain1.com” place holder we want to use “media” for the folder and config file names and then the domain of “media.yourdomain.com” where “yourdomain.com” is the web domain for your application. You don’t need to setup the domain2.com examples unless you just want to test/try it out.

Apache Install

Once again follow along with the Slicehost article Ubuntu Hardy - installing Apache and PHP5. No changes are needed to this article, the only items is unless you need php for some of your sites you’ll want to stop when you reach the “PHP5 Install” part of the article.

Next follow along with the Ubuntu Hardy - Apache configuration #1 article. Change the default port from 80 to 8080

Listen 8080
I also commented out the listening on the ssl port as currently I don’t have SSL configured.

Reducing the timeout is recommended, but you’ll want to keep in mind if you have any long running scripts to ensure they have enough time to complete. As we are only using Apache for serving the Django app and no static content we want to turn off Keep Alive off to improve performance.

KeepAlive Off

Go through the additional configuration in Ubuntu Hardy - Apache configuration #2

Django Install

Slicehost also has an article on installing Django Ubuntu Gutsy - Django installation. I highly recommend you install Django from trunk unless you have a specific need for using the older aptitude version. One addition to this article is after installing subversion edit the subversion conf

sudo nano /etc/subversion/config
to add “pyc” files to the global ignore list. Uncomment the following line and add the “*.pyc” onto the end. I also use “local_settings.py” to hold the settings I don’t want in subversion so I add that to the list as well.
### Set global-ignores to a set of whitespace-delimited globs
### which Subversion will ignore in its 'status' output, and
### while importing or adding files and directories.
global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store *.pyc local_settings.py

After installing Django we’ll also want to add the admin media to our “media” site the easiest way to do this is with a symbolic link

ln -s /usr/lib/python2.5/site-packages/django/contrib/admin/media /home/demo/public_html/media/public/admin
(where “demo” is your user name)

Configuring Postgresql

In the above article Ubuntu Gutsy - Django installation. It took you through installing Postgres, but left it at that, we still need to setup some users, and create a database.

Setting up Postgres Users

The postgres install will create a “postgres” user by default that is the superuser for the database server. First thing we want to do is change the password for the “postgres” user this requires changing it within postgres and within the OS.

Changing the postgres users database password:

su postgres -c psql template1
template1=# ALTER USER postgres WITH PASSWORD 'password';
template1=\q
Where “password” is the new password.

Changing the postgres user OS password:

sudo passwd -d postgres
sudo su postgres -c passwd
...
It’s convenient to have the two passwords match, but not required.

Next create a postgres user for your login (this isn’t required but it can be convenient) at the command prompt enter:

sudo -u postgres createuser -P demo
where “demo” is your username. Answer the questions as it prompts you.

Now create a user for your django app to use for logging into the database. For this user don’t give it any of the super user, create db, create role, priveleges.

sudo -u postgres createuser -P django_login
where “django_login” is the username you’ll use to connect with from your django app. Remember the user name and password as we’ll use those in your django app’s settings.py file For more information on creating users you can refer to the Postgres documentation.

Create the Database

Now we need to create a database that our django app can use. Login into the psql interface

psql template1
Then at the psql prompt enter
CREATE DATABASE django_db OWNER django_login ENCODING 'UTF8';
This creates a database called “django_db” owned by “django_login” (change those values be what you want the database to be called and to the user you created in the previous step).

Configuring Access to the Postgres Server

Who can access the db server and from where is set in the /etc/postgresql/8.3/main/pg_hba.conf file, go ahead and open it up to edit. Postgres again has plenty of documentation on the file and how to set it up. For my case I only allow three users to access the database and all only from locally

local   all         postgres                          ident sameuser
local   all         demo                          ident sameuser
local   django_db    django_login                      md5
The first line you can leave as is as it lets the “postgres” user connect through the unix sockets. Then add the second line (again substituting your username for “demo”) so your user can access the system locally. Finally the last line is to allow your django application to access the system, where “django_db” is the name of the database you created in the step above and “django_user” is the user name you create earlier for your app to use.

Installing and Configuring your Django App

Create a directory for your Django site

mkdir -p /home/demo/public_html/app/{public,logs}
Upload or create your django project into the “/home/demo/public_html/app” folder. Also if you app depends on any other django applications or python libraries install those now as well.

Settings.py

Within your settings.py file you’ll need to set the database variables to the database info you created earlier. Here is an example using our example settings:

DATABASE_ENGINE = 'postgresql_psycopg2'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
DATABASE_NAME = 'django_db'             # Or path to database file if using sqlite3.
DATABASE_USER = 'django_login'             # Not used with sqlite3.
DATABASE_PASSWORD = 'password'         # Not used with sqlite3.
DATABASE_HOST = ''             # Set to empty string for localhost. Not used with sqlite3.
DATABASE_PORT = ''             # Set to empty string for default. Not used with sqlite3.

Set the MEDIA_ROOT:

MEDIA_ROOT = '/home/demo/public_html/media/public/'
Set the MEDIA_URL:
MEDIA_URL = 'http://media.yourdomain.com'
Set the ADMIN_MEDIA_PREFIX:
ADMIN_MEDIA_PREFIX = 'http://media.yourdomain.com/admin/'

SyncDB and Test

At this point your Django app should be able to create the database and work (not from the web yet, but from the commandline. Go into your django project directory and enter the syncdb command.

./manage.py syncdb

At this point you should be able to go into the shell

./manage.py shell
and interact with your app.

Configuring the Web Servers for Django

Now that your app is installed and working it’s time to configure Apache and Nginx to server the django app.

Apache/Django Config

Create a virtual host file for the django apache configuration

sudo nano /etc/apache2/sites-available/app
In that file put the following config:
NameVirtualHost *
<virtualhost>
        ServerAdmin webmaster@yourdomain.com

        DocumentRoot /home/demo/public_html/app/public
        <directory>
                SetHandler python-program
                PythonPath "['/home/demo/public_html/app', '/home/demo/public_html/app/yourproject'] + sys.path"
                PythonHandler django.core.handlers.modpython
                SetEnv DJANGO_SETTINGS_MODULE yourproject.settings
                PythonDebug On
                Options FollowSymLinks
                AllowOverride None
        </directory>

        ErrorLog /home/demo/public_html/app/logs/apache_error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /home/demo/public_html/app/logs/apache_access.log combined
        ServerSignature Off
</virtualhost>
Configuring it for your project. Enable this virtual site and restart apache.
sudo a2ensite app
sudo /etc/init.d/apache2 restart
Now the site should be running on apache port 8080 (which can’t be accessed outside the server unless you opened the port in the firewall).

Setting up Nginx Proxy

Create a virtual host config file for the site for Nginx

sudo nano /etc/nginx/sites-available/app
Put this into the file:
server {
  listen   80;
  server_name app.yourdomain.com;

  location / {
    proxy_pass      http://127.0.0.1:8080/;
    proxy_redirect  off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_set_header        X-Magic-Header "secret";

    client_max_body_size       10m;
  }
}
Basically this is saying anything that comes to app.yourdomain.com:80 forward to the apache instance running locally on port 8080. Save the file and then add it to the enabled sites and restart nginx.
sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
sudo /etc/init.d/nginx restart

All Done

That should be it, you should now be able to got to http://app.yourdomain.com/ and access your django project.

Read other entries about Django
Written by James Punteney
blog comments powered by Disqus