mod_wsgi daemon mode on OS X Server - python

I've successfully deployed my Django webapp on OS X Server 10.9 using the config .plist and extra httpd.conf using the built-in server manager.
(as per: How does one deploy a django application on OS X Server?, Deploying Django on OS 10.9 Server)
Now I'm trying to get it running using mod_wsgi's daemon mode, rather than the default embedded mode.
So I went back to bare basics: running the included OS X Server mod_wsgi tester bare Python script, which has a httpd conf file with the single line:
WSGIScriptAlias /wsgi /Library/Server/Web/Data/WebApps/hello.wsgi
Changed it to:
WSGIDaemonProcess wsgi_test processes=2 threads=15
WSGIProcessGroup wsgi_test
WSGIScriptAlias /wsgi /Library/Server/Web/Data/WebApps/hello.wsgi
However, it fails when attempting to turn the site back on, with the following message to the apache error log:
[Tue Sep 09 11:56:08 2014] [notice] caught SIGTERM, shutting down
[Tue Sep 09 11:56:12 2014] [crit] (17)File exists: mod_rewrite: Parent could not create RewriteLock file /var/log/apache2/rewrite.lock
Configuration Failed
Then the site 'unticks' itself in the Server admin. I've checked, and the rewrite.lock file doesn't exist when the webserver is turned off.
Should it work? My other concern is whether daemon mode supported out of the box, or I need a new mod_wsgi.

I had a similar error "caught SIGTERM, shutting down" in the Apache error logs on Yosemite. Unfortunately, I can't speak to the mod_rewrite issue.
The SIGTERM seems to occur when the python-path is not set in the WSGIDaemonProcess directive.
Here's a configuration that worked for me for a basic Django app on OSX:
WSGIDaemonProcess myapp processes=2 threads=15 python-path=/path/to/django/app/
WSGIProcessGroup myapp
WSGIScriptAlias /myapp /path/to/django/app/wsgi.py process-group=myapp
<Directory "/path/to/django/app/">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
I'm not sure if the <Directory> config is required or not. However, setting the python-path in WSGIDaemonProcess solved the SIGTERM issue for me.
Hope this helps.

Related

django / Apache2 Server

I'm trying to set up an Apache2/Django server on Ubuntu 18.04 x64 Digital Ocean droplet. I've went through the tutorials but still get an error. I've searched Stackoverflow and other sources for the solution, but still nothing works. Would someone be able to help?
The project is placed in /root/myproject. I use virtualenv that I named myprojectenv. So the python path is correct with /root/myproject/myprojectenv. I'm using Python 3.6 and the version of
/root/myproject/myprojectenv/bin/python is indeed 3.6. I'm using libapache2-mod-wsgi-py3.
I have chown'ed the whole /root/myproject folder to 'www-data' and chmod'ed to 664 the sqlite.db file in accordance with DigitalOcean's tutorial.
The content of my /etc/apache2/sites-available/000-default.conf file is (comments deleted):
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /root/myproject
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
Alias /static/ /root/myproject/static/
<Directory /root/myproject/static>
Require all granted
</Directory>
<Directory /root/myproject/myproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess myproject python-home=/root/myproject/myprojectenv python-path=/root/myproject
WSGIProcessGroup myproject
WSGIScriptAlias / /root/myproject/myproject/wsgi.py process-group=myproject
</VirtualHost>
The content of /root/myproject/myproject/settings.py is:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = '[SOME STRING]'
DEBUG = True
ALLOWED_HOSTS = ['[IP Address as a string]']
...
The error I get by trying to access the page via browser:
Forbidden You don't have permission to access / on this server.
Apache/2.4.29 (Ubuntu) Server at [IP ADDRESS] Port 80
The error log from /var/log/apache2/error.log
[Wed May 16 19:55:47.012027 2018] [wsgi:warn] [pid 3565:tid 140254930643904] (13)Permission denied: mod_wsgi (pid=3565): Unable to stat Python home /root/myproject/myprojectenv. Python interpreter may not be able to be initialized correctly. Verify the supplied path and access permissions for whole of the path.
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
The problem seems to be with apache being unable to run python.
Thanks in advance. Happy to add further information if needed.
Best regards
Saalim

mod_wsgi error with Django: Timeout when reading response headers from daemon process

I'm running Django 2.0.4 with mod_wsgi 4.5.20.
I'm getting an error when I try to deploy a site to our dev environment at /parature. What's weird is that the site deployed at the root of the VirtualHost is responding as normal:
[Tue Apr 10 13:34:08.998704 2018] [wsgi:error] [pid 65245] [client xx.yy.zz:65390] Timeout when reading response headers from daemon process 'parature-develop-https': /var/django/html/parature-develop/config/wsgi.py
I can run the site via runserver with the virtualenv activated. It shouldn't be timing out, as I'm just trying to bring up the Django admin site.
<VirtualHost *:443>
SSLEngine On
ServerName wrds-pub1-dev.example.com
ErrorLog "|/usr/sbin/cronolog /var/log/httpd/errorlog/%Y/%Y-%m-wrds-pub1-dev-error.log"
LogLevel info
WSGIApplicationGroup %{GLOBAL}
# The site I'm adding, which isn't working
WSGIDaemonProcess parature-develop-https python-home=/var/django/virtualenvs/parature-develop request-timeout=600
WSGIProcessGroup parature-develop-https
WSGIScriptAlias /parature /var/django/html/parature-develop/config/wsgi.py process-group=parature-develop-https
<Directory /var/django/html/parature-develop/config>
Require all granted
</Directory>
Alias /parature/static/ /var/django/html/parature-develop/static/
<Directory /var/django/html/parature-develop/static>
Require all granted
</Directory>
# The site which has been and continues to work
WSGIDaemonProcess django-wrds-dev-https python-home=/var/django/virtualenvs/django-wrds-dev request-timeout=600
WSGIScriptAlias / /var/django/html/django-wrds-dev/config/wsgi.py process-group=django-wrds-dev-https
<Directory /var/django/html/django-wrds-dev/config>
Require all granted
</Directory>
Alias /static/ /var/django/html/django-wrds-dev/static/
<Directory /var/django/html/django-wrds-dev/static>
Require all granted
</Directory>
Alias /media/ /var/media/wrds-www/
<Directory /var/media/wrds-www>
Require all granted
</Directory>
</VirtualHost>
I feel like I'm missing something obvious, but can't see it. I've got a similar configuration in another VirtualHost with multiple Django projects under the same domain, and that is working fine, as long as the root site comes last.
The wsgi.py is almost exactly the same as the site that is working as well:
import os, sys, logging
from socket import gethostname
from django.core.wsgi import get_wsgi_application
# Since this powers Apache, let's route Python errors to the Apache
# log rather than STDOUT, where they'll never be seen.
logging.basicConfig(stream=sys.stderr)
# Figure out where we're at, and add the parent to the path
sys.path.append(os.sep.join(os.path.abspath(__file__).split(os.sep)[:-2]))
# wrds-pub1-dev server
if 'wrds-pub1-dev' in gethostname():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
# wrds-pub* production servers.
elif 'wrds-pub' in gethostname():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
# else use dev settings.
else:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_wsgi_application()
Any ideas?
I figured it out - our dev server (since there's never a good time for a rebuild) is our only non-Ansiblized server, and still running mod_wsgi built against Python 3.5. The virtualenv was built against Python 3.6.
I rebuilt the virtualenv against Python 3.5, and everything works. Hopefully this saves someone hair-pulling in the future!

How to manage mod_wsgi logs in apache?

I am working on flask application and i have used mod_wsgi and Apache to host the flask app. I have setup the logging in app it, but i observe that there are same logs are getting written in apache/logs/error.log
like
[wsgi:error] ... BACK TO THE BROWSER
[wsgi:error] ... Selected records from table
[wsgi:error] ... mod_wsgi (pid=1654): Exception occurred processing WSGI script '/tmp/mod_wsgi-localhost:8000:0/htdocs/'.
[wsgi:error] ... ID 1123 Inserted in table
Due to this error.log is getting polluted with wsgi:error and apache errors its getting difficult to analyse the log file.
Is their any way to stop getting written wsgi.errors in error.log files or may we way to redirect these specific logs to seperate log files ?
I typically add an ErrorLog to my VirtualHost. Here's an example Apache VirtualHost I use:
<VirtualHost *:443>
ServerName yourservername.com
ErrorLog /home/yourusername/apache_errors.log
WSGIDaemonProcess yourproject-https python-home=/home/yourusername/.virtualenvs/yourproject
WSGIScriptAlias /yourproject /var/www/html/yourproject/yourproject/wsgi.py process-group=yourproject-https application-group=yourproject-https
WSGIProcessGroup yourproject-https
Alias /yourproject/static/ /var/www/html/yourproject/static/
SSLENGINE on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLProtocol all -SSLv2
</VirtualHost>
Would that do the trick? You can choose a path other than your home directory, of course.
First, you should add ErrorLog within the VirtualHost, Then you should use flask.logging.default_handler to log your message.
And be careful that if your request application does not exist in your threadLocal environment, flask will use std.strerr to log the message, and this will due to the message be cached by the main log instead of VirtualHost log.

Apache shows 404 error using mod_wsgi for my django application

For my django application (called 'iwidget') I have created (and installed using a2ensite) this virtual host configuration file (001-default)
WSGIPythonHome /home/user/.virtualenvs/iwidget
<VirtualHost *:80>
ServerAdmin webmaster#localhost
WSGIDaemonProcess iwidget processes=4 threads=10 display-name=%{GROUP} python-path=/home/user/.virtualenvs/iwidget/lib/python2.7
WSGIProcessGroup iwidget
WSGIScriptAlias /iwidget /home/user/iwidget/iwidget/wsgi.py
Alias /iwidget/static/ /home/user/iwidget/iwidget/staticfiles/
<VirtualHost>
And this is my wsgi.py (in /home/user/iwidget/iwidget/ directory.)
import os, sys, site
site.addsitedir('/home/user/.virtualenvs/iwidget/lib/python2.7/site-packages')
activate_this = os.path.expanduser("/home/user/.virtualenvs/iwidget/bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))
sys.path.append('/home/user/iwidget')
sys.path.append('/home/user/iwidget/iwidget')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "iwidget.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
However, I am getting this error
[warn] mod_wsgi: Compiled for Python/2.7.2+.
[warn] mod_wsgi: Runtime using Python/2.7.3.
[notice] Apache/2.2.22 (Debian) mod_wsgi/3.3 Python/2.7.3 configured -- resuming normal operations
[error] File does not exist: /var/www/iwidget
/var/www/iwidget? Why is Apache looking in this directory? What am I doing wrong?
Note. There is already a default vhost configuration pointing which is working fine. This is my second (that is why I called it 001-default).
You have two configuration files, but no way of distinguishing between them. Apache will simply match everything against the original one, since it's first alphabetically, and never get to the new one - hence why it is looking in /var/www, since that's evidently the DocumentRoot set in 001-default.
Do you actually need this to be in a separate file? There's no reason you couldn't add this configuration inside 001-default. Otherwise, you will need to have them on separate ports, or use a ServerName directive to distinguish them.

Apache mod_wsgi throwing error "403 Forbidden" when deploying a Django project

I have been trying to deploy a Django site using mod_wsgi on a CentOS server recently, but so far when I try to access the django site through my laptop, the web page has only been displaying error: 403 Forbidden You don't have permission to access / on this server.
In addition to reading all the obvious documentation, I have looked at these previous questions:
Django + mod_wsgi + Apache = 403 Forbidden
Error message “Forbidden You don't have permission to access / on this server”
Forbidden You don't have permission to access / on this server
Apache mod_wsgi error: Forbidden You don't have permission to access / on this server
Django on apache wtih mod_wsgi (Linux) - 403 Forbidden
Environment:
Centos 6.5
Python 2.6
Django 1.6
I am running the following version of apache:
# apachectl -V
Server version: Apache/2.2.15 (Unix)
Server built: Apr 3 2014 23:56:16
Server's Module Magic Number: 20051115:25
Server loaded: APR 1.3.9, APR-Util 1.3.9
Compiled using: APR 1.3.9, APR-Util 1.3.9
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
I installed mod_wsgi using Yum and have confirmed it is installed on the server:
# httpd -M | grep wsgi
wsgi_module (shared)
Syntax OK
My httpd.conf wsgi config snippet is as follows:
#
# Add WSGI configuration
#
WSGIScriptAlias / /usr/local/django/basic/basic/apache/wsgi.py
WSGIPythonPath /usr/local/django/basic/
WSGIDaemonProcess ###.###.###.###
WSGIProcessGroup ###.###.###.###
<Directory /usr/local/django/basic/basic/apache>
<Files wsgi.py>
Options FollowSymLinks
Order deny,allow
Allow from all
</Files>
</Directory>
Finally my wsgi.py script is:
"""
WSGI config for basic project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
"""
import os
import sys
path = "/usr/local/django/basic/basic/apache"
if path not in sys.path:
sys.path.append(path)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "basic.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Output from error log:
[Fri Oct 24 14:10:43 2014] [error] [client (redacted)] Symbolic link not allowed or link target not accessible: /usr/local/django/basic
[Fri Oct 24 14:11:25 2014] [error] [client (redacted)] Symbolic link not allowed or link target not accessible: /usr/local/django/basic
[Fri Oct 24 14:14:02 2014] [error] [client (redacted)] Symbolic link not allowed or link target not accessible: /usr/local/django/basic
Notes:
The django project is in my user's home directory but has a symbolic link in `/usr/local/django/ pointing to it
In the past when I have worked on projects Error 403 usually meant that the permissions on a file were wrong, but I had check that and the files should all allow the apache user to access them
My web server works fine when I comment out the wsgi related lines of the Apache config.
Sorry, that I posted this a bit late. This was the final fix to my apache config that ultimately worked.
WSGIScriptAlias /basic /var/www/django/basic/basic/wsgi.py
WSGIPythonPath /var/www/django/basic/
<Directory /var/www/django/basic/basic>
Options FollowSymLinks
<Files wsgi.py>
Order allow,deny
Allow from all
</Files>
</Directory>
Alias /static /var/www/django/basic/basic/static
And this is the final version of my wsgi.py file in python. The key line of code here was the PYTHON_EGG_CACHE. That variable was by default set to a directory that did not exist. I set it to /tmp/.python-eggs Make sure that .python-eggs has correct permissions for the apache user to read/write to it wherever you may place this file.
"""
WSGI config for basic project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/
"""
import os
import sys
path = "/usr/local/django/basic/basic/apache"
if path not in sys.path:
sys.path.append(path)
os.environ['PYTHON_EGG_CACHE'] = '/tmp/.python-eggs'
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "basic.settings")
#print os.getenv("DJANGO_SETTINGS_MODULE")
#print os.getenv("PYTHON_EGG_CACHE")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Side note:
A friendly reminder to make sure that every file in your django application is readable, (and writeable if needed) by the apache user. Git once overwrote a file to an old permission I had set up once and it took me a little time to figure out the permissions had changed without realizing it.
May be you forget set DocumentRoot. You should make the DocumentRoot can be read and wrote by apache users.
just do like this:
sudo chown -R www_default:www_default /path/to/you/DocumentRoot
and you can also do like this :
sudo chmod -R 755 /path/to/your/DocumentRoot

Categories

Resources