原文http://www.winged.ch/blog/3/
Cherokee and Django
Published: 2009-09-05 22:31
Comments: 2
A friend asked me about how I've set up my web server, and how I've configured
Django, Cherokee etc. So I decided to write a short tutorial on how to proceed.
I'm going to assume that you know how to handle a UNIX/Linux-based server, and
make sure you're comfortable handling the shell ;)
The article got a bit long, but bare with me, you're gonna learn a thing or two.
And if you already know some stuff, you can skip a few sections, I won't send the
hangman after ya.
Installing Cherokee, Django, Postgresql
My Server was set up as an ubuntu 9.04 machine. However, a few software
components are a bit dated, as they need to look for stability and so on... you
know the drill.
So, where was I? Right, Cherokee.
You can get a recent Cherokee binary from here.
Just add the line to your /etc/apt/sources.list and import the PPA's signing key.
Here's how to go if you're in a hurry*. Be sure to use TWO >'s here... or you're in trouble.
$ echo deb http://ppa.launchpad.net/cherokee-webserver/ppa/ubuntu jaunty main >> /etc/apt/sources.list
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EBA7BD49
Now we're ready to install the webserver.
$ sudo apt-get update
$ sudo apt-get install cherokee
The next step is easy, as Jaunty has a pretty recent version of Postgresql. Note that
you can use MySQL as well here, but I'm using Postgresql.
$ sudo apt-get install postgresql
Now we need to create a user for your application, and a database as well. For this, we
need to create a new user. Run this to become the postgres user. In the default installation,
this is the only way to get into postgresql with admin rights.
$ sudo su - postgres
This following command should put you in an SQL shell, with admin rights:
$ psql
Now create the user to access the database later:
postgres=# CREATE USER my_webapp LOGIN PASSWORD 'mypasswd';
Create the database. Note the encoding and the owner!
postgres=# CREATE DATABASE webapp ENCODING 'utf-8' OWNER my_webapp;
Now your database is ready. Get out of the SQL shell (CTRL-D), and out of
postgres's shell too.
Installing django is easy. I started development with the 1.0 branch and I didn't
update to 1.1 yet, so I was happy with the django version that's coming with ubuntu:
$ sudo apt-get install python-django
But... you will need something more to get django running with cherokee and Postgresql:
$ sudo apt-get install python-flup python-psycopg2
The deployment
Now.. to get your Django application online, create a new user for your project:
$ sudo useradd -m my_webapp
$ sudo passwd my_webapp
The -m flag tells the useradd tool to automatically create the home directory
for you.
Before we continue, you go get your django app and put it in this new user's home
directory, configure it to access the right database, run django-admin syncdb
or whatever you need to get the installation working. I'll wait here for you.
Back? Good.
Now, there are two ways of setting up Cherokee for your web app. A very easy,
but inflexible way (it works, but you don't know why), and a way that requires
a little bit more work (If it doesn't work, you'll know why).
The first way would be to use Cherokee's new platform wizard. However, it just
creates a standard setup (and names things with just numbers), so I prefer the
second way.
Sooo... back to setting up Cherokee. Maybe you've already read about it, but:
We're not going to hack config files. Cherokee has a nifty configuration interface
that is very easy to use. Here's how:
Configuring Cherokee
$ sudo cherokee-admin
This command starts a web interface and prints out all the information to access
it - note how it creates a temporary password for extra security:
Login:
User: admin
One-time Password: VbBr4P2azYE8RJEW
Web Interface:
URL: http://127.0.0.1:9090/
Now point your browser to that URL. Obviously, you need to change the IP address
to the address of the actual server. But I don't need to tell you this. Sorry.
Before we continue, let's take a short digress into the organisation of Cherokee's
configuration: As you can see, the menu shows, among a few other things, two entries
labeled "Virtual Servers" and "Information Sources". Virtual servers are exactly
what you think. You configure domain names, behaviour on URLs, logging here.
Information sources are the way more interesting part, so let's do one of these!
An information source tells Cherokee what to do with an incoming request. After
creating one or more information sources, you can then connect virtual servers to them.
As you will see later, you can connect subdirectories to an information source, or
a regex (for example, match all requests to a PHP file and give it to an information
source that calls the PHP interpreter. But fortunately, we're not going to need this).
Creating an information source
So, what do I need to fill in those fields here? (I didn't need to tell ya to click
on "Information Sources", right? You're a coder or an admin, as far as I can see).
The Nickname is just something for you to remember. The connection... let's write a
path to a socket here. I've put /home/my_webapp/xlist.sock in mine.
Now the interpreter is a bit more complicated. Basically, you put your manage.py call
here. However, since we're not in development here, we don't want python to run the
web server. And since you want to be able to restart the application, and since
Cherokee needs something on the other side of the socket... you'll need a bit more
than the default options.
And there's a little problem you're probably not forseeing right now: As this line will be
run as your normal user instad of cherokee's, the created socket won't be readable by the
webserver process. So.. instead of writing a long manage.py line directoy into that field,
let's create a small bash scritpt that handles this for us. Put the file
in /home/my_webapp/runserver.sh.
#!/bin/bash
PIDFILE=/home/my_webapp/xlist.pid
SOCKFILE=/home/my_webapp/xlist.sock
# kill a possibly running instance
kill $(<$PIDFILE)
rm $SOCKFILE
# run in background so we can chmod the socket afterwards
/home/my_webapp/winged_xlist/manage.py runfcgi \
pidfile=$PIDFILE \
socket=$SOCKFILE \
daemonize=True
# stop if app start fails
if [ $? -ne 0 ]; then
exit $?
fi
# now wait for the socket to be created, then chmod it.
while [ ! -S $SOCKFILE ]
do
sleep 1
done
chmod a+rw $SOCKFILE
Note the script does not care much about protecting the socket file. This isn't
actually so bad, as any request a malicious user could put in via the socket file
could also be made via webserver. And if you already have malicious local users,
you're in trouble anyhow. Maybe not you but the server admin, but.. still, there's
trouble. But the point is it doesn't make your application less secure.
Now chmod +x the file and enter it as the interpreter line. I assume you changed
the paths to your needs.
The spawning timeout should be fairly enough, but if you're on a shared server, and
your codebase is big, you should put a longer timeout there, like 10 seconds or so.
This is not gonna make your app slow, as it is only started once if everything's okay.
Execute as User, Execute as Group: Since we don't want the code and passwords and
stuff to be readable if the web server gets compromised, put in the user and group
that we created before. Here, it is "my_webapp" in both fields.
Note how Cherokee saves the config each time you're done entering a value. To be sure,
click somewhere outside of the input fields to be sure it saves your last change.
This was it! Your first information source is ready to use!
So let's create a virtual server! I'm so excited! We're almost online!
Virtual Server Setup
Click on that "Add new Virtual Server" button you see in the Virtual Servers menu.
Give it a nickname and a document root. Since we're not going to access files
directly, I usually put a fake docroot there. But the path must exist, so create
some unused directory you can abuse. But DO NOT use a directory that you're actually
gonna put stuff in - and make it read-only please. Don't worry about the static
content from Django, we'll get to this.
So now you have your new virtual server. Click on it's name!
We don't need to do anything in the Basics tab, so let's skip over to the "Host Match".
As you can see, I've already added two wildcard matches. You could also add Regexes
instead, but normally, the normal wildcard match is sufficient.
The last thing you need now is to configure the behaviour. Behaviours match the request
in various ways, then decide what to do with it. As you can see, a few have already
been created for you. Delete all but the Default one (you can't anyway :P).
Click on the Default rule's name. You will land on the details page. We can't to
do anything more to the rule, so let's go over to the "Handler" tab.
Select the FastCGI option from the dropdown to get the fields shown here.
You can leave everything as is, except the "Check file" option. Turn it off. Otherwise,
Cherokee will not even pass the request to Django if a file with your URL does not
exist. Which would be stupid.
Okay, I lied. There's one other thing you need to do on this page. See the little
dropdown labeled "Application Server" at the bottom? Do you recognize the entry
you've got there? Yep, it's our information source! Yay! Let's select it!
Now let's see if this works. Select "Graceful restart" in the left panel and
click "Save". If everything went fine, you should get a nice green confirmation.
When you point your browser to the server you just created, you should be seeing
your web application in all it's glory.
All it's glory? No. All the nice CSS, the pictures, everything.. is missing! HELP!
Configuring Static File Delivery
Okay, I promised you to get back to the static file stuff before, so let's do that.
Let's go back to our virtual server and add a rule or two.
What you need here is a bit different depending on how you configured your
Django app. I have a /static directory that contains all the CSS and images, so
I'll add a new "Directory" rule with the "Web Directory" obviously being
"/static". Don't worry about the zapping around after you've entered the directory,
Cherokee is just being helpful here.
Switch to the Handler tab now and choose the "Static content" handler. This differs
from the "List&Send" insofar as "Static content" doesn't do directory listings.
Enter the path to the static content and save the server's config, again, doing
a graceful restart.
If you have more static directories (for example the django admin panel), just
repeat as needed.
Congratulations! You are now running your Django application with Cherokee!
* Note: You should NEVER be in a hurry when setting up a server. This is serious
business!
Also note: If you have trouble getting this set up, please drop me a comment below,
or send me an e-mail. You can reach me at dave AT winged DOT ch.