intermittent problem with two django apps on the same virtual host - python

I have two Django applications (appsystem and testapp) running in separate folders that are enabled in the same apache virtual host setting (see conf file at the end).
One application displays a page on the root of the domain and that one seems to always work fine but when I go to a URL that should go to the second application then it fails the first time complaining that it can't find the database table despite the fact I can see in the debug page that is loading the right settings.
If I refresh the page then it (testapp) works fine and continues to until I go back to a page from appssytem. If I do that and go back to testapp I must then refresh the page.
Both applications are using sqlite for authentication but removing the authentication and sqlite references from the settings file for appsystem didn't seem to make a difference.
The reason I've done it this way is because the idea is that the application that displays the root page (and some admin pages that have unique URLs) will list the other django application installed and display links to click through to.
I also suspect it may be session related because I can go directly to testapp in another browser and it works fine even on the first instance. Because of this I did give each django app its own value for SESSION_COOKIE_NAME but that doesn't seem to have helped.
Does anyone have an idea on what the problem may be?
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /app_www_root
RewriteEngine On
# the root of the box should show the system index - a list of installed apps
RewriteRule ^/$ /appsystem/system_index/ [PT]
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /app_www_root/>
Order allow,deny
allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
Include /etc/apache2/installed-apps/
## this is what gets pulled in by the include ##
Alias /testapp/static /testapp/static
Alias /testapp/logs /var/log/testapp
WSGIScriptAliasMatch ^/testapp /testapp/django.wsgi
<Directory "/testapp">
Order allow,deny
Allow from all
</Directory>
<Directory "/var/log/testapp">
Order allow,deny
Allow from all
</Directory>
<Location "/testapp/logs">
SetHandler none
Options +Indexes
</Location>
<Location "/testappl/static">
SetHandler none
Options -Indexes
Options +Includes
AddOutputFilter INCLUDES .html
</Location>
## end of included file ##
# wsgi docs advise against trailing slash below
WSGIScriptAlias /appsystem /app_sys/django.wsgi
</VirtualHost>

Have you read http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango at all?
I suspect your problem would be solved if you used mod_wsgi in daemon mode (i.e. via WSGIDaemonProcess).

Try running them in virtualenv with modwsgi.

FWIW, you have various things wrong with your configuration.
Why are you using WSGIScriptAliasMatch directive at all? You should just replace it with WSGIScriptAlias. Don't use WSGIScriptAliasMatch properly and it can stuff up reverse URL resolution.
Using 'SetHandler none' is not required. That is something you may have needed to do for mod_python but not mod_wsgi.
Using Location directive block to apply directives to static file resources as you are is bad practice. You should apply them to the specific directories using Directory directive instead.
As pointed out by others, you are better off using daemon mode. If doing so has worked but you delegate both applications to same single daemon mode process though, then you may have a multi process issue, ie., your application can't handle being run in multiple processes at the same time. If you delegated each to its own daemon process group, then you may have an issue with running them in same process even in case where in separate sub interpreters.

Related

Apache: ScriptAlias as a child of an Alias

I want a WSGIScriptAlias under an Alias. E.G.
/appA/ returns a static website.
/appA/api/ runs a python module.
I have set up in my httpd.conf
Alias /appA /source/appA/web/
WSGIScriptAlias /appA/api /source/appA/bin/api.py/
but when browsing to http://localhost/appA/api I get a 404 not found.
Renaming the WSGIScriptAlias to appB/api works.
Any ideas how to achieve what I'm looking for?
To meet this requirement I used AliasMatch instead of Alias. E.G.
AliasMatch (?i)^/appA^(api)(.*) /source/appA/web$1
WSGIScriptAlias /appA/api /source/appA/bin/api.py/
AliasMatch uses a regex to map all requests other than the /appA/api request.

Why does parse_qs give different result depending on the way wsgi application has been started?

I use Python 3.2.5 and Oracle Linux 6.4. I have written my wsgi application but I have some trouble: function urllib.parse.parse_qs behave differently depending on the way I started my application (Apache with mod_wsgi or wsgiref.simple_server). In my application function I have the following code:
def application(environ, start_response):
print(environ["QUERY_STRING"])
requestParams = parse_qs(environ["QUERY_STRING"])
print(requestParams)
.......
So. When I start my program using wsgiref.simple_server and make a query /query?name=Иван (it's Russian name) I get the following output:
name=%D0%98%D0%B2%D0%B0%D0%BD
{'name': ['Иван']}
But my application with Apache + mod_wsgi gives me the following:
name=%D0%98%D0%B2%D0%B0%D0%BD
{'name': ['\xd0\x98\xd0\xb2\xd0\xb0\xd0\xbd']}
As you can see, the latter doesn't give me correct Russian word encoded in UTF-8 although the input to the function is the same. According to https://docs.python.org/3.2/library/urllib.parse.html function parse_qs has default parameter encoding='utf-8'. As a result I have other problems during further work. I can't understand why this function works differently.
I have the following Apache virtual host:
<VirtualHost *:80>
DocumentRoot /var/www/my_project
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/my_project/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
WSGIDaemonProcess my_project processes=8 threads=1 python-path=/var/www/my_project display-name=%{GROUP}
WSGIProcessGroup my_project
WSGIScriptAlias /my_project /var/www/my_project/my_project.py
</VirtualHost>
My apache uses prefork MPM.
Graham Dumpleton (one of the developers of mod_wsgi) suggested me to use lang=en_US.UTF-8 locale=en_US.UTF-8 in WSGIDaemonProcess directive. These options aren't described in docs but they helped me to overcome my problems with string although python's print function doesn't print proper string. It still prints \xd0\x98\xd0\xb2\xd0\xb0\xd0\xbd in Apache log. But writing to a file works well. Therefore I can assume that it's because the environment variable PYTHONIOENCODING is not set for my python script which is started under Apache + mod_wsgi. Hope that my answer to my question will help someone.

Placing code outside of document root problems with Apache and Django

I am having trouble fulfilling the Django recommendation for code placement. I have searched google and beyond trying all types of VirtualHost configurations. However I cannot get the Django site to work with Apache like it does with Django's built in test web server.
I am using Django 1.5.4 and mod_wsgi
The Django documentation states that:
Where should this code live?
If your background is in plain old PHP (with no use of modern frameworks), you’re probably used to putting code under the Web server’s document root (in a place such as /var/www). With Django, you don’t do that. It’s not a good idea to put any of this Python code within your Web server’s document root, because it risks the possibility that people may be able to view your code over the Web. That’s not good for security.
Put your code in some directory outside of the document root, such as /home/mycode.
And in trying to do that I am failing.
Here is an example of my directory structure: I have /home/user/djangoRoot which I want for the document root and /home/user/djangoCode for where I want to put the code. I have followed the tutorial running django-admin.py startproject djangoSite and all the folders and files are created as they should. Database sync works great. I can view the site when I use Django's built in testing web server. But I feel like something is wrong with my apache virtual host because I cannot view the site the same way with apache.
Again, in the spirit of keeping code out of the document root, I want djangoRoot as my root directory and djangoCode for my code directory (with djangoSite/djangoSite directories in it that were created after running the django-admin.py start project djangoSite command).
I have tried
Making the DjangoCode/DjangoSite my root directory, but I can see the file structure inthe browser
Eliminating the DocumentRoot from the VirtualHost as quite a few suggessted.
And I have tried what I gathered from django and the rest
None worked.
So here is my current apache virtualhost
WSGIPythonPath /home/user/djangoCode/djangoSite/djangoSite
<VirtualHost *:80>
ServerAdmin webmaster#localhost
ServerName example.com
ServerAlias www.example.com
DocumentRoot /home/user/djangoRoot
<Directory /home/user/djangoRoot>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
WSGIScriptAlias /djangoRoot /home/user/djangoCode/djangoSite/djangoSite/wsgi.py
<Directory "/home/user/djangoCode/djangoSite/djangoSite/wsgi.py">
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
...
</VirtualHost>
This currently only allows me to see document root with no sign of django.
Is my virtual host configured wrong?
Am I taking this "code outside of document root too far"?
I really don't understand why you're finding this so hard, but you're clearly not following me at all. The point of the explanation in the docs is that the place where you code lives in your filesystem is completely independent from the point that Apache serves it at. The latter is given by the first parameter to WSGIScriptAlias. The former is given by the second parameter.
The document root is the default place for Apache to serve files from. But you're not serving files, you're running code to serve dynamic content. So, you proxy to the WSGI app, at the point given by the first parameter to WSGIScriptAlias. That is the root URL of your site. In the example you've given, that means that - assuming your domain name is example.com - your Django app will be accessible under example.com/djangoRoot. If you actually visited that URL in your browser, you'd see whatever page is configured under / in your urls.py. That is almost certainly not what you want. In the vast majority of cases, the first parameter - as shown in the docs - should just be /.
So I'm not sure why you think that goes against the security warning. Here, the document root stays at whatever it is by default - usually /var/www - but the code lives in /home/user/djangoCode/... and is served at /.

Configuring apache2 conf for several python web.py apps

I am working on a small web dashboard -project that has backend implemented with python's web.py framework.
The dashboard has all sorts of widget's on it, one of which also has its backend implemented using web.py. The problem is that only one of the designated application entry points seem to function at a time. Both the dashboard's and the widget's apache configurations are placed in the same file. The original configuration file (that actually worked for a while) in apache2/conf.d/ looks like this:
WSGIPythonPath /var/www/ProjectDASHBOARD/api
WSGIScriptAlias /ProjectDASHBOARD/api /var/www/ProjectDASHBOARD/api/api.py/
AddType text/html .py
<Directory /var/www/ProjectDASHBOARD/api/>
Order deny,allow
Allow from all
</Directory>
# Stuff for graphingwidget
WSGIPythonPath /var/www/ProjectDASHBOARD/widgets/graphingwidget/api
WSGIScriptAlias /ProjectDASHBOARD/widgets/graphingwidget/api /var/www/ProjectDASHBOARD/widgets/graphingwidget/api/api.py/
AddType text/html .py
<Directory /var/www/ProjectDASHBOARD/widgets/graphingwidget/api/>
Order deny,allow
Allow from all
</Directory>
This alone does not work, there is also the next piece of code that is needed in both api.py files, checking their approriate paths and adding them if not found (excerpt from the widget's file):
import web
import json
import sys
path = '/var/www/ProjectDASHBOARD/widgets/graphingwidget/api'
if path not in sys.path:
sys.path.append(path)
A similiar check is done for the dashboard.
All of this indeed worked for a whole week, and then suddenly stopped working when trying to install from scratch, making it all the more confusing as to what is wrong. The error received when trying to access the api from a webpage is HTTP Error 500 Internal server error. Then after a few changes to the apache config file ONE of the api's started working:
WSGIPythonPath /var/www/ProjectDASHBOARD/widgets/graphingwidget/api
WSGIPythonPath /var/www/ProjectDASHBOARD/api
WSGIScriptAlias /ProjectDASHBOARD/api /var/www/ProjectDASHBOARD/api/api.py/
WSGIScriptAlias /ProjectDASHBOARD/widgets/graphingwidget/api /var/www/ProjectDASHBOARD/widgets/graphingwidget/api/api.py/
AddType text/html .py
<Directory /var/www/ProjectDASHBOARD/api/>
Order deny,allow
Allow from all
</Directory>
# Stuff for graphingwidget
AddType text/html .py
<Directory /var/www/ProjectDASHBOARD/widgets/graphingwidget/api/>
Order deny,allow
Allow from all
</Directory>
Basically just moved the paths to the beginning of the file, and switched the order around a little bit, and suddenly one of api's start to work again. Changing the order a little bit then makes the other api work and brakes the other one. I don't remember the correct order for the paths, but the point is that it used to work well, then it stopped working when installed to a fresh identical virtual machine, and only one of the api's work depending on the order of the paths.
Initially the configs were in different files, but it didn't work like that. Had all kinds of errors like "Target WSGI script 'path' cannot be loaded as Python module.", and only started to work when they were moved to the same file.
Im thinking here that somehow one of the paths is overwritten by the other, or that all this time the whole config has been fundamentally wrong and has been working only by sheer luck (for a whole week, without issues...)
Any clues as to what is wrong?
Sorry for the late return, but the case was basically had to carefully RTFM at http://webpy.org/install#apachemodwsgi and make use of .htaccess files.
No idea really why the solution in the original question worked as far as it did.

Dynamic mass hosting using mod_wsgi

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.
Thanks,
Virgil
Discussion thread about this at:
http://groups.google.com/group/modwsgi/browse_frm/thread/2a9905f24c10a967

Categories

Resources