WSGIScriptAliasMatch question

608 views
Skip to first unread message

virgil.balibanu

unread,
Mar 11, 2010, 11:13:00 AM3/11/10
to modwsgi
Hi, I am trying to configure an apache server using mod_wsgi for
dynamic mass hosting. Each user will have it's own instance of a
python application located in /mnt/data/www/domains/[user_name] and
there will be a vhost.map telling me which domain maps to each user's
directory (the directory will have the same name as the user). What i
do not know is how to write the WSGIScriptAliasMatch line so that it
also takes the path from the vhost.map file.
What i want to do is something like this: I can have on my server
different domains like www.virgilbalibanu.com or virgil.balibanu.com
and flaviu.balibanu.com where each domain would belog to another user,
the user name having no neccesary connection to the domain name. I
want to do this beacuse a user, wehn he makes an acoount receives
something like virgil.mydomain.com but if he has his own domain he can
change it later to that, for example www.virgilbalibanu.ro, and this
way I would only need to chenage the line in the vhost.map file
So far I have something like this:

Alias /media/ /mnt/data/www/iitcms/media/
#all media is taken from here

RewriteEngine on

RewriteMap lowercase int:tolower

# define the map file
RewriteMap vhost txt:/mnt/data/www/domains/vhost.map

#this does not work either, can;t say why atm
RewriteCond %{REQUEST_URI} ^/uploads/
RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
RewriteCond ${vhost:%1} ^(/.*)$
RewriteRule ^/(.*)$ %1/media/uploads/$1

#---> this I have no ideea how i could do
WSGIScriptAliasMatch ^([^/]+) /mnt/data/www/domains/$1/apache/
django.wsgi

<Directory "/mnt/data/www/domains">
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>

<DirectoryMatch ^/mnt/data/www/domains/([^/]+)/apache>
AllowOverride None
Options FollowSymLinks ExecCGI
Order deny,allow
Allow from all
</DirectoryMatch>

<Directory /mnt/data/www/iitcms/media>
AllowOverride None
Options Indexes FollowSymLinks MultiViews
Order allow,deny
Allow from all
</Directory>

<DirectoryMatch ^/mnt/data/www/domains/([^/]+)/media/uploads>
AllowOverride None
Options Indexes FollowSymLinks MultiViews
Order allow,deny
Allow from all
</DirectoryMatch>

I know the part i did with mod_rewrite doesn't work, couldn't really
say why not but that's not as important so far, I am curious how could
i write the WSGIScriptAliasMatch line so that to accomplish my
objective.
I would be very grateful for any help, or any other ideas related to
how i can deal with this. Also it would be great if I'd manage to get
each site to run in wsgi daemon mode, thou that is not as important.

Carl Nobile

unread,
Mar 11, 2010, 11:24:46 AM3/11/10
to mod...@googlegroups.com
Hi Virgil,

Graham has provided a lot of documentation, but the one below should
answer you question.
http://code.google.com/p/modwsgi/wiki/ConfigurationDirectives

All the docs:
http://code.google.com/p/modwsgi/w/list

~Carl

> --
> You received this message because you are subscribed to the Google Groups "modwsgi" group.
> To post to this group, send email to mod...@googlegroups.com.
> To unsubscribe from this group, send email to modwsgi+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/modwsgi?hl=en.
>
>

--
-------------------------------------------------------------------------------
Carl J. Nobile (Software Engineer)
carl....@gmail.com
-------------------------------------------------------------------------------

Graham Dumpleton

unread,
Mar 11, 2010, 9:43:04 PM3/11/10
to mod...@googlegroups.com
On 12 March 2010 03:13, virgil.balibanu <virgil....@gmail.com> wrote:
> Hi, I am trying to configure an apache server using mod_wsgi for
> dynamic mass hosting.

Is this hosting of arbitrary applications which are provided and/or
implemented by the user, or are they managed applications which the
user has no ability to change the code in?

At the present time I would discourage using a single instance of
mod_wsgi for hosting of multiple distinct user supplied applications
unless you really know what you are doing and have ensured you have
done absolutely everything possible to ensure that different users
code is adequately isolated.

Although some hosting service companies do seem to use mod_wsgi for
this type of arrangement, I never see the right types of questions
being asked about how to properly secure Apache/mod_wsgi. As such I
can only assume that such companies simply provide it and hope that
all will be okay without really understanding where the risks lie.

Anyway, that is my paranoid disclaimer so when things go custard I can
say that I warned people against this model of usage. :-)

> Each user will have it's own instance of a
> python application located in /mnt/data/www/domains/[user_name]

But will it always be Django like your configuration below suggests?

Will they only ever have one Python application to host, or could they
want more than one?

Do the users have the ability to modify the code?

If they do have the ability to modify the code, then you MUST use
daemon mode with each distinct users code running as a separate user.
At that point things become difficult as daemon mode configuration is
static. This means you either have to change the Apache configuration
every time you add a new user, or pre-specify a whole lot of daemon
processes against preconfigured user accounts and later allocate users
to those accounts or use user/group permissions in such a way that
their application when run as that special user can still access
files/directories within their real account.

> and
> there will be a vhost.map telling me which domain maps to each user's
> directory (the directory will have the same name as the user). What i
> do not know is how to write the WSGIScriptAliasMatch line so that it
> also takes the path from the vhost.map file.

You cant use WSGIScriptAlias(Match) in conjunction with rewrite rules,
you need to fall back to lower level Apache URL mechanisms.

I am not in a state of mind right now to try and explain it with a
good example, so refer you to prior discussion at:

http://groups.google.com/group/modwsgi/browse_frm/thread/c29dde8fbef68e0b

so you can start to get an idea of what you have to go through to get
close to what you want.

As I said above, depending on what you are doing, daemon mode may well
be mandatory.

You certainly don't want to be running lots of fat Django instances at
same time in embedded mode as the memory requirements will become
excessive.

Try and digest what is in that other discussion I sent you and see if
you can integrate that into what you are trying and then come back
with more specific questions.

Graham

virgil.balibanu

unread,
Mar 26, 2010, 10:32:55 AM3/26/10
to modwsgi
So, I'm back from holiday and i worked out a solution following your
advice. It seem interesting butstill I'm not sure it's the best
solution. I'll write what I've got so far maybe you can help me with
some sugetions and then I'll explain what is exactly that I'm trying
to build, so maybe you could tell me if this or embedded mode would
work best for me. Thanks

RewriteEngine On
RewriteMap tolower int:tolower

RewriteCond %{REQUEST_URI} ^/uploads/ [OR]
RewriteCond %{REQUEST_URI} ^/thumbnails/ [OR]
RewriteCond %{REQUEST_URI} ^/captchas/ [OR]
RewriteCond %{REQUEST_URI} ^/invoices_pdf/
RewriteRule ^/(.*) /mnt/data/www/domains/${tolower:%{SERVER_NAME}}/
media/$1

RewriteCond %{REQUEST_URI} ^/media/ [OR]
RewriteCond %{REQUEST_URI} ^/uploader/
RewriteRule ^/(.*) /mnt/data/www/iitcms/$1

RewriteCond %{REQUEST_URI} ^/admin_media/
RewriteRule ^/admin_media/(.*) /usr/lib/python2.6/site-packages/
django-trunk/django/contrib/admin/media/$1

RewriteCond %{REQUEST_URI} ^/(?!uploads|thumbnails|captchas|
invoices_pdf|media|uploader)
RewriteRule ^/(.*) /mnt/data/www/domains/${tolower:%{SERVER_NAME}}/
apache/django.wsgi/$1

RewriteRule . - [E=APPLICATION_GROUP:${tolower:%{SERVER_NAME}}]

WSGIProcessGroup %{GLOBAL}
WSGIApplicationGroup %{ENV:APPLICATION_GROUP}

<DirectoryMatch /mnt/data/www/domains/(.+)/apache>


Order allow,deny
Allow from all

Options ExecCGI
AddHandler wsgi-script .wsgi
</DirectoryMatch>

(and all the other directories here)

Now, what I am trying to do is configure a server for a kind of CMS
application. A user comes, creates an account and he gets his own site
that he can edit, right then. At the moment the server has cpanel that
creates the user account and creates a virtual host - uses daemon
mode. The problem is that because of this cpanel need to restart
apache after each account is created, so if I have 5 ppl trying to
create an account in roughly the same time one will get through while
the other will get to wait after one another, the waiting interval
being able to go up to 4 or 5 minutes. During all this process apache
restarts and restarts and no other user sites work. This is my problem
and because of this I am trying to find another way. I would want to
keep each user account in daemon mode but I'm not sure there is a way
to do this, so I tried the other approach, using embedded mode, with
the above result. This would keep apache from restarting but other
complications might appear. I'm not sure the 5 users at the same time
will happen very often but I'd rather avoid it if I can.
Which of the above solutions do you think is better? Can you see
another solution, better than what I am trying?
Could you please tell me of a good article about embedded mode and the
problems it might pose in this case. I'll have tons of sites running
under the same process (big fat django sites).

Can I do something using .htaccess maybe? Or can I use mod_rewrite to
define processes for each site, thus making it run in daemon mode?

Thank you,
Virgil

Graham Dumpleton

unread,
Mar 27, 2010, 6:28:05 AM3/27/10
to mod...@googlegroups.com

Did you read:

http://groups.google.com/group/modwsgi/browse_frm/thread/c29dde8fbef68e0b

right through?

It has an example in there of dynamic assignment to daemon process
group. The only restriction is that the pool of daemon processes has
to be set up in advance.

The idea thus is to preallocate enough daemon processes to allow you
to operate for a while without restarting Apache. When you run out of
daemon process groups to allocate, then you adjust Apache
configuration to add a batch of new daemon process groups and repeat.

Now, the issue to be solved is that because you have to preallocate
daemon process groups, you would have to assign them a user to run as
if you want all daemon process groups to run as different users. If
who requests an application is arbitrary, you can never know in
advance what those users should be.

The solution to this is not attempt to guess. Instead, have special
accounts, which don't overlap with potential users. Thus, the
applications will not actually run as same user as the customer.

This is actually good in some ways because it is more secure as a
breach of the application will not result in access to arbitrary file
system directories of that user.

You will still need some access though for data directories and other
writable directories however if not everything is in a database. To
handle this, the special user would have a unique group of its own.
When a customer is delegated against that daemon process group, they
would be added as a member of that special group, allowing them to
make changes in directories access to which is shared between the user
that daemon process group runs and themselves.

Anyway, that is the only way one could really handle it at the moment
if you want daemon process groups and for each to run as separate
user.

If you don't need each daemon process group to run as separate user,
same idea, but no separate user/group, and so easier.

In respect of embedded mode, that is a bad idea because your processes
will become too bloated. You also loose ability to restart individual
application instances without restarting whole of Apache.

Other issues with embedded mode were also mentioned in a blog post
referenced from that prior discussion. This was at:

http://blog.dscpl.com.au/2009/03/load-spikes-and-excessive-memory-usage.html

Graham

virgil.balibanu

unread,
Mar 30, 2010, 11:16:59 AM3/30/10
to modwsgi
Thanks,

I did not understand that part very well the first time I read through
it and it seemed very difficult so i tried the embedded method. Now
reread it and played with it for a bit and got to this:

WSGIDaemonProcess site-1
WSGIDaemonProcess site-2
WSGIDaemonProcess site-3
WSGIDaemonProcess site-4

RewriteEngine On
RewriteMap tolower int:tolower

RewriteMap wsgiprocmap txt:/etc/httpd/modules.d/wsgiprocmap.txt

RewriteCond %{REQUEST_URI} ^/uploads/ [OR]
RewriteCond %{REQUEST_URI} ^/thumbnails/ [OR]
RewriteCond %{REQUEST_URI} ^/captchas/ [OR]
RewriteCond %{REQUEST_URI} ^/invoices_pdf/
RewriteRule ^/(.*) /mnt/data/www/domains/${tolower:%{SERVER_NAME}}/
media/$1

RewriteCond %{SERVER_NAME} !webbi [NC]
RewriteCond %{REQUEST_URI} ^/media/
RewriteRule ^/media/(.*) /mnt/data/www/iitcms/media/$1

RewriteCond %{REQUEST_URI} ^/uploader/
RewriteRule ^/uploader/(.*) /mnt/data/www/iitcms/uploader/$1

RewriteCond %{SERVER_NAME} webbi [NC]
RewriteCond %{REQUEST_URI} ^/media/
RewriteRule ^/media/(.*) /mnt/data/www/domains/webbi/media/$1

RewriteCond %{REQUEST_URI} ^/admin_media/
RewriteRule ^/admin_media/(.*) /usr/lib/python2.6/site-packages/
django-trunk/django/contrib/admin/media/$1

RewriteCond %{REQUEST_URI} ^/(?!uploads|thumbnails|captchas|

invoices_pdf|media|uploader|admin_media)


RewriteRule ^/(.*) /mnt/data/www/domains/${tolower:%{SERVER_NAME}}/
apache/django.wsgi/$1

RewriteRule . - [E=PROCESS_GROUP:${wsgiprocmap:%{SERVER_NAME}}]

WSGIProcessGroup %{ENV:PROCESS_GROUP}
WSGIApplicationGroup %{GLOBAL}

webbi server is not a user site but my site, but i can't (or more
correct i don't know how) put it in a virtual host block. Now what I
understood so far is that each site will user a different process but
under the same user. And you say that I can also configure it so that
each runs under a different user. How can I do that? Just by creating
the users site-1 ... site-N in the system? Also the users have to
belong to a specific group and the group to have access to all
directories needed, that I get.

Thanks,
Virgil

virgil.balibanu

unread,
Mar 31, 2010, 4:41:20 AM3/31/10
to modwsgi
Ok, sorry for that silly question, I just added the users in the
system and added them to the defined WSGIDaemonProcess.

Thanks

Graham Dumpleton

unread,
Mar 31, 2010, 6:40:19 AM3/31/10
to mod...@googlegroups.com
On 31 March 2010 19:41, virgil.balibanu <virgil....@gmail.com> wrote:
> Ok, sorry for that silly question, I just added the users in the
> system and added them to the defined WSGIDaemonProcess.

Yeah. Sorry that haven't responded. Haven't even looked properly at
your last email. Haven't been very focused of late. :-(

Graham

Reply all
Reply to author
Forward
0 new messages