Apache hangs with mod_wsgi + django - django

I have had Apache + mod_wsgi + django running. For some reason, something has changed on the server and now apache completely hangs--it stops responding to all other requests and has to be stopped and started--when I post a request. Eventually we see a "Premature end of script headers: django.wsgi" error.
We did a strace and one thing I saw that seemed suspicious was "GATEWAY_INTERFACE\0CGI/1.1\0SERVER_PROTOCOL..." (We also see a shutdown being issued.)
Is "GATEWAY_INTERFACE\0CGI/1.1" specifying that it is set up for CGI rather then WSGI? (I have read that premature end of script can results if it is set as CGI.)
Our virtualhost specifies:
WSGIDaemonProcess [host] threads=25
WSGIProcessGroup [host]
WSGIScriptAlias / /path/to/apache/django.wsgi
and I see nothing to do with CGI in the httpd.conf just loading the WSGI module.

Here, try this one:
http://www.foxhop.net/django-virtualenv-apache-mod_wsgi
Remember to add python and project paths to syspath.

Related

XAMPP with WSGI not rendering django page

I am trying to run django on XAMPP Apache server and followed the steps mentioned here. Here are the changes in Apache config:[![enter image description here][1]][1]
When access the application in browser below is the result instead of django page:
[![enter image description here][2]][2]
Please help what I am missing in this ?
#Razenstein: Following are errors in Apache log:
AH02102: C:/xampp/htdocs/polls/mysite/mysite/wsgi.py is not executable; ensure interpreted scripts have "#!" or "'!" first line (9)Bad file descriptor: [client 127.0.0.1:58357] AH01222: don't know how to spawn child process: C:/xampp/htdocs/polls/mysite/mysite/wsgi.py
The application is running fine with built in python server. After correcting Alias getting "500 | Internal Server Error"
[1]: https://i.stack.imgur.com/w2R0Y.png
[2]: https://i.stack.imgur.com/vl8Da.png
ok, this error message says that Apache tries to execute wsgi.py as a cgi script and not as python. A possible reason is, that you tried to deploy your app on Apache with some wrong commands that are still in the httpd.conf or vhosts-httpd.conf. This typically happens if you follow one (bad?) tutorial without success, switch to another one and forgot to clean the the code from the first trial (only a guess!). There is all kinds of strange turorials out there and sometimes it is also difficult to understand if they are for Windows or Unix.
Something like the follwing would cause that behavior:
Alias / C:/xampp/htdocs/polls/mysite/mysite/wsgi.py
<Directory C:/xampp/htdocs/polls/mysite/mysite>
Options +ExecCGI
AddHandler cgi-script .cgi .pl .asp .py
Require all granted
</Directory>
please search in your httpd.conf and vhosts-httpd.conf if you have left something similar.
your "WSGIScriptAlias ...." is overwritten by that and not active.

Django project doesn't show up with Apache and mod_wsgi

I've installed Apache and mod_wsgi on windows xp service pack 3 and added these line to my httpd.conf :
WSGIScriptAlias / "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo/wsgi.py"
WSGIPythonPath "C:/Documents and Settings/X/My Documents/Downloads/Foo"
<Directory "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
but when I open localhost on my firefox, it shows Apache's It Works! message, what should I do to run my project on localhost ?
EDIT :
I checked and recognized that my project's path is not included in PYTHONPATH. Isn't the line WSGIPythonPath ... expected to add the address to PYTHONPATH ?
Alright, so my setup is in linux so this is not tested on windows, but:
I did not see your LoadModule statement
File: httpd.conf
LoadModule wsgi_module modules/mod_wsgi.so
modwsgi wont work without that.
Also: the your grant statement seems a bit suspicious.
In the wsgi configuration guide suggests using a Directory directive for allowing this access to your mod_wsgi application.
<Directory "C:/Documents and Settings/X/My Documents/Downloads/Foo/Foo/">
Order allow,deny
Allow from all
</Directory>
Finally:
Make your life easy down the road.
configure apache in worker mode
configure mod_wsgi in daemon mode.
profit
Might I suggest watching this PyCon talk Making Apache suck less for hosting Python web applications from 'the-man' Graham. I wish I knew all of that stuff years ago.
Note: To figure out if you have apache in mpm worker mode.
httpd.exe -V
look for the "Server MPM" value of worker.
Django runs on port 8000 so you'll want to do two things. First, you need to run the server by entering into your console python manage.py runserver. Second, you need to direct your browser to localhost:8000.
As an aside, you don't need Apache to run a simple, local development environment. Django has its own server built in that you can leverage.

Running apache bloodhound on apache2 web server

I am trying to run to apache bloodhound tracker on apache2 web server. I am using 0.7 version of the blood hound. I followed the website https://issues.apache.org/bloodhound/wiki/BloodhoundInstall
Blood hound is running on port 8000.
But the problem is I am not able to run the blood hound on port 80, so that if I hit bloodhound.mydomain.com, I should get bloodhound. I have mentioned my apache2 webserver setting file as specified in the website
/etc/apache2/sites-available/bloodhound
<VirtualHost *:8080>
WSGIDaemonProcess bh_tracker user=ubuntu python-path=/home/ubuntu/bloodhound-0.7/installer/bloodhound/lib/python2.7/site-packages
WSGIScriptAlias /bloodhound /home/ubuntu/bloodhound-0.7/installer/bloodhound/site/cgi-bin/trac.wsgi
<Directory /home/ubuntu/bloodhound-0.7/installer/bloodhound/site/cgi-bin>
WSGIProcessGroup bh_tracker
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
<LocationMatch "/bloodhound/[^/]+/login">
AuthType Digest
AuthName "ubuntu"
AuthDigestDomain /bloodhound
AuthUserFile /home/ubuntu/bloodhound-0.7/installer/bloodhound/environments/main/bloodhound.htdigest
Require valid-user
</LocationMatch>
</VirtualHost>
After adding the above file, its not running on either of the ports 8000 and also 8080 also.
How do I make it run. Kindly help me. By the way I am using ubuntu ec2 instance.
By golly I think I've figured it out! I've been stuck right about where you are on my own Bloodhound port configuration for days.
n3storm is correct: the whole magic of setting up mod_wsgi is that you no longer need to manually start bloodhound with that
tracd port=8080 /ridiculously/long/path/to/bloodhound/installer/bloodhound/environments/main
command. Instead, mod_wsgi runs all that python for you the moment your web browser requests http://[host]:8080/bloodhound, meaning your Bloodhound server is ready to serve the moment it's turned on.
The pain is how many interlocking config files are involved, and how many tiny things can break down the whole process. I don't really know python, I just barely understand Apache, and I'm 70% confident I've accidentally opened some gaping security that I don't understand, but here's my understanding of the mod_wsgi + Apache + Bloodhound domino chain. Paths are for my Apache 2.4 installation on Ubuntu 14.04.1 LTS:
1. You load http://[host]:8080/bloodhound
For this to work, I needed to edit /etc/apache2/ports.conf so that Apache is actually listening on port 8080. So add the line
Listen 8080
to /etc/apache2/ports.conf
Now visiting http://[host]:8080/bloodhound should at least show you something from Apache. For me, it was a HTTP Error 403: Forbidden page, and next up is my home remedy for the Error 403 blues!
2. Apache triggers bloodhound.conf
FULL PATH: /etc/apache2/sites-available/bloodhound.conf
Technically, Apache is looking in /etc/apache2/sites-enabled/ for a matching VirtualHost rule but you set this up by creating/editing .conf files in /sites-availabe/ and then activating them with the Apache command
a2ensite [sitename].conf
So. Apparently, Apache 2.4 changed its access control syntax for .conf files. So, to stop the Error 403ing, I changed
Order deny,allow
Allow from all
in /etc/apache2/sites-available/bloodhound.conf to
Require all granted
And then once again you should restart Apache with
sudo apachectl graceful
or
sudo /etc/init.d/apache2 graceful
or maybe
sudo service apache2 restart
I'm not sure, they all seem to work equally but I suppose the graceful ones are nice because they don't shut down your server or something important like that.
3. bloodhound.conf triggers trac.wsgi
FULL PATH: /ridiculously/long/path/to/bloodhound/installer/bloodhound/site/cgi-bin/trac.wsgi
After figuring out that ton of other things, I realized that, in the end, the default script that Bloodhound generates worked fine for me:
import os
def application(environ, start_request):
if not 'trac.env_parent_dir' in environ:
environ.setdefault('trac.env_path', '/usr/local/bloodhound/installer/bloodhound/environments/main')
if 'PYTHON_EGG_CACHE' in environ:
os.environ['PYTHON_EGG_CACHE'] = environ['PYTHON_EGG_CACHE']
elif 'trac.env_path' in environ:
os.environ['PYTHON_EGG_CACHE'] = \
os.path.join(environ['trac.env_path'], '.egg-cache')
elif 'trac.env_parent_dir' in environ:
os.environ['PYTHON_EGG_CACHE'] = \
os.path.join(environ['trac.env_parent_dir'], '.egg-cache')
from trac.web.main import dispatch_request
return dispatch_request(environ, start_request)
4. trac.wsgi serves up the HTML files for Bloodhound
Isn't the internet just magical?
By using Apache mod_wsgi you don't need Bloodhound running apart anymore. Is mod_wsgi what makes Bloodhound running. You should use standard apache port in this case.
Also, I guess you should use a ServerName directive at Virtualhost (or is it you only serve one host?)

Apache/mod_wsgi daemon mode not working

I have problems getting mod_wsgi to run in daemon mode on my Debian/Apache/Python2.6/Django setup. In my virtual host config file I have
<VirtualHost *:80>
ServerName mysite.com
WSGIDaemonProcess mysite.com processes=2 threads=15
WSGIProcessGroup mysite.com
WSGIScriptAlias / /path/to/mysite/wsgi/django.wsgi
<Directory /path/to/mysite/wsgi/>
Order deny,allow
Allow from all
</Directory>
</VirtualHost>
set up. To test activation of daemon mode, I use this wsgi script:
import sys
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
def application(environ, start_response):
print >> sys.stderr, 'mod_wsgi.process_group = %s' % repr(environ['mod_wsgi.process_group'])
from django.core.handlers.wsgi import WSGIHandler
_application = WSGIHandler()
return _application(environ, start_response)
and the resulting log file always says:
mod_wsgi.process_group = ''
which, accroding to the documentation, indicates that daemon mode is not being used. I checked my setup multiple times, the versions of Apache, mod_wsgi and Python are matching and my setup is correct according to all the HOWTO's I've read out there. What could I be missing?
Edit: FYI my application is running fine in embedded mode, I just wanted to switch to daemon mode and found out it is not activated using the wsgi script above.
It turned out that a symlink wasn't set correctly so my config changes never loaded in Apache. Sorry for wasting your time, I thought I checked everything thoroughly before posting.
The line mod_wsgi.process_group = '' implies that you are still operating in embedded mode (as you note). mod_wsgi daemon mode will not work on Apache 1.x so I assume that you are running 2.x (as you also note).
You could try setting the apache
LogLevel info
so that there is more helpful information in the log file. I'm also assuming that you've forced apache to restart
# /etc/init.d/apache2 restart
this shouldn't be necessary in daemon mode so much, but if you were in embedded mode previously you will need to reload your config files.

Apache Permission for a bat file w/ Django

I have seen a lot of similar questions, but still i am failing. I have win XP, Apache 2.2, Django 1.4, Python 2.7 and mod_wsgi 3.3. All i am trying to do is when you hit the page the bat file executes and which echoes hi. This works when i run it on the django internal dev server. But when i got to Apache, it fails and in the error.log i get the message
The system cannot write to the specified device.
The system cannot write to the specified device.
The system cannot write to the specified device.
The system cannot write to the specified device.
The system cannot write to the specified device.
I have not seen that error in many other places. Most people seem to get "Permission denied". I still think the permissions are wrong. So when i run it is the django internal server i get in the console:
Validating models...
0 errors found
Django version 1.4, using settings 'testsite.settings'
Development server is running at http:`//127.0.0.1:8000/
Quit the server with CTRL-BREAK.
C:\Sites\cprm>echo hi
hi
[18/Sep/2012 14:58:45] "GET / HTTP/1.1" 200 63
That seems fine. The only thing throwing me off that I'm running from /testsite and not /cprm. I could just cd .. before. Anyway, so since in the internal server it is writing to the console, i guess i need to do the equivalent in apache. I'm not sure where the apache console is. I tried adding permission to the apache log file as that is where the error gets generated. I'm not sure that is equivalent to the regular console.
My Apache file looks like this (ignore back ticks):
<`VirtualHost *>
ServerName http://example.com:80
WSGIScriptAlias /cprm "C:/sites/cprm/wsgi.py"
WSGIScriptAlias /testsite "C:/sites/testsite/wsgi.py"
<Directory "C:/sites">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
<Directory "C:/Program Files/Apache Software Foundation/Apache2.2/logs">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
<`/VirtualHost>
My view just looks like this:
from django.http import HttpResponse
import datetime, os
def home(request):
os.system('C:/Sites/testsite/testsite/test.bat')
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
It's basically just a quick test I tried doing.
EDIT
Hi pacha. Thanks for the response. I have done some reading on the topic now. So I made the changes you indicated. My wsgi.py file looks like such:
import os, sys
path = 'C:/Sites/testsite'
if path not in sys.path:
sys.path.append(path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testsite.settings")
sys.stdout = sys.stderr
print 'hi'
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Then when i go to error.log, i do in fact see 'hi' printed. So that is good. However, the test.bat file w/ the echo hello does not execute and i still get the same message. And thanks for the permission advice. I am now no longer using virtual. I am not ready for that yet. Any other ideas for what I could try?
Things to check
Permissions what are the user permissions on the file
C:/Sites/testsite/testsite/test.bat?
Are they read for the same user that is running the Apache Process?
Have you installed python for all logged in users not just for?
Have you reviewed your Apache conf directives?
User/Group: The name (or #number) of the user/group to run httpd as.
It is usually good practice to create a dedicated user and group for
running httpd, as with most system services.
User carlos
Group Administrators
Does that same user have permissions to read the file on the file system?
<Directory "C:/Sites/testsite/testsite/">
AllowOverride None
Options None
Order deny,allow
Allow from all
</Directory>
Your problem seems to be related to how the standard output is handled. WSGI disables standard output by default. That's why your program works fine in the development server (which redirects the output to the terminal where the server was launched) but doesn't work with Apache.
You can enable stdout in WSGI using a configuration directive that you put in your virtual host conf file (together with the other WSGI directives):
WSGIRestrictStdout Off
However, take into account that Apache isn't associated to any terminal. If you want to see the output of your program then one thing you can do is to redirect the standard output to the standard error stream by adding this to your WSGI file:
sys.stdout = sys.stderr
Restart Apache an you should see any output of your application (or any child process, as it is your case) in the error.log file of Apache.
Note: Don't add the Apache log files directory to your virtual host configuration. You aren't granting permissions to Apache over those files but allowing anyone to see them, which is as you can imagine a non-trivial security risk.
Update
Avoiding permission problems
You may want to try to use WSGI in daemon mode. That way the web application can be executed under your username (much like when using the internal development server). In your case, the configuration directives should be something along the lines:
WSGIDaemonProcess site1 user=<USERNAME> group=<GROUP> processes=1 threads=1
WSGIScriptAlias /testsite "C:/sites/testsite/wsgi.py"
<Directory "C:/sites/testsite/">
WSGIProcessGroup site1
WSGIApplicationGroup %{GLOBAL}
Order allow,deny
Allow from all
</Directory>
You have to substitute <USERNAME> and <GROUP> by your username and group in your Windows machine (it may work by just setting the username though). This is usually a nice way of avoiding permission issues since your application will be executed in a very similar way to how it is executed by the development server. (Notice that we're using just one process and one thread just to make Apache behave even more closely to how the development server does. You surely want to change those values in production to higher values).
You can check the daemon mode documentation here
Executing your script
To call external program from Python code, the module subprocess is usually preferred over os.system calls. The former allows you to have much more control over how the new process has to be executed whereas the later just passes the call to the operating system.
You can try the subprocess.check_output function. It executes a script/program and allows you to capture its output:
print subprocess.check_output(['C:\Sites\testsite\testsite\test.bat'], shell=True)
It has the additional advantage that you can capture the output in a string variable. (Btw, you may or may not need the shell=True param in Windows when calling a bat script, I'm not sure about that).