On 4 May 2010 11:32, Graham Dumpleton <
graham.d...@gmail.com> wrote:
> On 3 May 2010 05:07, paryl <
pry...@gmail.com> wrote:
>> Hi All,
>>
>> At work we maintain a large-scale PHP project. For our dev
>> environment, each developer is constantly creating new svn checkouts
>> for revisions, each one in a unique directory. We have Apache
>> configured for a virtual hosting environment, and the URL determines
>> which branch to serve from.
>
> Sorry, some more questions.
>
> How are you current setting up virtual hosts when using PHP?
>
> If you are using VirtualHost directive you would have same issue with
> needing to restart Apache to have it recognise the new virtual host.
>
> Does the system where you are running Python also need to support PHP
> in parallel and thus whatever you use for Python has to interwork with
> supporting PHP?
>
> Need to know how PHP comes into the picture or whether PHP support can
> simply be ignored, thus simplifying how Python might be handled.
Pending an answer on the above, I'll assume that you don't have to
worry about hosting PHP and that this Apache instance is used only for
hosting Python applications.
First thing to note is that if you use WSGIScriptAlias, then to add a
new application you must restart Apache. We thus need to avoid that.
The way of doing that is to use AddHandler instead. This will allow
one to drop a .wsgi file corresponding to a new application instance
into a directory and will be immediately available.
Using AddHandler does however have the consequence that by default the
name of the .wsgi file becomes part of the URL. If your application is
relocatable and not dependent on being hosted at the root of the web
server, this would be more than adequate in a development and test
environment. It even allows you to do it within a single virtual host.
<VirtualHost *:80>
ServerName
example.com
DocumentRoot /var/www/htdocs
<Directory /var/www/htdocs>
Order deny,allow
Allow from All
Options ExecCGI
AddHandler wsgi-script .wsgi
</Directory>
</VirtualHost>
So, for each instance, add a file into DocumentRoot directory. For
example, you might have 'rev100.wsgi', 'rev101.wsgi', 'rev102.wsgi',
etc. These would be access as:
http://example.com/rev101.wsgi
http://example.com/rev102.wsgi
http://example.com/rev103.wsgi
To bring a new instance online, just add a new .wsgi file.
The issue is now separation between the instances.
By default each application instance is run within a distinct sub
interpreter of a process. The name of the sub interpreter is created
from combination of server name and application mount point
(SCRIPT_NAME). Thus for above, the sub interpreters are named as
follows:
example.com|/rev101.wsgi
example.com|/rev102.wsgi
example.com|/rev103.wsgi
So separation should hopefully not be an issue as each application
will run in separate sub interpreter.
You could still have problems with third party C extension modules or
issues with process global configuration at C level, such as time
zones or language locale.
Thus, process separation, rather than separation by way of sub
interpreters within a process, would be a preferable solution.
Process separation of a different type is also an issue. This is that
at present we are running in embedded mode. This means to drop an in
memory instance of an application as it is no longer needed, or we
want to reload an application because we changed the code, we still
need to restart Apache.
First step at least is thus to use daemon mode. For that, add
WSGIDaemonProcess/WSGIProcessGroup.
<VirtualHost *:80>
ServerName
example.com
DocumentRoot /var/www/htdocs
WSGIDaemonProcess apps
WSGIProcessGroup apps
<Directory /var/www/htdocs>
Order deny,allow
Allow from All
Options ExecCGI
AddHandler wsgi-script .wsgi
</Directory>
</VirtualHost>
This gets the applications out of the Apache server child processes
albeit they are still in the same process.
We can at least though cause that process to be restarted if one
application changes by touching the .wsgi file for that application.
For actual process separation, we need a
WSGIDaemonProcess/WSGIProcessGroup for each, but to add a new one for
each .wsgi script file, then need to again restart Apache.
To avoid that, we can create a pool of daemon process groups and
dynamically delegate a new .wsgi file to an available process.
<VirtualHost *:80>
ServerName
example.com
DocumentRoot /var/www/htdocs
WSGIDaemonProcess wiggles display-name=%{GROUP}
WSGIDaemonProcess sam display-name=%{GROUP}
WSGIDaemonProcess murray display-name=%{GROUP}
WSGIDaemonProcess anthony display-name=%{GROUP}
WSGIDaemonProcess jeff display-name=%{GROUP}
WSGIDaemonProcess dorothy display-name=%{GROUP}
WSGIDaemonProcess henry display-name=%{GROUP}
WSGIDaemonProcess wags display-name=%{GROUP}
WSGIProcessGroup %{ENV:PROCESS_GROUP}
SetEnv PROCESS_GROUP wiggles
<Directory /var/www/htdocs>
Order deny,allow
Allow from All
Options ExecCGI
AddHandler wsgi-script .wsgi
AllowOverride FileInfo
</Directory>
</VirtualHost>
The WSGIProcessGroup directive you see sets a default, so if you don't
override it for a specific .wsgi file it will end up in the 'wiggles'
process.
In the .htaccess file of the DocumentRoot directory, we can now do the
following.
<Files rev101.wsgi>
SetEnv PROCESS_GROUP sam
</Files>
<Files rev102.wsgi>
SetEnv PROCESS_GROUP murray
</Files>
<Files rev103.wsgi>
SetEnv PROCESS_GROUP anthony
</Files>
So, as you add new .wsgi script files, you modify .htaccess file to
say what process to run it in. You can still run multiple applications
in one process if you want to.
If you remove a .wsgi script file, just remember to send a SIGINT to
the process so it will recycle and discard old application. Having
used display-name option, you can easily use 'ps' on most systems to
identify which process to send signal. For example '(wsgi:sam)' for
rev 101.
If you simple want to free up a process but still keep .wsgi file, you
can take out SetEnv for a .wsgi file and send signal and next time
.wsgi used, will use the default process.
One can take this further if you really needed a separate virtual host
for each even with the application mounted at root of web server.
The start of this would be to not use VirtualHost, but use other
methods for construction virtual hosts. One way of doing that is to
use mod_vhost_alias instead. I haven't tried this, but believe you
could use:
VirtualDocumentRoot /var/www/vhosts/%0/htdocs
WSGIDaemonProcess wiggles display-name=%{GROUP}
WSGIDaemonProcess sam display-name=%{GROUP}
WSGIDaemonProcess murray display-name=%{GROUP}
WSGIDaemonProcess anthony display-name=%{GROUP}
WSGIDaemonProcess jeff display-name=%{GROUP}
WSGIDaemonProcess dorothy display-name=%{GROUP}
WSGIDaemonProcess henry display-name=%{GROUP}
WSGIDaemonProcess wags display-name=%{GROUP}
WSGIProcessGroup %{ENV:PROCESS_GROUP}
SetEnv PROCESS_GROUP wiggles
<Directory /var/www/vhost/*/htdocs>
Order deny,allow
Allow from All
Options ExecCGI
AddHandler wsgi-script .wsgi
AllowOverride FileInfo
</Directory>
Each virtual host then has a separate document root directory. You
would still stick .wsgi files in that directory like before and use
SetEnv to dynamically dictate which daemon process group to use.
Finally, if you want application to appear at root of host, you should
be able to have in .htaccess something like the following.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,PT,L]
with the application file being called site.wsgi.
You will need to play with that though as recollect that is what one
would use in main Apache configuration. That or you may be able to
even put it in the main Apache configuration.
<Directory /var/www/vhost/*/htdocs>
Order deny,allow
Allow from All
Options ExecCGI
AddHandler wsgi-script .wsgi
AllowOverride FileInfo
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /site.wsgi/$1 [QSA,
</Directory>
If VirtualDocumentRoot doesn't work, then one can instead look at
doing dynamic virtual hosts using mod_rewrite. Can look at that later
if need be.
Hope that is of use. :-)
If you try out VirtualDocumentRoot let me know what works, as haven't
tried that one before. Just remember that if you use that, you
shouldn't use VirtualHost in same Apache configuration.