Mime type woes hopefully solved

So some of you have pointed out to me that downloading a tar.gz file from my site through a browser like Firefox never seems to work well- I think I have finally fixed the problem. The odd part was that using a command line too like wget would work just fine. It all comes down to the .htaccess file.

Options +ExecCGI
Options +FollowSymLinks

AddType application/x-tar .tgz
AddType text/plain .c
AddType text/plain .h

ExpiresActive On
ExpiresDefault "access plus 15 minutes"
ExpiresByType image/gif "access plus 1 hours"
ExpiresByType image/png "access plus 1 hours"
ExpiresByType image/jpeg "access plus 1 hours"
ExpiresByType image/x-icon "access plus 1 hours"
ExpiresByType application/x-javascript "access plus 15 minutes"
ExpiresByType text/css "access plus 1 hours"

SetOutputFilter DEFLATE
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE\s6 no-gzip
BrowserMatch \bMSIE\s7 !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \
        \.(?:gif|jpe?g|png|pdf|swf|ipk)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \
        \.(?:exe|tar|t?gz|zip|t?bz2|sit|rar)$ no-gzip dont-vary
Header append Vary User-Agent env=!dont-vary

I had everything in this file except one line, which is the SetEnvIfNoCase condition for exe, tar, tgz, etc. files. Because I wasn't excluding these common binary formats from the DEFLATE filter, the Transfer-encoding: HTTP header was getting set to chunked, which seemed to break all sorts of stuff (but since wget did not treat this header the same, it worked fine).

Long story short- it should be all better now. Send me an email if I'm wrong.

dreamhost

Arch Eee Repository

For those of you using Arch Linux out there who don't regularly read the forums(Arch on Eee PC thread) or the wiki (Installing Arch on the Eee), you may not know that I have an Eee-specific repository of packages available. This repository includes the following:

  • kernel-eee - the primary motivation of making this repository was to build a kernel optimized for the Eee. This includes most required drivers built right into the kernel, drops a bunch of unnecessary modules from the stock Arch config, and is optimized for the right processor and possible RAM. It is also patched with an asus_acpi driver as well as the atl2 ethernet driver.
  • madwifi-ng-eee - the madwifi-ng wifi driver/module for the integrated Atheros wireless chipset. This is an SVN driver, although I failed to include this in the package name. I don't try to stay on the bleeding edge for fear of breakage, but I do update it to newer versions every so often.
  • linux-uve-eee-svn - the driver/module for the integrated webcam.
  • eeepc-linux - a custom kernel module that allows you to adjust the fan speed and overclock the FSB on the eee. Seems dangerous, but not hard to maintain. Word of caution- I don't really use it.
  • luvcview - available in the Arch AUR, I put it here so people could just grab it. A super simple program to test your webcam.

As usual, I am using GIT for maintaining this little side project. My eee GIT repository holds all the stuff you would need to build your own version of this repository.

archlinux

My new toy, the Eee PC

About a week ago, I got my newest electronic toy, the Eee Pc. First thought after I opened the box: "Wow, this is small!" Second thought: "Wow, this thing is cool!"

Needless to say, I've been playing with this thing quite a bit since I received it. I bought the 4G Galaxy Black model from Amazon.com, along with a 4GB Class 6 (the fastest speed available) SDHC Card. I've been a happy Amazon customer as of late- I bought my awesome new Samsung LCD TV there as well, which came with free shipping and arrived in just over a week.

The keyboard is not large by any means, and the touchpad isn't the greatest one I've ever used. However, you get used to it pretty quickly. It is good enough to post here as I am doing right now. But the huge advantage is this thing is small. You could carry this thing just about anywhere and it is only the size of a large (but thin) book. It even comes with a slick little carrying case. The AC adapter is more like a phone charger rather than the large brick you see with most laptops. The thing is also quiet due to the solid-state drive instead of a normal hard drive.

As I said above, I bought a 4GB card for use as extra storage space, but I really don't plan on storing loads of stuff on this machine. It works great as a internet browsing machine, as you can use it just about anywhere. Loading up some music or a movie on the card would be a great idea though as it works great as a media player. The small screen is still plenty large for playing back movies full screen- it is comparable to a portable DVD player.

I've had zero issues so far with the battery life- I don't know exactly how long it is supposed to last but I can't see it being shorter than 3 hours under normal usage. The CPU is designed to scale down to 112.5MHz when it isn't fully needed, which does a great deal to save power (wasn't that the speed of my family's first Pentium machine?). The lack of a spinning hard drive also helps a lot.

The biggest usability fix I've found so far is plugging a USB mouse in- this allows you to have one hand on the mouse and one on the keyboard. Given the keyboard's size, it is quite easy to touch-type with one hand.

I'll be doing a follow-up post sometime about getting Arch onto the Eee, and how I have it all set up. It is running great now, with every piece of hardware working. There is a rather large community of Arch users that have an Eee, including another dev Daniel (ise). Several users put together some packages of modules and scripts for the Eee, and I tried to build on their knowledge to put a little repository. I was going to do that tonight, but realized it might get a bit lengthy. I have a nice TV to watch anyway.

other

Road to pacman 3.2.0

Hadn't posted on the old blog in a while, so I thought I'd give a quick update on my "little" baby project, pacman.

The road to 3.2.0 is coming along nicely, with the biggest set of changes being merged very early on- the switch to entirely dynamic allocation of memory in libalpm. This provided some HUGE benefits for pacman. I discussed the gory details of this in an earlier blog post.

Other things that are cool to see is Xavier's and my continued work to clean up some of the codebase, with our most recent target being the server/download code in libalpm. This work is coming along nicely and should get merged to master soon. Some parts have already made it in.

We have also done some extensive work on "delta v2.0" for libalpm and the package and database scripts. This will address some of the shortcomings the previous implementation had. I want to make it clear that Nathan Jones did a tremendous job of getting this into libalpm in the first place- he did most of the hard work by writing the code from scratch, and we are simply trying to make some changes so it would be hard for a "certain distribution" not to use it.

There are several other one-off patches that have been incorporated as well. One of the cooler things we have now is a Chinese translation for pacman, with fully supported wide character output. This will actually find itself a home in 3.1.3, which should be coming relatively soon.

So is there a timeline for 3.2.0 release? Not really. Once the bigger patches start falling into place and we do some more testing, I might have a better idea, but a release in 2 months or so is quite plausible. Although there won't be any huge user-visible changes, the dynamic memory allocation is a large enough change and improvement to warrant a release.

pacman archlinux C

Valgrind 3.3.0 and the new massif

I previously wrote a column on using valgrind, and I briefly touched on the massif tool. With the release of Valgrind 3.3.0, the massif tool got quite an overhaul. The output is no longer postscript by default, but instead is a massif.out.<pid> file that can be post-processed by other tools. Currently the only tool to do this with is ms_print.

Massif is invoked as before. The example command line below is for using it with pacman to test heap usage during a large sync operation. I wanted to do a before and after with our dynamic memory allocation changes and the removal of many unnecessary pkg_dup calls in the code. This was the root of FS#8155.

sudo valgrind --tool=massif --depth=4 --max-snapshots=200 ./src/pacman/.libs/lt-pacman --root /tmp/installroot/ -Sy base --noconfirm

I ran this command with two different cuts of code- the v3.1.1 tag of pacman, and the current master branch (which happened to be commit 88cbee). The results were quite interesting.

Because massif does not output a human friendly file by default, you have to post-process it with ms_print. The following basic idea should get you started:

ms_print --x=132 --y=60 massif.out.2786 | less

With this all complete, I was able to produce the following two output files which show a huge improvement in the current pacman release and our working branch with the malloc and dup changes. You can see the old code uses much more memory at its maximum point than the new code- 13.9MB vs 5.3MB! In addition, the memory usage of the old code continuously grows because of the pkg_dup calls, while then new code stays at constant memory usage after all targets are loaded. This should make pacman fail early (if at all) when it comes to memory issues, rather than completing half of an install and dying.

pacman C

Pacman 3.1.0 release

I released pacman 3.1.0 tonight after quite a bit of testing by some fellow Archers using my [pacman-git] repository. You can see the news release here, and the pacman website gives a bit more information as well.

I'm making this post mainly because I want to thank all those who helped make this release happen. We've had nearly 750 patches since the 3.0.X series of releases, and the effort shows. The code has undergone some huge changes for the better, with many parts being refactored and reworked for correctness. We've added over 70 pactests since 3.0.6 to help track down small but important issues in how pacman handles everything from file conflicts to versioned provisions. It is quite impressive what we can all get done in our free time.

I'd like to thank Andrew Fyfe for his great work on a complete rework of makepkg, which is now a great example of functionalized bash programming. Chantry Xavier has been a HUGE help to me the past few months, taking a lot of patches from the mailing list and collecting them in his GIT tree, not to mention all his own hard work fixing issues and implementing features. Nagy Gabor has found and helped fix several logic and consistency issues throughout the code base. Nathan Jones is just starting to get into some of the C code, but he has been showing some great work and potential. Finally, Aaron Griffin didn't contribute as many patches as he may have liked, but I could always bounce anything of him that I was working on and get some great feedback.

Thanks also to anyone I didn't mention above- you work isn't forgotten by any means. And I encourage everyone to continue to improve what we have here- a rock-solid package manager for a rock-solid distribution.

pacman archlinux

Using gcov for code coverage testing

I just made use of a handy tool today to do code coverage testing with C programs, and I thought I'd do a quick rundown of how to use gcov, a code coverage tool for gcc.

The helpful documentation that I used is part of the GCC docs. The manpage for gcov is also helpful. I recommend taking a look at both after reading the rest of this post and before starting on your own.

Compiling your code for use with gcov

In order to compile your code for use with gcov, you must use two additional compile flags with gcc. These flags are -fprofile-arcs and -ftest-coverage. For a simple one file program, it is easy enough to just pass these with your gcc call:

gcc -fprofile-arcs -ftest-coverage -o myprog myprog.c

For something with the GNU autoconf/automake setup (such as the pacman code base), the following worked for me:

./configure <normal parameters> CFLAGS='-fprofile-arcs -ftest-coverage'

A quick note- ensure you are using plain gcc and not something like ccache or distcc, as it may interfere later when trying to get test coverage results back.

Running your program

Once you have compiled your program, it is highly recommended to run your program from the same directory you ran the compile. Simply running your program will output a whole bunch of files in your source directories, with names based off your source file names and ending in things like gcda and gcno. These are the data files recorded with each run of your program, and they are cumulative, meaning you can run your whole test suite and then go looking for code that wasn't ran. To reset the stats, you must delete all these files, which can be done real easily with a command like the following:

find -name '*.gcda' -o -name '*.gcno' -delete

Once you have ran your program, you can use the gcov tool to get some human-readable results. To do this, I simply navigated into my src/ directory and ran a command like the following:

gcov *.c

This produced a .gcov file for each of my C source files with code coverage and line number annotations along the side. This will contain stuff similar to the following:

    -:  844:    /* Opening local database */
  302:  845:    db_local = alpm_db_register_local();
  302:  846:    if(db_local == NULL) {
#####:  847:        pm_printf(PM_LOG_ERROR, _("could not register 'local' database (%s)\n"),
    -:  848:                alpm_strerrorlast());
#####:  849:        cleanup(EXIT_FAILURE);
    -:  850:    }
    -:  851:
    -:  852:    /* start the requested operation */
  302:  853:    switch(config->op) {
    -:  854:        case PM_OP_ADD:
   48:  855:            ret = pacman_add(pm_targets);
   48:  856:            break;
    -:  857:        case PM_OP_REMOVE:
   38:  858:            ret = pacman_remove(pm_targets);
   34:  859:            break;

How to interpret results

As you can guess, the first column is the number of times that line was run, and the second column is the line number. gcov is smart enough to realize that some lines are not an instruction, so simply fills the first column with a -. The most interesting lines are those with #####, which means they were never triggered. In the cases that we see this above, it is simply error messages that are never triggered (which is probably a good thing). The times you really want to watch out for is whole sections of your code that are never triggered, or branches of small statements that you know should be tested.

Other notes

gcov can also be used in tandem with gprof to do some code profiling and hotspot location. However, I tend to use the more powerful (in my opinion) valgrind/callgrind combination due to the power of using kcachegrind to navigate the results. See my earlier post for details.

When using gcov with programs that use libtool, you can have some problems trying to generate the coverage files on the library source files due to libtool's .libs directory. There are gcda/gcno files in multiple places and it took some work to get them to generate properly, but I found the following trick to work:

cd /lib/libsourcefolder/.libs
cp ../*.c . #copy all the source files into the .libs dir, you could link too
gcov *.c

Happy profiling!

pacman C

Django Middleware Order

I have found it a mystery why everything in the Django documentation always mentions how important it is to order middleware correctly, and yet no canonical order is given for the supplied middleware. The following ordering is what I have settled on after a long conversation and exchange with some folks in #django on freenode.

# Define our middleware classes.
# To disable caching for devel, use simple://.
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.middleware.gzip.GZipMiddleware',
    'django.middleware.cache.CacheMiddleware',
    'django.middleware.http.ConditionalGetMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.doc.XViewMiddleware',
)

Of course, I bet you want some explanation as to why this is the right order. I'll give it my best shot.

Session middleware needs to come before Auth middleware, because authentication is handled with sessions. Django needs to look up the session of a user before the identity of a user can be looked up.

Both of these come before Cache middleware so the CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting is honored. If sessions and authentication are not established first, then Django will throw an error in your webserver log insisting you have authentication middleware installed.

I don't really know what XView does, so it is last. It isn't that important.

Common middleware can go near the bottom in my setup. If you wanted to use the vary_on_cookie decorator, then it would need to go much higher in the list.

Conditional Get middleware needs to see Etags, so it must be above the Common middleware that sets those.

django

Using valgrind for C programming

When trying to find memory leaks and hotspots in C code, no tool is better than valgrind. I frequently use it when debugging and fixing up pacman code, and I thought I'd share some of my common usage patterns.

Valgrind is more than just memory checking

Most people familiar with valgrind know that it is a very good memory checking tool. However, this is just the default tool that runs when you start valgrind without specifying a --tool option.

man valgrind reveals that it comes with a nice selection of tools. These include cachegrind, callgrind, helgrind, massif, and memcheck. All serve their own purpose, I will talk about a small selection below.

Initial setup

In order to have valgrind provide you with useful information and no useless information, I have it set up the following way for pacman. First, the valgrind.supp file included in the GIT repository helps eliminate spurious warnings during library loading and relocation. In order to use this all the time, set up a .valgrindrc file in your code directory with the following (this instructs valgrind to always run with these options for this project):

 --suppressions=valgrind.supp
 --memcheck:leak-check=full

The second option in this file will be described more below. A quick side note: a local .valgrindrc file will take precedence over any options in ~/.valgrindrc.

memcheck

memcheck is one of the most used tools, and for good reason. C memory management can be tough when you malloc in one place, are using list structures with pointers, and don't always free everything at the same time. Running valgrind on pacman and going through all of the options is something I've tried to do to catch various memleaks. Now you can just run something like this to find problems in pacman:

 valgrind --tool=memcheck ./src/pacman/.libs/lt-pacman <operation>

By using lt-pacman instead of just pacman, you can skip a lot of process creation (and thus valgrind output) that the libtool pacman script spits out. Just be sure you have run ./src/pacman/pacman at least once, or lt-pacman won't exist.

pactest actually has valgrind support slightly integrated, so you can do something like this to find memleaks during pactests (such as one I found on smoke001.py):

 ./pactest/pactest.py --test ./pactest/tests/<pactest> -p ./src/pacman/.libs/lt-pacman --valgrind

So once you see that their are memory leaks, how do you fix them? That comes with practice. In most cases, the backtraces that the leak-check option prints (above in the .valgrindrc) point to the malloc of the memory, so it is up to you to find where the memory should actually be freed. Sometimes you are lucky- it should be freed in the same functions. Most of the time it is not this easy, and you will have to do some poking around the code to find the right location to free the memory.

callgrind

I don't think people have fully seen what valgrind can do until they use callgrind on their program. A quick word of warning- using the callgrind tool makes your program run much slower, so try to get your test case right the first time.

In order to use interpret results from callgrind, install kcachegrind. It is an amazing tool and really helps find hotspots in your code. Using callgrind and kcachegrind, I have been able to find several hotspots in libalpm code. Here is one before and after example. As you can see, strcmp was a limiting factor in this particular operation. A few code changes later, I was able to eliminate much of the overhead of it. I just recently made a large fix to the usage of alpm_splitdep which resulted in it being called 1700 times instead of ~1.3 million times in a single run of pacman -Qt.

Here is an example command for tracking down the second fix I made above:

 valgrind --tool=callgrind ./src/pacman/.libs/lt-pacman -Qt

After the callgrind run completes, run kcachegrind and open the callgrind.out file. From here, you may see some functions that are hotspots. Navigating the functions is relatively intuitive once you figure out how the program is laid out.

massif

I haven't used this tool much, but it appears that it could be helpful in seeing how much heap usage your program is using. This will come in useful when trying to get pacman running in low memory environments.

Right now, pacman is rather inefficient with the heap because we allocate static-length strings when creating packages with _alpm_pkg_new as you can see here. When we switch this to dynamically allocated strings, this graph will hopefully show a lot less heap usage.

I haven't used massif in a while, but I believe something like this should work:

 valgrind --tool=massif --depth=4 ./src/pacman/.libs/lt-pacman <operation>

This should produce a few files in your working directory once it completes, including a ps (postscript) file. This can be converted to png using some standard tools.

Note that this tool can show a memleak that memcheck doesn't really catch- high usage of the heap where we always have pointers to our objects, but we hold onto these handles for too long. In the pacman case, you can see that our heap usage never shrinks when running the program, which indicates we don't free much until the end of the program.

Summary

valgrind is a helpful tool, and is one of many that I use in C development. In the future I'll try to talk about a few more programs that I use to help write, debug, and clean up code. If you have any questions on anything I talk about, feel free to send me an email and I'll be glad to help you out.

For much more information on valgrind, be sure to read the manpage as well as the informative valgrind documentation.

pacman C

Git workflow with pacman

I've become quite comfortable with GIT after the initial uphill battle with its seemingly overwhelming list of commands. You begin to realize how many things you can do in GIT that you couldn't previously do in other revision control systems once you adapt your workflow to something that works better with GIT. Coming from CVS on the pacman project, it took some changing of habits but overall I can be much more efficient now.

The basics come first

Because GIT works with an index between your working tree and the previous revision, committing and diffing can become much more powerful. For one, you don't need to commit at the whole project or file level as you do with CVS or SVN. Without going into too much detail, I'd recommend reading man git-add, and especially looking at the interactive option. Once you have git-added a file, you can make further changes and they will not automatically be committed until you add them again- at first this seems weird, but is quite powerful. Read up on git-diff --cached as well.

Patches welcome

GIT makes it relatively easy to submit patches for review, because the subject and description of the patch can all get sent out with it. Patches made using the GIT tools are far easier to apply correctly than those using the standard diff utility. They are also easier to create once you get things set up.

For creation of patches, don't think the way you would with CVS/SVN, where you never actually commit your changes. The best method I've found is to create a topic branch (remember that branches are extremely cheap in GIT) using git checkout -b fixfoo from the master branch. From there, change and test the code until you get things working right. Then commit the patch, with a good description line and as much description is necessary. Sign off on it too for good measure. Then the following set of commands can send your patch right off to wherever it needs to go:

 git-format-patch master
 git-send-email <patch files>

A few hints about the above- the patch files are always numbered and named with their subject line, so pick good subjects. git-send-email also needs some initial setup to get it working as expected. Using git-config, I set the sendemail.smtpserver variable to /usr/bin/msmtp. I then configured msmtp with my email account settings.

Applying patches

At least in my position, I tend to apply patches more than send them out. This is fairly straightforward. A quick hint for those that use Gmail: you are able to use the "Show original" link on a message to get a plain-text file that will apply with the git patch tools, with one exception- once you save the file, you will need to delete the first (blank) line of the file.

For those not using Gmail, I'm sure you can figure out how to get plain text emails out of your client, or at least into mbox/Maildir format. I tend to only apply one patch at a time, so it is quite simple:

 git-am -s < /tmp/<patchfile>

The advantage this has over using patch is simple- it actually creates a GIT commit and you don't need to rewrite the description message. Of course, we have a few people on the mailing list that don't submit patches this way...

Local development

I could look at it as a blessing or a curse, but GIT allows extensive local development that can exist independent of the master branch. With CVS, you really have to keep multiple checkouts and pray that updates of the repository don't smash your changes. With GIT, you can manage all these topic branches in one local repository. At the time of writing this, I have some 11 local branches, each with a different purpose. When it comes time to merge these in, I won't have to pray like I did with CVS that the merge or application of the patches will work- I know it will be relatively smooth.

One of the most helpful commands when it comes to keeping your work up-to-date with the master branch is git-rebase. The manpage gives a good overview (as does just about every GIT manpage, they are highly recommended reading). At first, the command line syntax of the option can be daunting but that is only because it can be quite powerful. When it comes down to it, 95% of the time the usage will look like this:

 git-rebase master <yourbranch>

This will rebase the bottom of your branch (or patch stack) onto the tip of master. You may have to resolve some conflicts while doing this, but using git-mergetool should prove to be very helpful. In addition, running mkdir .git/rr-cache is recommended- it will create a cache directory that records these hand merges and will use them later if appropriate, saving you time and thinking. If this directory exists, the rest will be automatic; see man git-rerere for details.

More to come

For now I'm going to leave off with this- GIT isn't something you can master in a day, but you can quickly become quite proficient in doing things fast with it.

Some future topics I'd like to touch on, so keep your eyes open for these: * qgit and how I use it all the time git-stash (new in v1.5.3) and its alternatives git-merge and its infrequent but helpful usage

In addition, feel free to send me an email with anything that you think is GIT related and worth posting about. Or really about anything Arch and programming related, because that is what this blog mostly caters to.

pacman git

Getting Django running on Dreamhost, part 1

When trying to get Django up and running to host this site and blog, I ran into quite a few potholes. Hopefully this will help someone else out that wants to get it working as well. I should probably update this page a bit, which had some helpful hints but seemed woefully outdated.

Getting it up and running

The first step is to email Dreamhost support about raising memory limits for your Python FastCGI processes as described here.

Set up a dispatch.fcgi that works. This was one of the most troublesome parts for me. Here is my dispatch.fcgi, with some variables in there for you to fill in:

#!/usr/bin/python2.4
import sys, os

# Add a custom Python path.
sys.path.insert(0, '<homedir>/usr/lib/python')
sys.path.insert(0, '<homedir>/usr/lib/python/flup')
sys.path.insert(0, '<homedir>/usr/lib/python/django_src')
sys.path.insert(0, '<homedir>/django')

# Set the DJANGO_SETTINGS_MODULE environment variable.
os.environ['DJANGO_SETTINGS_MODULE'] = "<projectname>.settings"

from django.core.servers.fastcgi import runfastcgi
runfastcgi(method="prefork", daemonize="false")

Notice that I am using the dreamhost installed version of Python. I didn't want to fiddle with building my whole own toolchain, so I skipped that and just used theirs. However, I am using the path to python2.4 instead of just python (which defaults to python2.3).

A few other things are worth pointing out in the file as well. First, I installed my django toolchain to $HOME/usr/lib/python, so these paths are needed for everything to get running. Both flup and django are the SVN versions. I simply checked out the respective repositories right there in my library path. The final path is that to my actual Django project code.

With Dreamhost, ensure you are using method="prefork" to invoke your FastCGI process. The default threaded method doesn't work.

Here is my .htaccess file, located in the same place as dispatch.fcgi:

Options +FollowSymLinks
AddHandler fastcgi-script fcgi
RewriteEngine On
RewriteBase /
RewriteRule ^(media/.*)$ - [L]
RewriteRule ^(admin_media/.*)$ - [L]
RewriteRule ^(dispatch\.fcgi/.*)$ - [L]
# For stats pages
RewriteCond %{REQUEST_URI} ^/stats/(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]
# Final rewrite rule
RewriteRule ^(.*)$ dispatch.fcgi/$1 [L]

I think someone was smoking crack when they came up with the syntax for this file, so I felt it was worth posting once I got it right. My comments should help decipher it. Notable things- I want both the media/ and admin_media/ folders to be served by Apache, so those rewrite rules are present. In addition, I wanted access to the stats pages, so those rules are there as well. Finally, the last rewrite rule sends every other request to dispatch.fcgi.

Other tips

In your project settings file, you will need to use `DATABASE_ENGINE = 'mysql_old'', as the Dreamhost installed version is too old to be supported by the rewritten MySQL database engine.

You should let Apache do the dirty work of serving up your media- this folder should be placed right in your web root for your site. However, all of the django stuff should reside elsewhere.

Enabling file-based caching for django is relatively easy and should speed up loading of your site. Add 'django.middleware.cache.CacheMiddleware' as the last middleware in the MIDDLEWARE_CLASSES array, and add the following lines somewhere in the project settings file:

# Caching backend
CACHE_BACKEND = 'file:///<homedir>/path/to/cachedir'
CACHE_MIDDLEWARE_SECONDS = 10800
CACHE_MIDDLEWARE_KEY_PREFIX = '<something>'
CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True

The easiest way to restart your FastCGI process if you change something in one of the Django python files is to simply touch /path/to/dispatch.fcgi, which will do the job. If something seems real persistant, you can use pkill -9 dispatch to do the job as well. Note that my biggest problems were not restarting the process, but making sure I cleaned the Django file-based cache.

blog django dreamhost

First Post!

This is the first official post on my new shiny blog. It is all up and running with Django, which I'm sure I will get into the setup a bit more later. Thanks to Eliott (cactus) for some help with getting a blog application up and running in Django.

Obviously I still have quite a bit of work to do, but this is at least a start to something. Nothing like going live when you are still under development.

blog

Want to see more posts? Take a look at the archives.