tech.agilitynerd.com

scratching that itch... 
Filed under

ubuntu

 

Configuring Runit for Gunicorn and Django Installed in a Virtualenv on Ubuntu

I couldn't find any documentation that covered all the pieces for configuring my latest Django site so I hope this helps someone else out.

I had used mod_wsgi under Apache for my other Django sites. But now I'm using different python versions for the sites (until if/when I update the older sites) and I wasn't getting the correct versions of some python libraries (even though virtualenv apeared to be putting the appropriate python packages at the start of the sys.path). So I decided to configure Apache to ProxyPass to Gunicorn so I could run my Django app in its virtualenv without it getting any other python modules.

Installing Gunicorn

I installed Gunicorn into the virtualenv for my application, which simplifies using gunicorn from the command line. Assuming /home/user/virtualenvs/myapp is the location of the virtualenv:

$ source /home/user/virtualenvs/myapp/bin/activate
$ pip install gunicorn
or
$ easy_install gunicorn

This copies gunicorn_django to the /home/user/virtualenvs/myapp/bin directory. Test gunicorn with your app, assuming your Django app is located at /home/user/source/myapp, as follows:

$ source /home/user/virtualenvs/myapp/bin/activate
(myapp)$ cd /home/user/source/myapp
(myapp)$ gunicorn_django

Gunicorn starts myapp using the settings.py file in the current directory on 127.0.0.1:8000. Ctrl-C to stop the process.

Installing Runit on Ubuntu

There are two runit packages. You want the one that only runs services you add to it:

$ sudo apt-get install runit
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  runit-run socklog-run
The following NEW packages will be installed:
  runit
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0B/113kB of archives.
After this operation, 537kB of additional disk space will be used.
Selecting previously deselected package runit.
(Reading database ... 209845 files and directories currently installed.)
Unpacking runit (from .../runit_2.0.0-1ubuntu2_i386.deb) ...
Processing triggers for man-db ...
Setting up runit (2.0.0-1ubuntu2) ...
runsvdir (start) waiting
runsvdir (start) starting
runsvdir (start) pre-start
runsvdir (start) spawned, process 9575
runsvdir (start) post-start, (main) process 9575
runsvdir (start) running, process 9575

You'll want to create a directory for the application and a run script in /etc/service:

$ sudo mkdir /etc/service/myapp
$ sudo vi /etc/service/myapp/run
# enter the run script I'll show below
$ sudo chmod +x /etc/service/myapp/run
# stop runit from trying to run gunicorn until we are ready
$ sudo sv stop myapp
ok: down: myapp: 0s, normally up

The example run script checked into Gunicorn had some syntax errors and wasn't quite what I wanted. Here's my version:

#!/bin/sh

GUNICORN=/home/user/virtualenvs/myapp/bin/gunicorn_django
ROOT=/home/user/source/myapp
PID=/var/run/myapp.pid

if [ -f $PID ] 
    then rm $PID 
fi

cd $ROOT
exec $GUNICORN -c $ROOT/gunicorn.conf.py --pid=$PID 

You can create a configuration file for gunicorn to use or just create an empty file for now:

$ touch /home/user/source/myapp/gunicorn.conf.py

If you have multiple appserver you'll need to run gunicorn on different ports, you can put the configuration in the gunicorn.conf.py file:

bind = "127.0.0.1:8111"

Putting it Together

Now you can test that the run script works when run as root:

$ sudo /etc/service/myapp/run

Gunicorn should start and start the appserver. If it fails you can debug the script via:

$ sudo bash -x /etc/service/myapp/run

Tell runit to start and keep gunicorn running:

$ sudo sv start myapp
ok: run: myapp: (pid 7540) 0s
$ sudo sv status myapp
run: myapp: (pid 7543) 1s

Filed under  //   apache   django   gunicorn   runit   ubuntu   virtualenv  

Comments [1]

Notes on Configuring Postfix on Ubuntu Gutsy to Send Email via Google Apps

Here are some notes I took on configuring my Slicehost Ubuntu Gutsy installation to use Postfix to send emails via Google Apps. I am far from an expert on postfix configuration but maybe these notes will be helpful to others needing this configuration.

These sites contain the key information:

I basically followed the Behind My Screen tutorial (read the comments too) with the updates from The Prancing Tarantula and the following changes.

My Ubuntu server install didn't have the Thawte certificates installed by default so I installed them.

 

sudo aptitude install ca-certificates

Then you can append that file to your /etc/postfix/cacert.pem If you "sudo su" before doing the append to the file you won't get messed up by the shell:

$ sudo su
# cat /etc/ssl/certs/Thawte_Premium_Server_CA.pem >> /etc/postfix/cacert.pem

Since I have Google Apps setup for my domain I don't just want to relay email as "user@gmail.com", I want the email to be sent as though it came from my domain ("me@agilitynerd.com"). This requires some simple changes to the config files.

In my transport file I have:

agilitynerd.com smtp:[smtp.gmail.com]:587

In my generic file I have:

demo@myservername.agilitynerd.com me@agilitynerd.com

Where "demo" is the login name and "myservername" is my slicename. In my sasl_passwd file I have:

[smtp.gmail.com]:587 me@agilitynerd.com:me_gmail_account_password

After restarting postix you can test sending email from your server:

$ sudo aptitude install mailx
$ mailx -s "test email" someotheraccount@gmail.com < ~/sometestfile_to_send

Check your logfiles for errors/warnings:

sudo tail /var/log/mail.*

I hope these notes might help folks "get over the hump" if they are setting up the same configuration.

 

 

Filed under  //   postfix   slicehost   ubuntu  

Comments [0]