<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7848112787715004355</id><updated>2011-04-21T12:20:29.904-07:00</updated><category term='apache'/><category term='memcached'/><category term='postgresql'/><category term='mod_wsgi'/><category term='ubuntu'/><category term='django'/><category term='nginx'/><title type='text'>Ethics Gradient</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ethics-gradient.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7848112787715004355/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ethics-gradient.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Paul Skarseth</name><uri>http://www.blogger.com/profile/04999064950288939413</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7848112787715004355.post-3800763897352259917</id><published>2009-02-24T02:40:00.001-08:00</published><updated>2009-02-24T03:31:50.218-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='memcached'/><category scheme='http://www.blogger.com/atom/ns#' term='nginx'/><category scheme='http://www.blogger.com/atom/ns#' term='mod_wsgi'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='postgresql'/><title type='text'>The Django and Ubuntu 8.04 Chronicle</title><content type='html'>This is my gift to you. I've spent the better part of a Jōmon Sugi tree's lifespan configuring servers and glancing with a raised eyebrow at the various nuggets of wisdom that people have decided to part with through the intertubes. Some of these do actually contain useful information, but most will actually end up doing you more harm than good. This is where I come in, the savior as it were, saving you from yourself and others.&lt;br /&gt;&lt;br /&gt;This guide revolves around deploying Django on Ubuntu 8.04 LTS (Hardy Heron), using PostgreSQL as the database, Nginx as a proxy server infront of Apache2 coupled with mod_wsgi, and Memcached as the cache back-end.&lt;br /&gt;&lt;dl id="top"&gt;&lt;dt&gt;&lt;a href="#general"&gt;General&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#users"&gt;Users&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#ssh-key"&gt;SSH Key&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#ssh-copy"&gt;SSH Copy&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#ssh-config"&gt;SSH Config&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#vim"&gt;.vimrc&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#bash"&gt;.bashrc and .bash_aliases&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#locales"&gt;Locales&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#update"&gt;Updates and Upgrades&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#firewall"&gt;Firewall&lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="#nginx"&gt;Nginx&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#nginx-install"&gt;Installation&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#nginx-config"&gt;Config&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#nginx-default"&gt;Default Site&lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="#apache"&gt;Apache&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#apache-install"&gt;Installation&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#apache-config"&gt;Config&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#apache-ports"&gt;Ports&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#apache-default"&gt;Default Site&lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="#postgre"&gt;PostgreSQL&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#postgre-install"&gt;Installation&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#postgre-config"&gt;Config&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#postgre-users"&gt;Users&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#postgre-admin"&gt;phpPgAdmin&lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="#memcached"&gt;Memcached&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#memcached-install"&gt;Installation&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#memcached-cmemcache"&gt;cmemcache&lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="#django"&gt;Django&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#django-install"&gt;Installation&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#django-default"&gt;Default Project&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#django-database"&gt;Database&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#django-config"&gt;Config&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#django-nginx"&gt;Nginx&lt;/a&gt;&lt;/dd&gt;&lt;dd&gt;&lt;a href="#django-apache"&gt;Apache&lt;/a&gt;&lt;/dd&gt;&lt;dt&gt;&lt;a href="#epilogue"&gt;Epilogue&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;a href="#epilogue-links"&gt;External Links&lt;/a&gt;&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="general" style="color: rgb(204, 102, 0);font-size:140%;" &gt;General&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;We'll be using Ubuntu, and specifically the 8.04 LTS (Hardy Heron) version, due to its ease-of-use and stability coupled with the more than adequate security measures for our needs. I'll update this document when the new 9.04 LTS (Jaunty Jackalope) version is released in April 2009. You can read more about Ubuntu on their &lt;a href="http://www.ubuntu.com/"&gt;site&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="users" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Users&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;After a clean install of Ubuntu 8.04, login via SSH:&lt;br /&gt;&lt;code&gt;$ ssh root@255.255.255.255&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Once logged in, the first thing you should do is to make an admin user that will have sudo rights, since the actual root user will ideally only be used during this initial stage. We will also make a dedicated django user.&lt;br /&gt;&lt;br /&gt;Make the users and create home folders.&lt;br /&gt;&lt;code&gt;# useradd -m paul&lt;br /&gt;# useradd -m django&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Create their passwords.&lt;br /&gt;&lt;code&gt;# passwd paul&lt;br /&gt;# passwd django&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Change the default shell from Bourne to Bash.&lt;br /&gt;&lt;code&gt;# chsh -s /bin/bash paul&lt;br /&gt;# chsh -s /bin/bash django&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Add your admin user, but not the Django user, to the sudo list. Include this at the end of the file.&lt;br /&gt;&lt;code&gt;# visudo&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:21 paul    ALL=(ALL) ALL&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="ssh-key" style="color: rgb(204, 102, 0);font-size:130%;" &gt;SSH Key&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;One of the most convenient and secure ways of accessing your server is through a public/private key scheme. This entails having a public key stored on the server and a private key on your local workstation, a benefit of which is that you don't have to supply your password when accessing your server through SSH.&lt;br /&gt;&lt;br /&gt;You might find that some of these steps are already completed on your local workstation, if that is the case, jump ahead to the "SSH copy" section.&lt;br /&gt;&lt;br /&gt;Open up a new terminal window in addition to the one already connected to the server; it is always wise to keep an open connection to your server throughout when configuring SSH. Create the .ssh directory on your &lt;span style="font-weight: bold;"&gt;local&lt;/span&gt; workstation and limit who has access to it.&lt;br /&gt;&lt;code&gt;localhost$ mkdir ~/.ssh&lt;br /&gt;localhost$ chmod go-rwx ~/.ssh&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Create the ssh keys on your &lt;span style="font-weight: bold;"&gt;local&lt;/span&gt; workstation.&lt;br /&gt;&lt;code&gt;localhost$ ssh-keygen -t rsa&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;That should give you two files in your ~/.ssh folder, id_rsa and id_rsa.pub. The .pub file is your public key and the one we will copy to your server, the other file is your private key and should never be shown, copied or otherwise distributed.&lt;br /&gt;&lt;br /&gt;&lt;span id="ssh-copy" style="color: rgb(204, 102, 0);font-size:130%;" &gt;SSH Copy&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Copy your public key to the server. Execute this command from your &lt;span style="font-weight: bold;"&gt;local&lt;/span&gt; workstation.&lt;br /&gt;&lt;code&gt;localhost$ scp ~/.ssh/id_rsa.pub paul@255.255.255.255:&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now log in to your server with the admin user, create the .ssh directory, set up authorized_keys and limit its permissions.&lt;br /&gt;&lt;code&gt;$ ssh paul@255.255.255.255&lt;br /&gt;$ mkdir ~/.ssh&lt;br /&gt;$ mv ~/id_rsa.pub ~/.ssh/authorized_keys&lt;br /&gt;$ chmod -R go-rwx ~/.ssh&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Reconnect to the server and verify that the keys are interacting, bypassing the password prompt.&lt;br /&gt;&lt;br /&gt;&lt;span id="ssh-config" style="color: rgb(204, 102, 0);font-size:130%;" &gt;SSH Config&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;People are generally incapable of agreeing on anything so there are a plethora of different suggestions as to how one should configure SSH on a server, but there are a few common threads we can adopt. One popular setting is to disable PasswordAuthentication, i.e. the only way a user can log in to the server is if he has an SSH key pair. This is more secure, but I tend to use a handful of different computers to access my servers and have a few guest accounts on them, so I opt to leave PasswordAuthentication on. Another security measure is to change the default SSH port of 22 to one of your chosing; there are a few reasons why this would be beneficial, but I will be using the default in this guide to strike a median between security and ease-of-use.&lt;br /&gt;&lt;br /&gt;First create a group which limits who can access your server through SSH.&lt;br /&gt;&lt;code&gt;$ sudo groupadd sshers&lt;br /&gt;$ sudo usermod -a -G sshers paul&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now edit the sshd_config file. You will have to add line 78 and 79 yourself.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/ssh/sshd_config&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:26 PermitRootLogin no&lt;br /&gt;line:62 X11Forwarding no&lt;br /&gt;line:77 UsePAM no&lt;br /&gt;line:78 UseDNS no&lt;br /&gt;line:79 AllowGroups sshers&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Reload the SSH daemon and reconnect to the server to verify that you still can. Remember to always have at least one active connection to the server throughout when configuring SSH, that way you won't accidentally lock yourself out.&lt;br /&gt;&lt;code&gt;$ sudo /etc/init.d/ssh reload&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="vim" style="color: rgb(204, 102, 0);font-size:130%;" &gt;.vimrc&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Include a few rudimentary settings for &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt;. This is a very small sample of what's &lt;a href="http://www.google.com/search?hl=en&amp;q=.vimrc"&gt;possible&lt;/a&gt;.&lt;br /&gt;&lt;code&gt;$ vim ~/.vimrc&lt;br /&gt;&lt;/code&gt;&lt;code&gt;" Use the latest&lt;br /&gt;set nocompatible&lt;br /&gt;&lt;br /&gt;" Better indent&lt;br /&gt;set autoindent&lt;br /&gt;set smartindent&lt;br /&gt;&lt;br /&gt;" Set tabs to represent 4 spaces&lt;br /&gt;set tabstop=4&lt;br /&gt;set shiftwidth=4&lt;br /&gt;set shiftround&lt;br /&gt;set expandtab&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="bash" style="color: rgb(204, 102, 0);font-size:130%;" &gt;.bashrc and .bash_aliases&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Create some very basic aliases. Feel free to improvise.&lt;br /&gt;&lt;code&gt;$ vim ~/.bash_aliases&lt;br /&gt;&lt;/code&gt;&lt;code&gt;alias ll='ls -lh'&lt;br /&gt;alias la='ls -alh'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Open .bashrc and activate the .bash_aliases file. Uncomment line 67, 68 and 69.&lt;br /&gt;&lt;code&gt;$ vim ~/.bashrc&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:67 if [ -f ~/.bash_aliases ]; then&lt;br /&gt;line:68     . ~/.bash_aliases&lt;br /&gt;line:69 fi&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Reload .bashrc to load the new aliases.&lt;br /&gt;&lt;code&gt;$ source ~/.bashrc&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="locales" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Locales&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Generate the necessary locales. This will of course vary depending on where you are located on the globe.&lt;br /&gt;&lt;code&gt;$ sudo locale-gen en_US.UTF-8&lt;br /&gt;$ sudo /usr/sbin/update-locale LANG=en_US.UTF-8&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="update" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Update and Upgrade&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Got to make sure that we have the latest and greatest upgrades. First update your local list of sources.&lt;br /&gt;&lt;code&gt;$ sudo aptitude update&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now install any eventual upgrades. Start with the safe-upgrade, then proceed to the full-upgrade.&lt;br /&gt;&lt;code&gt;$ sudo aptitude safe-upgrade&lt;br /&gt;$ sudo aptitude full-upgrade&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;These are some general programs and utilities that you'll more than likely need at least once in your journeys.&lt;br /&gt;&lt;code&gt;$ sudo apt-get install build-essential git-core python-dev&lt;br /&gt;$ sudo apt-get install python-setuptools python-psycopg2&lt;br /&gt;$ sudo apt-get install subversion rsync postfix&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="firewall" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Firewall&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;A new installation of Ubuntu 8.04 LTS is by default open on all ports from any source, which isn't exactly optimal in this Brave New World. We're going to use Ubuntu's own &lt;a href="https://wiki.ubuntu.com/UbuntuFirewall"&gt;Uncomplicated Firewall&lt;/a&gt; to configure our iptables to only accept connections from the default ports of HTTP, HTTPS and SSH. You might have to customize this to your liking, to include port 5432 for instance if you want to make your PostgreSQL database remotely accessible.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install ufw&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Enable ufw and turn on the logging feature.&lt;br /&gt;&lt;code&gt;$ sudo ufw enable&lt;br /&gt;$ sudo ufw logging on&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Allow access to the desired ports.&lt;br /&gt;&lt;code&gt;$ sudo ufw allow 22&lt;br /&gt;$ sudo ufw allow 80/tcp&lt;br /&gt;$ sudo ufw allow 443/tcp&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Deny everything else.&lt;br /&gt;&lt;code&gt;$ sudo ufw default deny&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Take a look at your newly configured iptables.&lt;br /&gt;&lt;code&gt;$ sudo iptables -L&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Reload the SSH daemon yet again and reconnect to the server one last time.&lt;br /&gt;&lt;code&gt;$ sudo /etc/init.d/ssh reload&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Finally, if all went well, disable password access to the root account.&lt;br /&gt;&lt;code&gt;$ sudo passwd -l root&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="nginx" style="color: rgb(204, 102, 0);font-size:140%;" &gt;Nginx&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://nginx.net/"&gt;Nginx&lt;/a&gt; is a light, but very fast and effective, web server which will act as a proxy to our Apache installation and serve static files.&lt;br /&gt;&lt;br /&gt;&lt;span id="nginx-install" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Installation&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install nginx&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="nginx-config" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Config&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Optimize Nginx and create a proxy.conf file. Modify the worker_processes and uncomment tcp_nopush.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/nginx/nginx.conf&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:2 worker_processes  4;&lt;br /&gt;line:18 tcp_nopush     on;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Create the proxy.conf file.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/nginx/proxy.conf&lt;br /&gt;&lt;/code&gt;&lt;code&gt;proxy_redirect          off;&lt;br /&gt;proxy_set_header        Host            $host;&lt;br /&gt;proxy_set_header        X-Real-IP       $remote_addr;&lt;br /&gt;proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;&lt;br /&gt;client_max_body_size    10m;&lt;br /&gt;client_body_buffer_size 128k;&lt;br /&gt;proxy_connect_timeout   90;&lt;br /&gt;proxy_send_timeout      90;&lt;br /&gt;proxy_read_timeout      90;&lt;br /&gt;proxy_buffers           32 4k;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="nginx-default" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Default Site&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Remove the default site displayed by Nginx. Reaching a point where the default page is displayed shouldn't be a terribly common event, but it might happen if using the IP of the server explicitly when browsing, opposed to the &lt;a href="http://en.wikipedia.org/wiki/Domain_name_system"&gt;DNS&lt;/a&gt; entry.&lt;br /&gt;&lt;code&gt;$ sudo rm /etc/nginx/sites-enabled/default&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="apache" style="color: rgb(204, 102, 0);font-size:140%;" &gt;Apache&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Apache is the most commonly used web server and the recommended way of serving Django sites in a production environment. There are a few brave souls experimenting with Nginx, lighttpd and various other solutions as the main web server, but Apache2 coupled with mod_wsgi is the preferred way of doing things. You can mozy on down to the Apache site &lt;a href="http://www.apache.org/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="apache-install" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Installation&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;A note to be made here is that we'll be using the libapache2-mod-wsgi package residing on the official repositories which is, as of this writing, version 1.3. The latest version of mod_wsgi is 2.3 and you can download it from &lt;a href="http://packages.debian.org/unstable/python/libapache2-mod-wsgi"&gt;here&lt;/a&gt;. The reason I opt to use the older version is that the main point of setting up an Ubuntu LTS server is to keep it stable and secure, not to run the latest, cutting edge software. You'll have to manually stop and start Apache after the installation to correctly set up mod_wsgi.&lt;br /&gt;&lt;code&gt;$ sudo apt-get install apache2 libapache2-mod-wsgi&lt;br /&gt;$ sudo /etc/init.d/apache2 stop&lt;br /&gt;$ sudo /etc/init.d/apache2 start&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="apache-config" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Config&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Towards the end of installing Apache you'll see this warning.&lt;br /&gt;&lt;code&gt;apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Apache loves FQDNs so let's do what any gallant administrator would do and satisfy its desire. Read more about FQDN &lt;a href="http://httpd.apache.org/docs/2.2/mod/core.html#servername"&gt;here&lt;/a&gt;. We'll also modify another setting while we're at it, making Apache play nice with the other children. You'll have to add line 300.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/apache2/apache2.conf&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:77 KeepAlive Off&lt;br /&gt;line:300 ServerName YourHostname&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="apache-ports" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Ports&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Make Apache listen locally, Nginx will act as the front-end web server. NameVirtualHost must be added by you.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/apache2/ports.conf&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:1 Listen 127.0.0.1:8080&lt;br /&gt;line:2 NameVirtualHost 127.0.0.1:8080&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="apache-default" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Default Site&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Lastly, remove the default site for the same reasons we removed the Nginx default site.&lt;br /&gt;&lt;code&gt;$ sudo rm /etc/apache2/sites-enabled/000-default&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now restart Apache and marvel at your newly configured web server. You'll get a warning but that will be taken care of once we actually map a Django project to a VirtualHost.&lt;br /&gt;&lt;code&gt;$ sudo /etc/init.d/apache2 restart&lt;br /&gt;* Restarting web server apache2&lt;br /&gt;[warn] NameVirtualHost 127.0.0.1:8080 has no VirtualHosts&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="postgre" style="color: rgb(204, 102, 0);font-size:140%;" &gt;PostgreSQL&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;PostgreSQL is the database of choice for Django; I won't initiate a holy war by discussing the pros and cons of the various database choices, I'll leave that to &lt;a href="http://www.google.com/search?hl=en&amp;q=postgresql+vs"&gt;others&lt;/a&gt;. You can find PostgreSQL's claim to some internet real estate &lt;a href="http://www.postgresql.org/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="postgre-install" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Installation&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;You will actually have to run this command twice for Aptitude to correctly configure PostgreSQL.&lt;br /&gt;&lt;code&gt;$ sudo apt-get install postgresql-8.3 postgresql-server-dev-8.3&lt;br /&gt;$ sudo apt-get install postgresql-8.3 postgresql-server-dev-8.3&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="postgre-config" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Config&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Give the postgres user an actual password.&lt;br /&gt;&lt;code&gt;$ sudo -u postgres psql template1&lt;br /&gt;template1=# ALTER USER postgres WITH PASSWORD 'password';&lt;br /&gt;template1=# \q&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Next, limit who can access the database by changing the METHOD for local.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/postgresql/8.3/main/pg_hba.conf&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:79 local   all         all          password&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Restart PostgreSQL to activate the new settings.&lt;br /&gt;&lt;code&gt;$ sudo /etc/init.d/postgresql-8.3 restart&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="postgre-users" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Users&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Create a personal superuser. You can read more about this &lt;a href="http://www.postgresql.org/docs/current/static/app-createuser.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;code&gt;$ sudo -u postgres createuser -P -s -e paul&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="postgre-admin" style="color: rgb(204, 102, 0);font-size:130%;" &gt;phpPgAdmin&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;This handy piece of software let's you administer your databases through a web browser. We'll tie this to our Nginx and Apache scheme in the &lt;a href="#django"&gt;Django&lt;/a&gt; portion of the guide.&lt;br /&gt;&lt;code&gt;$ sudo apt-get install phppgadmin&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="memcached" style="color: rgb(204, 102, 0);font-size:140%;" &gt;Memcached&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Memcached is the preferred type of cache for Django, as explained &lt;a href="http://docs.djangoproject.com/en/dev/topics/cache/#memcached"&gt;here&lt;/a&gt;. The fastest Python binding for Memcached is currently &lt;a href="http://gijsbert.org/cmemcache/"&gt;cmemcache&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="memcached-install" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Installation&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Install the necessary packages.&lt;br /&gt;&lt;code&gt;$ sudo apt-get install memcached libmemcache-dev&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Start the Memcached daemon. This delegates 64 megabytes of RAM, modify this to your needs.&lt;br /&gt;&lt;code&gt;$ sudo memcached -u www-data -p 11211 -m 64 -d&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="memcached-cmemcache" style="color: rgb(204, 102, 0);font-size:130%;" &gt;cmemcache&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;We can't use Aptitude to install cmemcache so this will be a somewhat more laborious process than what we've been used to, but only marginally so. Create a general directory for the various libraries that we'll download, and grab the latest cmemcache version.&lt;br /&gt;&lt;code&gt;$ mkdir ~/libs&lt;br /&gt;$ cd ~/libs&lt;br /&gt;$ wget http://gijsbert.org/downloads/cmemcache/cmemcache-0.95.tar.bz2&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Unpack the archive and go to its directory.&lt;br /&gt;&lt;code&gt;$ tar -xjvf cmemcache-0.95.tar.bz2&lt;br /&gt;$ cd cmemcache-0.95&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Use the supplied setup.py to install.&lt;br /&gt;&lt;code&gt;$ sudo python setup.py install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And that's it. A note if you're using a 64-bit OS, cmemcache will give you this warning during the installation procedure.&lt;br /&gt;&lt;code&gt;warning: format '%llu' expects type 'long long unsigned int', but argument 4 has type 'u_int64_t'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This is merely a warning and shouldn't have any tangible effect.&lt;br /&gt;&lt;br /&gt;&lt;span id="django" style="color: rgb(204, 102, 0);font-size:140%;" &gt;Django&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;In the words of the Django marketing department: "Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design". It is, in my humble opinion, easily the best high-level web framework out there at the moment. You can read more about Django &lt;a href="http://www.djangoproject.com/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;One additional note before we install Django, there are a myriad of different ways to organize a Django project, none necessarily better than the other. Wait, that's not entirely true, I've seen some truly horrendous projects; but I digress. What I'm presenting here is a compromise between flexibility and simplicity. If you're planning to host multiple Django projects on the same server you should take a serious look at &lt;a href="http://pypi.python.org/pypi/virtualenv"&gt;virtualenv&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span id="django-install" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Installation&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Download and install the latest official version.&lt;br /&gt;&lt;code&gt;$ cd ~/libs/&lt;br /&gt;$ wget http://www.djangoproject.com/download/1.0.2/tarball/&lt;br /&gt;$ tar -xzvf Django-1.0.2-final.tar.gz&lt;br /&gt;$ cd Django-1.0.2-final&lt;br /&gt;$ sudo python setup.py install&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="django-default" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Default Project&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Create a basic directory skeleton and then a default project. I'll be using gen.ki as a domain.&lt;br /&gt;&lt;code&gt;$ sudo su - django&lt;br /&gt;$ mkdir -p ~/domains/gen.ki/{public,private,log}&lt;br /&gt;$ mkdir ~/domains/gen.ki/public/media&lt;br /&gt;$ mkdir ~/domains/gen.ki/private/apache&lt;br /&gt;$ cd ~/domains/gen.ki/&lt;br /&gt;$ django-admin.py startproject genki&lt;br /&gt;$ exit&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="django-database" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Database&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Create a database and user for the Django project.&lt;br /&gt;&lt;code&gt;$ sudo su - postgres&lt;br /&gt;$ createuser -P genki&lt;br /&gt;Shall the new role be a superuser? (y/n) n&lt;br /&gt;Shall the new role be allowed to create databases? (y/n) n&lt;br /&gt;Shall the new role be allowed to create more new roles? (y/n) n&lt;br /&gt;$ createdb --encoding=UNICODE genki -O genki&lt;br /&gt;$ exit&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="django-config" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Config&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Now we need to connect all the bits and pieces. Switch to the django user and stay logged in as him throughout this process.&lt;br /&gt;&lt;code&gt;$ sudo su - django&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Link the admin media to the public media folder.&lt;br /&gt;&lt;code&gt;$ ln -s /usr/lib/python2.5/site-packages/django/contrib/admin/media/ ~/domains/gen.ki/public/media/admin&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Modify the settings.py file for the Django project. Update the ADMINS, TIME_ZONE and such as you see fit, what I mention here is merely what is required. Feel free to read up on Django's &lt;a href="http://docs.djangoproject.com/en/dev/topics/cache/"&gt;cache&lt;/a&gt; and view a complete list of possible settings &lt;a href="http://docs.djangoproject.com/en/dev/ref/settings/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;code&gt;$ vim ~/domains/gen.ki/genki/settings.py&lt;br /&gt;&lt;/code&gt;&lt;code&gt;line:12 DATABASE_ENGINE = 'postgresql_psycopg2'&lt;br /&gt;line:13 DATABASE_NAME = 'genki'&lt;br /&gt;line:14 DATABASE_USER = 'genki'&lt;br /&gt;line:15 DATABASE_PASSWORD = 'password'&lt;br /&gt;line:48 ADMIN_MEDIA_PREFIX = '/media/admin/'&lt;br /&gt;line:60 MIDDLEWARE_CLASSES = (&lt;br /&gt;line:61     'django.middleware.cache.UpdateCacheMiddleware',&lt;br /&gt;line:62     'django.middleware.common.CommonMiddleware',&lt;br /&gt;line:63     'django.contrib.sessions.middleware.SessionMiddleware',&lt;br /&gt;line:64     'django.contrib.auth.middleware.AuthenticationMiddleware',&lt;br /&gt;line:65     'django.middleware.cache.FetchFromCacheMiddleware',&lt;br /&gt;line:66 )&lt;br /&gt;line:70 TEMPLATE_DIRS = (&lt;br /&gt;line:71     '/home/django/domains/gen.ki/genki/templates/',&lt;br /&gt;line:72 )&lt;br /&gt;line:81 CACHE_BACKEND = 'memcached://127.0.0.1:11211/'&lt;br /&gt;line:82 CACHE_MIDDLEWARE_SECONDS = 60 * 5&lt;br /&gt;line:83 CACHE_MIDDLEWARE_KEY_PREFIX = 'genki'&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Now that we have a proper config we can sync the database.&lt;br /&gt;&lt;code&gt;$ python ~/domains/gen.ki/genki/manage.py syncdb&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Exit from the django user's session.&lt;br /&gt;&lt;code&gt;$ exit&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="django-nginx" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Nginx&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Create the Nginx proxy for the Django domain. The setting "expires 30d" indicates that the media files will only be refreshed every 30 days, you will obviously have to change this if the media files are modified frequently in your project.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/nginx/sites-available/gen.ki&lt;br /&gt;&lt;/code&gt;&lt;code&gt;server {&lt;br /&gt;    listen   80;&lt;br /&gt;    server_name www.gen.ki gen.ki;&lt;br /&gt;&lt;br /&gt;    access_log /home/django/domains/gen.ki/log/nginx_access.log;&lt;br /&gt;    error_log /home/django/domains/gen.ki/log/nginx_error.log;&lt;br /&gt;&lt;br /&gt;    location / {&lt;br /&gt;        proxy_pass    http://127.0.0.1:8080/;&lt;br /&gt;        include       /etc/nginx/proxy.conf;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    location /media/ {&lt;br /&gt;        root   /home/django/domains/gen.ki/public/;&lt;br /&gt;        expires 30d;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Enable the site and restart Nginx.&lt;br /&gt;&lt;code&gt;$ sudo ln -s /etc/nginx/sites-available/gen.ki /etc/nginx/sites-enabled/gen.ki&lt;br /&gt;$ sudo /etc/init.d/nginx stop&lt;br /&gt;$ sudo /etc/init.d/nginx start&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="django-apache" style="color: rgb(204, 102, 0);font-size:130%;" &gt;Apache&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;Configure mod_wsgi to help Apache serve the project. Notice that we add both the domain and the Django project name to the path, this is due to any 3rd party applications we might include in our project at a later date.&lt;br /&gt;&lt;code&gt;$ sudo -u django vim /home/django/domains/gen.ki/private/apache/genki.wsgi&lt;br /&gt;&lt;/code&gt;&lt;code&gt;import os, sys&lt;br /&gt;&lt;br /&gt;sys.path.append('/home/django/domains/gen.ki')&lt;br /&gt;sys.path.append('/home/django/domains/gen.ki/genki')&lt;br /&gt;&lt;br /&gt;os.environ['DJANGO_SETTINGS_MODULE'] = 'genki.settings'&lt;br /&gt;import django.core.handlers.wsgi&lt;br /&gt;application = django.core.handlers.wsgi.WSGIHandler()&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Create a virtual host for the domain. You might have to modify the number of processes and threads the WSGI daemon spawns depending on your server environment.&lt;br /&gt;&lt;code&gt;$ sudo vim /etc/apache2/sites-available/gen.ki&lt;br /&gt;&lt;/code&gt;&lt;code&gt;&amp;#60;VirtualHost 127.0.0.1:8080&amp;#62;&lt;br /&gt;    ServerAdmin admin@domain.com&lt;br /&gt;    ServerName www.gen.ki&lt;br /&gt;    ServerAlias gen.ki&lt;br /&gt;&lt;br /&gt;    Alias /phppgadmin /usr/share/phppgadmin/&lt;br /&gt;&lt;br /&gt;    &amp;#60;Directory /home/django/domains/gen.ki/genki/&amp;#62;&lt;br /&gt;        Order deny,allow&lt;br /&gt;        Allow from all&lt;br /&gt;    &amp;#60;/Directory&amp;#62;&lt;br /&gt;&lt;br /&gt;    LogLevel warn&lt;br /&gt;    ErrorLog  /home/django/domains/gen.ki/log/apache_error.log&lt;br /&gt;    CustomLog /home/django/domains/gen.ki/log/apache_access.log combined&lt;br /&gt;&lt;br /&gt;    WSGIDaemonProcess gen.ki user=www-data group=www-data threads=10&lt;br /&gt;    WSGIProcessGroup gen.ki&lt;br /&gt;    WSGIScriptAlias / /home/django/domains/gen.ki/private/apache/genki.wsgi&lt;br /&gt;&amp;#60;/VirtualHost&amp;#62;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Enable the site and restart Apache.&lt;br /&gt;&lt;code&gt;$ sudo ln -s /etc/apache2/sites-available/gen.ki /etc/apache2/sites-enabled/gen.ki&lt;br /&gt;$ sudo /etc/init.d/apache2 restart&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;span id="epilogue" style="color: rgb(204, 102, 0);font-size:140%;" &gt;Epilogue&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;And that's it. If you go to the URL you supplied as a ServerName you should now see the default Django page, provided that you've done the necessary &lt;a href="http://en.wikipedia.org/wiki/Domain_Name_System"&gt;DNS&lt;/a&gt; configuration. Also try going to /phppgadmin, the interface should load and you can log in with the personal superuser you made during this &lt;a href="http://ethics-gradient.blogspot.com/#postgre-users"&gt;step&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So what now? One option is to actually &lt;a href="http://docs.djangoproject.com/en/dev/intro/"&gt;learn&lt;/a&gt; how to make a Django site. Or you can set up a plethora of these Django servers and make a fortune redistributing them. &lt;strike&gt;Or you can quit this computer nonsense and live happily ever after.&lt;/strike&gt;&lt;br /&gt;&lt;br /&gt;&lt;span id="epilogue-links" style="color: rgb(204, 102, 0);font-size:130%;" &gt;External Links&lt;/span&gt; &lt;a href="#top"&gt;&amp;uarr;&lt;/a&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/modwsgi/"&gt;The mod_wsgi project.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.dscpl.com.au/"&gt;Graham Dumpleton's blog.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://articles.slicehost.com/sitemap"&gt;Slicehost articles.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.codemongers.com/Main"&gt;Nginx wiki.&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7848112787715004355-3800763897352259917?l=ethics-gradient.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ethics-gradient.blogspot.com/feeds/3800763897352259917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://ethics-gradient.blogspot.com/2009/02/django-and-ubuntu-804-chronicle.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7848112787715004355/posts/default/3800763897352259917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7848112787715004355/posts/default/3800763897352259917'/><link rel='alternate' type='text/html' href='http://ethics-gradient.blogspot.com/2009/02/django-and-ubuntu-804-chronicle.html' title='The Django and Ubuntu 8.04 Chronicle'/><author><name>Paul Skarseth</name><uri>http://www.blogger.com/profile/04999064950288939413</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>
