This post is meant to be informative, as I have been trying to get this working on my server for about a week now and I've finally got what I wanted. Sorry in advance if this turns out to be really long, but I'm hoping that my hard work and research will help someone else in the same situation.
Let's start with a problem statement: How do I run multiple web2py applications all using different domains/subdomains AND make those sites usable with SSL on Apache? Oh, and while we're at it, how do we keep existing PHP sites working? I am using Ubuntu 10.04 as a LAMP server in production and want to start hosting multiple web2py sites/applications on it as well.
The best recommendation I can make as far as getting web2py installed is to follow the documentation:
You will want to read the Apache Setup section and the first part of the mod_wsgi section where web2py is downloaded, unziped and owned by www-data. After that, the Apache config files mentioned are great for simple server setups, but we want something more complex, so we will make our own.
First let's go over what we have and what we need:
We have an existing PHP app running on
oldapp.com. We have two web2py applications that we want to run and we have two domains for them:
exampleapp.com and
anotherexample.com. If you want to run any of these sites on SSL, then you need to get certificates for them. If they are simple apps, then you can get free 1-year certificates from StartSSL.com. I won't go into detail about how to get these certificates or decrypting the private keys, as that is a fairly broad topic and the documentation from your chosen certificate authority can probably explain it better than I can.
So now we assume you have your SSL certificates, now it's time to configure Apache and web2py. First, let's take care of the PHP application. Hopefully you will have each PHP site in it's own VirtualHost file, and not called 000-default. If it is, then you will need to run the following commands to disable the site, rename it, and re-enable it:
sudo a2dissite 000-default
sudo mv /etc/apache2/sites-available/000-default /etc/apache2/sites-available/php-oldapp
sudo a2ensite php-oldapp
sudo /etc/init.d/apache2 restart
Check to make sure your PHP site is still working, as we're done with that. Next, we need to create a default web2py configuration. So run your preferred text editor to create a new default file (I'll use nano here for simplicity):
sudo nano /etc/apache2/sites-available/000-default
Now, put the following in your new configuration file:
# This is the default VirtualHost and should be the first VirtualHost
# This is required in order to run SSL web2py sites
NameVirtualHost *:443
# Make this process global so that other VirtualHosts can access it (i.e. SSL sites)
WSGIDaemonProcess web2py user=www-data group=www-data display-name=%{GROUP}
<VirtualHost *:80>
WSGIProcessGroup web2py
WSGIScriptAlias / /var/repositories/web2py/wsgihandler.py
<Directory /var/repositories/web2py/>
AllowOverride None
Order Allow,Deny
Deny from all
<Files wsgihandler.py>
Allow from all
</Files>
</Directory>
AliasMatch ^/([^/]+)/static/(.*) \
/var/repositories/web2py/applications/$1/static/$2
<Directory /var/repositories/web2py/applications/*/static/>
Order Allow,Deny
Allow from all
</Directory>
<Location /admin>
Deny from all
</Location>
<LocationMatch ^/([^/]+)/appadmin>
Deny from all
</LocationMatch>
CustomLog /var/log/apache2/access.log common
ErrorLog //var/log/apache2/error.log
</VirtualHost>
This configuration file will run all of your non-SSL web2py sites. You can map domain names to applications with web2py's routes.py file (which we will see later) without ever having to touch this Apache configuration file again. To test this, enable the site and restart Apache:
sudo a2ensite 000-default
sudo /etc/init.d/apache2 restart
web2py should be working now, but it may not work the way we want yet, as we have not configured its routers.py file yet. Now we need to set up SSL for our sites. In order to do this, we need a Apache configuration (VirtualHost) file for each domain/application. This is because each domain needs its own certificate and it's best to let Apache handle this for us. We need to make another file for our SSL-enabled exampleapp:
sudo nano /etc/apache2/sites-available/web2py-exampleapp-ssl
Put the following in the new configuration file:
<VirtualHost *:443>
ServerName exampleapp.com
ServerAlias *.exampleapp.com
SSLEngine on
SSLCertificateFile /var/repositories/web2py/exampleapp.com.crt
SSLCertificateKeyFile /var/repositories/web2py/exampleapp.com.key
WSGIProcessGroup web2py
WSGIScriptAlias / /var/repositories/web2py/wsgihandler.py
<Directory /var/repositories/web2py/>
AllowOverride None
Order Allow,Deny
Deny from all
<Files wsgihandler.py>
Allow from all
</Files>
</Directory>
AliasMatch ^/([^/]+)/static/(.*) \
/var/repositories/web2py/applications/$1/static/$2
<Directory /var/repositories/web2py/applications/*/static/>
Order Allow,Deny
Allow from all
</Directory>
<Location /admin>
Deny from all
</Location>
<LocationMatch ^/([^/]+)/appadmin>
Deny from all
</LocationMatch>
CustomLog /var/log/apache2/access.log common
ErrorLog //var/log/apache2/error.log
</VirtualHost>
Just replace "exampleapp" with the name of the domain and the appropriate names of the private key file and the certificate file. You can use this file as a template for other SSL sites, again, just change the domain name and SSL file names and you can have as many SSL-enabled sites as you have certificates.
Enable this site and restart Apache to make sure there were no configuration errors:
sudo a2enmod web2py-exampleapp-ssl
sudo /etc/init.d/apache2 restart
Now we need to configure web2py to map our domains to the proper applications. Open the routes.py file and configure the router:
This part is pretty simple. Just replace the domain/subdomain names on the left and the application names they belong to on the right. Finally, restart Apache again for the router changes to take effect:
sudo /etc/init.d/apache2 restart
Now test your sites to see if they work on both HTTP and HTTPS. If you have any trouble, I have attached some example files to this post that you can examine. If you're still having problems, let me know. I am no Apache expert by any stretch of the imagination, as I am still learning myself, but I'll try to help if there are any problems.