Sep 25 2008

Setting up Django on a WHM/cPanel VPS (LiquidWeb)

Tag: Programming & InternetDustin @ 5:55 am

I ordered a new VPS from LiquidWeb for the purpose of using it to host our company’s new product that I’m currently writing in Django. I have another VPS with LiquidWeb and I highly recommend them!

I got Django up and running on my other server with some help of LiquidWeb support. This time I’m going to attempt to do it on my own and document the process as I’m sure this won’t be the last time I need to set this up. Hopefully, it can help someone else out there looking to do the same.

Python 2.4.3 is installed by default. My original plan was to use Python 2.5.2, but I had problems compiling database bindings with 2.5, so I finally gave up and decided to stick with 2.4.

Install PostgreSQL & Python Database Bindings

I’m quite familiar with MySQL, but knowing that Django creators have a fondness for PostgreSQL, I thought I might attempt to use it for this project. (My development so far has been using SQLIte, but I don’t think that it will be adequate for this project). I didn’t have PostgreSQL installed, but installing it was pretty straight forward. cPanal has an installer script (thanks LiquidWeb support for the tip):

 

# /scripts/installpostgres

 

 

After installation, I set the password in WHM and now the database options appeared in cPanel:

image

Just follow the wizard to create your database.

Next, I installed psycopg to bind python to PostgreSQL.

 

# cd /usr/local/src
# wget http://initd.org/pub/software/psycopg/psycopg2-2.0.8.tar.gz
# tar xzvf psycopg2-2.0.8.tar.gz
# cd psycopg2-2.0.8
# python setup.py build
# python setup.py install

 

 

Build and Install WSGI

Basically, here are the commands I ran to download and complie wsgi:

cd /usr/local/src/
wget http://modwsgi.googlecode.com/files/mod_wsgi-2.3.tar.gz
gzip -dc mod_wsgi-2.3.tar.gz | tar xf -
cd mod_wsgi-2.3
./configure
make && make install

After compiling the module, I was given the path to where it was located (/usr/lib/httpd/modules/mod_wsgi.so).

I logged in to WHM -> Server Configuration -> Apache Setup -> Include Editor to add the following line to load the module:
image

LoadModule wsgi_module /usr/lib/httpd/modules/mod_wsgi.so
AddHandler wsgi-script .wsgi

image

If it works for you… Lucky you. Unfortunately I got this error:

Configuration problem detected on line 220 of file /usr/local/apache/conf/httpd.conf: : Syntax error on line 1 of /usr/local/apache/conf/includes/pre_virtualhost_2.conf: API module structure ‘wsgi_module’ in file /usr/lib/httpd/modules/mod_wsgi.so is garbled - expected signature 41503232 but saw 41503230 - perhaps this is not an Apache module DSO, or was compiled for a different Apache version? — /usr/local/apache/conf/httpd.conf — 214 215 216 217# SUEXEC is supported 218 219Include “/usr/local/apache/conf/includes/pre_virtualhost_global.conf” 220 ===> Include “/usr/local/apache/conf/includes/pre_virtualhost_2.conf” <=== 221 222# DO NOT EDIT. AUTOMATICALLY GENERATED. IF YOU NEED TO MAKE A CHANGE PLEASE USE THE INCLUDE FILES. 223NameVirtualHost * 224 225# Default vhost for unbound IPs 226 — /usr/local/apache/conf/httpd.conf —

My first thought was that I had two versions of Apache installed, but I noticed my ./configure command said it found Apache 2.2.9. I asked LiquidWeb Support and they said that it was likely because I needed FastCGI installed.

So in WHM again, I went to Software -> Apache Update and reinstalled Apache and added fastcgi support.

That didn’t help either.

So I posted to the modwsgi google group and got help from the modwsgi author himself, Graham Dumpleton and was able to install the correct version by specifying the apxs file located in /usr/local/apache/bin/. So back in /usr/local/src/mod_wsgi-2.3, I ran the following commands to rebuild modwsgi:

# make distclean
# ./configure --with-apxs=/usr/local/apache/bin/apxs
# make && make install

The output was more concise this time. Then I when back into WHM -> Server Configuration -> Apache Setup -> Include Editor and loaded the module and restarted apache and it all worked this time! Thank you Graham!

I followed the Quick Configuration Guide to test WSGI to make sure it was working and learn a bit more about how it works. I recommend that you do too. Everything worked by the way. Well come back to modwsgi setup in a moment, but first we need to install Django.

Install Django

Download and installation of Django 1.0 was quite simple really - the easiest part of the gig.

cd /usr/local/src
wget http://www.djangoproject.com/download/1.0/tarball/
tar xzvf Django-1.0.tar.gz
cd Django-1.0
python setup.py install

Run Baby, Run

Now, we attempt to put it all together!

This set up will need to be run per domain/account. First, lets create our wsgi app that will call the Django application.

I already have my account set up on WHM where I will run my Django app. It is fcabi.net and the username is fcabi, so where every you see this, be mindful to replace it with your specifics.

Create a file in /home/fcabi/public_html with the following python code:

 

import os, sys
sys.path.append('/home/fcabi/public_html')
sys.path.append('/home/fcabi/public_html/fcabinet')
os.environ['DJANGO_SETTINGS_MODULE'] = ‘fcabinet.settings’

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

 

 

Next I create a file to add my virtual host directives in.

 

# mkdir -p /usr/local/apache/conf/userdata/std/2/fcabi/fcabi.net/
# vi /usr/local/apache/conf/userdata/std/2/fcabi/fcabi.net/wsgi.conf

 

 

I enter the following:

 

<IfModule mod_alias.c>
Alias /robots.txt /home/fcabi/public_html/fcabinet/media/robots.txt
Alias /favicon.ico /home/fcabi/public_html/fcabinet/media/favicon.ico
Alias /media /home/fcabi/public_html/fcabinet/media
Alias /adminmedia /home/fcabi/public_html/fcabinet/media/adminmedia
</IfModule>

<IfModule mod_wsgi.c>
WSGIScriptAlias / /home/fcabi/public_html/django.wsgi
WSGIDaemonProcess django threads=15 display-name=%{GROUP}
WSGIProcessGroup django
WSGIApplicationGroup %{GLOBAL}
</IfModule>

 

 

Next I run the cPanel script to add the include file to the main httpd.conf file and make sure the changes stick, then I restart apache.

 

# /usr/local/cpanel/bin/build_apache_conf

 

 

After running this command, I should see the Include to the file I just created:

 

<VirtualHost 67.227.189.54:80>
    ServerName fcabi.net
    ServerAlias www.fcabi.net
    DocumentRoot /home/fcabi/public_html
    ServerAdmin webmaster@fcabi.net
    UseCanonicalName Off
    CustomLog /usr/local/apache/domlogs/fcabi.net combined
    CustomLog /usr/local/apache/domlogs/fcabi.net-bytes_log "%{%s}t %I .\n%{%s}t %O ."
    ## User fcabi # Needed for Cpanel::ApacheConf
    <IfModule !mod_disable_suexec.c>
        SuexecUserGroup fcabi fcabi
    </IfModule>

Include “/usr/local/apache/conf/userdata/std/2/fcabi/fcabi.net/*.conf”

</VirtualHost>

 

 

It’s there, so I restart apache.

 

# /usr/sbin/apachectl restart

Notice that I added an alias to adminmedia. To get this to work, I also had to add a symbolic link to to the contrib/admin/media files:

# ln -s /usr/local/lib/python2.4/site-packages/django/contrib/admin/media/ /home/fcabi/public_html/fcabinet/media/adminmedia

 

Bonus: Wildcard Subdomains

My application makes use of wildcard sub-domains, so I also needed this to work as well. This was fairly easy to implement.

Log in to cPanel and click on Subdomains:
image

For the subdomain, enter “*” and click create (Document Root may autopopulate with “/public_html”, this is normal).

Now, set up virtual host directives for this subdomain like you did with your original domain.

 

# mkdir -p /usr/local/apache/conf/userdata/std/2/fcabi/wildcard_safe.fcabi.net/
# vi /usr/local/apache/conf/userdata/std/2/fcabi/wildcard_safe.fcabi.net/wsgi.conf

 

 

Enter the following:

 

<IfModule mod_alias.c>
Alias /robots.txt /home/fcabi/public_html/fcabinet/media/robots.txt
Alias /favicon.ico /home/fcabi/public_html/fcabinet/media/favicon.ico
Alias /media /home/fcabi/public_html/fcabinet/media
</IfModule>

<IfModule mod_wsgi.c>
WSGIScriptAlias / /home/fcabi/public_html/django.wsgi
WSGIDaemonProcess django-sub threads=15 display-name=%{GROUP}
WSGIProcessGroup django-sub
WSGIApplicationGroup %{GLOBAL}
</IfModule>

 

 

* Notice the the WSGIDaemonProcess name is must be different.

Rebuild the config file and restart apache.

# /usr/local/cpanel/bin/build_apache_conf
# /usr/sbin/apachectl restart

PS. If you’re using sub-domains, you might find my sub-domain middleware useful.


Sep 22 2008

I Hate RC Willey

Tag: YadaDustin @ 9:49 am

image So it was labor day. For some reason - likely do to excessive advertising, I think of RC Willey on Labor day. My wife has been wanting a bedroom set. We were planning on ordering from Canopy, but I thought it would be fun to go look at RC Willey and see if they had any sales going on. Big mistake!

So we found a set we liked and decided to order. We were told we could pick it up at the warehouse, way out west, so we drove down to Alpine and borrowed my father-in-law’s truck, since my truck was not registered at the moment (a long crazy story).

Once we get there we were told that the bed frame was on back order and won’t be available until next month. Frustrated and angry, I told them to cancel the order. One the way back I called the salesman (Michael F. Langeland) and asked if he knew that information and didn’t bother telling us just so he could get his commission. He said he wasn’t aware of that. He pulled it up in the computer and said, yeah, the bed is on back-order.

We looked around at other furniture sets and we decided to order the Canopy one we wanted originally, but found that one piece we wanted was also not in stock. So as long as we were going to wait, we figured we would get the RC Willey furniture because it was a little cheaper and we wouldn’t have to put it together. So we called back and said, OK we’ll get this set as long as you deliver it free. We were still mad about wasting all the gas to go pick it up. So that deal was made. In the process of that deal they double billed us.

A few days later my wife is wondering when they are going to arrive with the furniture that was in stock. So she called and learned that no delivery was ever scheduled and now all of the furniture set was on back order. We were really annoyed with our salesman now, so we went in to another store to talk with another salesman (we didn’t want Michael to get any commission at this point) and look around at other furniture sets. We found something we like, but a bit more expensive. So we decided to just cancel our order and save a bit longer. We stood in line and eventually had them cancel our order and fix the double billing problem and return all the money to our account.

So now its two weeks later. We’ve had one charge returned but still have $1100+ that needs to be returned to our account. It shouldn’t take two weeks to get a return right? So I called again to find out what is going on. It turns out they never canceled our order. The question was “so you don’t want your bed?” Uh, no! We were in the store and we canceled that. The response was. “No, you didn’t. Do you want to cancel it now?” Oh, I didn’t huh? Whatever. “YES. CANCEL IT!” Now it can’t just be that easy. She said, “you’ll have to call back at ten o’clock to speak with a cashier to get your money back.” Seriously, it was 9:56!

So I called back and I think I got it taken care of. But something that urks me about the whole process is how everyone seems to treat me like I’M stupid.

“What’s your account number?”

“I don’t know”

“What’s your social security number… You account doesn’t come up with that. What do you need?”

I need my money back. Then I swear, I’ll never BOTHER you people again!


Sep 19 2008

Windows Live Writer

Tag: YadaDustin @ 8:53 am

This is a test post from Windows Live Writer.

Someone said it was the "bomb diggity" so I had to check it out!

Not bad indeed!

It certainly looks cool:
image 

And it’s like editing directly in my blog as it uses my existing CSS!

Wow!


Sep 11 2008

Django Accounts on Subdomains

Tag: Programming & InternetDustin @ 11:33 am

*Disclaimer: I’m a Django and Python newbie. Your mileage may vary following my advice.

My Goal is to create an accounts system similar to Unfuddle, where to register for a new account, a user will enter a subdomain and admin login (see Unfuddle registration).

Users can’t really log in from the home page - only from their subdomain. Once they are logged in, administrators can add more users that only have access to that subdomain.

FYI, I’m not competing against Unfuddle. I’m just very familiar with their system as I am a happy paying user. There are a number of other sites using this kind of accounting system. I’m sure I could implement it in PHP, but I really want to learn Django so I’m sticking with it on this project.

I would like to give props to the developers of Unfuddle as they have been more than helpful in reguards to sharing the structure of their application and the way they do things. Thanks guys! I’m sure if I were writing this in Ruby on Rails they would be even more helpful as their application is written in Rails.

Now, back to the show.

I’m trying to use as much pre-existing code as possible so I can take advantage of others knowledge and so I don’t have to reinvent any wheels.

I’m doing my development and testing on Windows. So in order to test this, I’ve edited my hosts files (C:\WINDOWS\system32\drivers\etc\hosts) with my main domain and a few subdomains that I want to test. When I go live, I will likely remove these from the hosts files and set up wildcard dns & subdomains on the server.

Here is an example of my hosts file entries used to test:

127.0.0.1    sample.com
127.0.0.1    www.sample.com
127.0.0.1    test.sample.com
127.0.0.1    company.sample.com
127.0.0.1    django.sample.com
127.0.0.1    nerd.sample.com
127.0.0.1    dork.sample.com

So far, this is what I’ve done to implement:

1. Install django-registration - I just checked out the latest source and plugged the registration folder into my project. Once I got it set up, I added a field to the form.

This is still a work in progress so I’ll have to come update later. Basically my goal is to have a registration form that also asks for the subdomain and title of the user or company. Then I will append the subdomain to the username before saving it to the Users table so that username can be unique within sub-domains.

2. I created a simple middleware inside my application. This basically reads the HTTP_HOST and sets request.domain and request.subdomain. If there is no subdomain, or the subdomain is ‘www’, then it returns and empty string.

3. My main template will have a link to log in. If they are on their subdomain they will see the login screen (I’m using django.contrib.auth for authentication and login forms). If they are on the main site, they will first be asked for their subdomain. After entering their subdomain, they will be redirected.

Here are the contents of my app’s login function.
The subdomain form and template are quite trivial to create.

I hope this helps someone. I hope to expand this post when I get further into it.


Sep 11 2008

Setting up Wildcard DNS & Subdomains on cPanel

Tag: Programming & InternetDustin @ 8:18 am

*** UPDATE: DON’T READ THIS POST… JUST READ COMMENT #2 FROM CPANEL ***

I’ve posted instructions in the past on how to set up wildcard DNS and subdomains on DirectAdmin. DirectAdmin makes it rather trivial, which is quite nice. There is a little bit more effort involved in cPanel - manly because you actually have to make some modifications via SSH. So I would say this tutorial involves and intermediate skill level to accomplish (it can’t be more because this is about the extent of my skill level). You will need access to WHM and root access to your server.

Background: I’m currently learning Django and trying to create a solution for sub-domaining accounts. I’ve been told by a few people that this will be the hardest part to set up. At my currently Django level, this part is trivial. I hope to make more posts when I get the Django parts figured out as well. Stay tuned.

Step 1: DNS: A Record

First we’ll need to log in to WHM. Under DNS Functions, select Edit DNS Zone. Choose the domain for the zone in which you wish to edit. Add an A record mapped to asterisk (wildcard) for the subdomain and the IP Address the site is hosted on. You likely already have A records for ftp, webmail, etc. just model this new one after those.

You should now be able to enter any subdomain on your domain, but it will not likely find your main site. So now we need to set that up.

Step 2: ServerAlias

Log in to your server via SSH and go open /etc/httpd/conf/httpd.conf (I’ll assume you know your way around linux via command line as well as vi or some other editor)

*Note: wherever you see deqb.com you should expect to see your domain name that you are setting up

Now, we could edit this file and make everything work, but there is a problem with that. Look at the top of the document and you should see something like this:

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#   Direct modifications to the Apache configuration file may be lost upon subsequent regeneration of the       #
#   configuration file. To have modifications retained, all modifications must be checked into the              #
#   configuration system by running:                                                                            #
#       /usr/local/cpanel/bin/apache_conf_distiller –update                                                    #
#   To see if your changes will be conserved, regenerate the Apache configuration file by running:              #
#       /usr/local/cpanel/bin/build_apache_conf                                                                 #
#   and check the configuration file for your alterations. If your changes have been ignored, then they will    #
#   need to be added directly to their respective template files.                                               #
#                                                                                                               #
#   It is also possible to add custom directives to the various “Include” files loaded by this httpd.conf       #
#   For detailed instructions on using Include files and the apache_conf_distiller with the new configuration   #
#   system refer to the documentation at: http://www.cpanel.net/support/docs/ea/ea3/customdirectives.html       #
#                                                                                                               #
#   This configuration file was built from the following templates:                                             #
#     /var/cpanel/templates/apache2/main.default                                                                #
#     /var/cpanel/templates/apache2/main.local                                                                  #
#     /var/cpanel/templates/apache2/vhost.default                                                               #
#     /var/cpanel/templates/apache2/vhost.local                                                                 #
#     /var/cpanel/templates/apache2/ssl_vhost.default                                                           #
#     /var/cpanel/templates/apache2/ssl_vhost.local                                                             #
#                                                                                                               #
#  Templates with the ‘.local’ extension will be preferred over templates with the ‘.default’ extension.        #
#  The only template updated by the apache_conf_distiller is main.default.                                      #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

Basically what it’s saying is don’t edit this file directly because you’re changes may be lost.

Do a search for the domain you are adding the wildcard to. You should find the VirtualHost set up for your domain. Here is mine:

# DO NOT EDIT. AUTOMATICALLY GENERATED.  IF YOU NEED TO MAKE A CHANGE PLEASE USE THE INCLUDE FILES.

<VirtualHost 67.225.128.241:80>
    ServerName
deqb.com
    ServerAlias www.deqb.com
    DocumentRoot /home/deqb/public_html
    ServerAdmin webmaster@deqb.com
    UseCanonicalName Off
        Options -ExecCGI -Includes
        RemoveHandler cgi-script .cgi .pl .plx .ppl .perl
    CustomLog /usr/local/apache/domlogs/deqb.com combined
    CustomLog /usr/local/apache/domlogs/deqb.com-bytes_log “%{%s}t %I .\n%{%s}t %O .”
    ## User deqb # Needed for Cpanel::ApacheConf
    <IfModule !mod_disable_suexec.c>
        SuexecUserGroup deqb deqb
    </IfModule>

    # To customize this VirtualHost use an include file at the following location
    # Include “/usr/local/apache/conf/userdata/std/2/deqb/deqb.com/*.conf”

 

</VirtualHost>

Notice the highlighted lines. This is where we are going to create a file. We are going to create a file at:
/usr/local/apache/conf/userdata/std/2/deqb/deqb.com/ServerAlias_wildcard.conf
(you can give it any name you want really)

*Hint: You may need to create the directories first, run this command:
mkdir -p /usr/local/apache/conf/userdata/std/2/deqb/deqb.com/

So really, you don’t need to edit anything it httpd.conf, we just needed some info.

Inside of the ServerAlias_wildcard.conf file, enter this line:
ServerAlias *.deqb.com

Now, you’ll need to rebuild the httpd.conf file per the instructions at the top of that file by running the following command:
/usr/local/cpanel/bin/build_apache_conf

If you open your /etc/httpd/conf/httpd.conf file again you should see that your VirtualHost for your domain as changed slightly:

<VirtualHost 67.225.128.241:80>
    ServerName
deqb.com
    ServerAlias www.deqb.com
    DocumentRoot /home/deqb/public_html
    ServerAdmin webmaster@deqb.com
    UseCanonicalName Off
        Options -ExecCGI -Includes
        RemoveHandler cgi-script .cgi .pl .plx .ppl .perl
    CustomLog /usr/local/apache/domlogs/deqb.com combined
    CustomLog /usr/local/apache/domlogs/deqb.com-bytes_log “%{%s}t %I .\n%{%s}t %O .”
    ## User deqb # Needed for Cpanel::ApacheConf
    <IfModule !mod_disable_suexec.c>
        SuexecUserGroup deqb deqb
    </IfModule>

    Include “/usr/local/apache/conf/userdata/std/2/deqb/deqb.com/*.conf”

</VirtualHost>

 

Step 3: Restart Apache

The last step required is to restart apache. I suppose there are a number of ways to do this. As long as we are logged in to SSH, we might as well just run the command:
/usr/sbin/apachectl restart

Now, give it a try. you should be aby to access something like http://itworked.deqb.com and still see your main page.

Technorati Tags: , , , , ,


Sep 10 2008

Gmail + Thunberbird = WOW

Tag: Programming & InternetDustin @ 6:12 am

I’ve been using Gmail as my main email client for about the past 4 years or so. I currently have Thunderbird set up with SMTP to use for certain situations - mainly when I want to copy and past images in - like showing screenshots to people. (I still prefer the speed of the web app - and being able to make it look like an app with Google Chrome/Google Gears is just that much sweeter)

Today I noticed something really cool. I got an email request from a client for updates to his website. I was composing a reply in Thunderbird with screenshots and all. In the process, I had a Gmail client open (in Google Chrome) and I was reading his initial email again to make sure there wasn’t something I missed.

At the bottom of the screen it said there was a new message with a link to update the conversation. I’ve seen this before on rare occassions. I figured he had sent me a follow up email. When I clicked the update link I saw the draft of the message I was composing in Thunderbird - screenshots and all. How cool is that?

Ok, maybe I’m over dramatic. But I thought it was neato!

Technorati Tags: ,




ss_blog_claim=4973c51f5e7bec57951f995fed1b85f3 ss_blog_claim=4973c51f5e7bec57951f995fed1b85f3