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.
#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?