Site Sections: Satchmo Main | Wiki | Demo Store |

Optimizing A Django VPS Setup

As I started moving forward with a plan to host Satchmo on my own, I began experimenting with hosting solutions. I already had a traditional hosting service and was able to get Satchmo running as a fast cgi. It worked reasonably well, but the control was less than optimal. For some reason, I never could figure out how to effectively start and stop my django processes. I also decided that I wanted to host my own Trac and Subversion instance so that I could have a similar level of integration as the Django site. For all these reasons, I decided I need more flexibility so started looking at VPS and VPS-like solutions.

I ended up going to http://www.grokthis.net for one of the advanced hosting accounts. After playing with it, I started running into some limitations and realized I really did want more control. So, I moved to one of their small Xen VPS accounts. These accounts have 96MB of RAM and 192MB of swap. I really liked the root access and quickly learned to like the Ubuntu distro.

As I configured the VPS, I tried to keep my memory footprint as low as possible. The first thing I did was get rid of Apache and move to lighttpd. If you want to see some good detailed instructions on getting lighttpd, Django and Satchmo running, take a look at Bruce's detailed tutorial here - http://coderseye.com/2007/setting-up-satchmo-on-a-debian-server.html

My exact setup is a little different and I will eventually post the examples of the scripts I use. For now, though, Bruce's write up is pretty close to mine. In addition to Satchmo, I wanted to run Trac and Subversion. Fortunately, subversion comes with it's own server which is pretty light-weight from a memory perspective. The only downside is that you have to access subversion via the svn:// protoccol instead of http://. This causes some problems with some brain-dead firewalls but it hasn't been a show stopper yet.

With lighttpd, the only option to run Trac is through fast-cgi. The process was pretty simple but I noticed that Trac started to use a bunch of memory. I would normally end up with 5 Trac processes all using 15M+ of memory. In order to conserve overall memory, I decided to run Django in the threaded fast-cgi instead of preforking. More on this choice later.

The other memory hog in this setup was MySQL. After looking around on the web, I found a few good suggestions. Here are some of the changes I made in /etc/mysql/my.cnf:

key_buffer = 8M
query_cache_size = 2M
skip-innodb
skip-ndbcluster

These changes drastically reduced MySQL's memory footprint. I honestly don't remember how much but it made a big difference. Obviously, I'm dealing with a very small database so the tuning I did may not work for a real production system with lots of users and data.

After the MySQL changes, everything seemed to run pretty well. Using top and ps, I could tell I was using a lot of my memory and was going to swap quite a bit but the site seemed to run ok. Usage was pretty low (less than 100 visitors a day) and it sometimes seemed slow to me but I was ok with it. I ran like this for a while, then we launched Satchmo 0.5.

Traffic picked up dramatically as the word spread and the vps couldn't keep up. As the small deluge subsided, I was able to see that my memory filled up and the constant swapping doomed the site. By no means was this a slashdot or Digg-level traffic but it was too

After doing some post mortem analysis, it was clear that I needed even more memory. I moved my account to a different grok-this program called vps-village. This plan gave me 256MB of RAM for only $20 so I figured I'd give it a shot. Because I was on the same hosting provider, I was able to get everything moved and did not have to reconfigure everything.

After the move, I noticed I had lots of free memory. I decided to move Django away from the threaded server and go to the prefork with the following options:

prefork minspare=2 maxspare=4 maxchildren=5

My trac config now looks like this:

## FastCGI programs have the same functionality as CGI programs,
## but are considerably faster through lower interpreter startup
## time and socketed communication
##
## Documentation: /usr/share/doc/lighttpd-doc/fastcgi.txt.gz
##                http://www.lighttpd.net/documentation/fastcgi.html

#server.modules   += ( "mod_fastcgi" )

fastcgi.debug = 1


fastcgi.server = ("/trac" =>
                  ("trac" =>
                    ("socket" => "/var/trac/run/trac-fastcgi.sock",
                     "bin-path" => "/usr/share/trac/cgi-bin/trac.fcgi",
                     "check-local" => "disable",
                     "min-procs" => 1,
                     "max-procs" => 3,
                     "bin-environment" =>
                       ("TRAC_ENV" => "/var/trac",
                        "PYTHON_EGG_CACHE" => "/var/trac/egg-cache")
                    )
                  ),
              "/main.fcgi" =>
                 ("shop" =>
                   ("socket" => "/var/django/satchmo.sock",
                    "check-local" => "disable",
                   )
                 )
                )

url.rewrite = (
"^(/admin.*)$" => "/main.fcgi$1",
"^(/shop.*)$" =>  "/main.fcgi$1",
"^(/account.*)$" => "/main.fcgi$1",
"^(/blog.*)$" => "/main.fcgi$1",
"^(/comments.*)$" => "/main.fcgi$1",
"^(/)$" => "/main.fcgi$1",
  )

This has server me well. Hopefully this is useful for others trying to figure out how to manage multiple apps on a small footprint vps server. In the future I'll probably move the trac and svn portions to another box but that is another post.

Posted on September 25, 2007 by chris django vps

7 Comments

#1 syncsync commented, on September 26, 2007 at 6:08 a.m.:

I run my django sites on grokthis VPS hosting too. Well, great article. But it is not clear for me what are the advantages of hosting subversion repositories on VPS? There are a lot of free subversion hosting, so why not use them instead of spending valuable virtual server resources?

#2 Chris commented, on September 26, 2007 at 8:23 a.m.:

Good question. The basic reason was that I want to be able to install some additional plugins. The main one I wanted to use is the one that enables you to display rst files stored in the repository on wiki pages. I can't seem to get to trac hacks now, but the plugin is stored there.

#3 Marijn commented, on October 10, 2007 at 9:22 a.m.:

What is the benefit of running with fastcgi instead of using mod_python / apache? You're using less memory by using lighttpd but isnt this being nullified by having to use fastcgi instead of mod_python? How is the memory footprint of apache/mod_python compared to lighttpd/fastcgi?

#4 chris commented, on October 10, 2007 at 8 p.m.:

Marijn - I chose to run fastcgi because it seemed a little bit easier for me. I had some problems getting mod_python compiled and working with Apache. Fastcgi worked fine and it works with lighttpd so that's why I chose it. I have no idea if mod_python + Apache uses less memory than my setup.

#5 Kun Xi commented, on February 29, 2008 at 10:40 a.m.:

Usually mod_python has a bigger memory footprint as each instance would have one python interpreter instance. FastCGI is the suggested deployment for high traffic productive web site.

#6 Lucas commented, on March 16, 2008 at 7:52 p.m.:

Also mod_python and apache are developed independently of each other. It makes the upgrade process a pain.

Using fcgi keeps your django processes separate from your web server. You are not locked into a specific server implementation or version.

#7 imgrey commented, on July 8, 2008 at 9:20 a.m.:

I use satchmo in several projects and appreciate your work. Therefore I'm ready to propose you free VDS at http://0x2a-dc.com

Post a comment

Your name:

Comment: