Deploying bottle on apache took me some time today which I hope to not repeat. Due to some of my mistakes and errors, I tripped myself up in a mess. I screwed up a new vhost entry on apache because it defaulted back to my default entry. It took me a while to realize I needed a ServerName entry in my new vhost file...
From there I copied some crazy configurations I found through google. They seemed geared towards some other distributions. At the end, I was able to slim my configuration down to several simple files that work.
Lets go over the system I am working on:
- debian squeeze - fresh install of 6.0.5
- apache - Apache/2.2.16 (Debian) This is the special apache setup
- bottle - latest one from github
- virtualenv - 1.4.9
First step is first... make sure you can get the default vhost entry operational. I know you want to skip that step, but don't skip it. Sometimes other things break. Make sure you can at least get that setup. Additionally, you should create a second vhost entry with a different ServerName.
The reason you found this article is because you have many projects you want to host on a server. You have different virtual environments for each python project with different libraries. Keeping these projects isolated is a great idea but serving them up isolated is better.
Let's go into the /opt directory as root and create a directory for my user jarvis:
root@palmtree:~$ cd /opt root@palmtree:/opt$ mkdir jarvis root@palmtree:/opt$ chown -R jarvis:jarvis jarvis
Let's create the virtualenv in the /opt directory:
jarvis@palmtree:/opt/jarvis$ virtualenv --no-site-packages test jarvis@palmtree:/opt/jarvis$ cd test jarvis@palmtree:/opt/jarvis/test$ source bin/activate jarvis@palmtree:/opt/jarvis/test$ mkdir src jarvis@palmtree:/opt/jarvis/test$ cd src jarvis@palmtree:/opt/jarvis/test/src$ touch test.py jarvis@palmtree:/opt/jarvis/test/src$ touch dispatch.wsgi
Create a test.py file for bottle to run:
from bottle import route, run, request @route('/', method='GET') def index1(): return '<h1>HELLO</h1>' @route('/hello/:name', method='GET') def index(name='World'): return '<b>Hello %s!</b>' % name
Create a dispatch.wsgi file for apache to run:
import sys, os # ... build or import your bottle application here ... import bottle import test # Do NOT use bottle.run() with mod_wsgi application = bottle.default_app()
Go to your apache sites-available directory and copy the default vhost into a new entry:
root@palmtree:~# cd /etc/apache2/sites-available/ root@palmtree:~# cp default test
Grab your favorite editor and edit the new vhost entry called test:
<VirtualHost *:80> ServerName test.example.net WSGIDaemonProcess ptest display-name=%{GROUP}\ threads=4 \ python-path=/opt/jarvis/test/src:/opt/jarvis/test/lib/python2.6/site-packages WSGIProcessGroup ptest WSGIScriptAlias / /opt/jarvis/test/src/dispatch.wsgi Alias /robots.txt /opt/jarvis/test/src/apache_static/robots.txt Alias /favicon.ico /opt/jarvis/test/src/apache_static/favicon.ico <Directory /opt/jarvis/test/src> Order allow,deny Allow from all </Directory> ErrorLog ${APACHE_LOG_DIR}/test_error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog ${APACHE_LOG_DIR}/test_access.log combined </VirtualHost>
Activate the conf file, and restart Apache:
root@palmtree:~# a2ensite test root@palmtree:~# services apache resart
The key to getting this simple configuration to work is in step 6. The line with python-path needs the path to the test.py bottle file and the site-packages directory for the virtualenv that was created. Hopefully this works for you!