I'm trying to deploy Django (located in a virtualenv) on Apache using WSGI deploying. I'm following the default tutorial from https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/modwsgi/
wsgi.py (the default one which Django generated, with the comments dropped):
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
apache2.conf (its the same httpd.conf just in Debian ). Appended this to the end:
WSGIScriptAlias / /home/user/Desktop/expofit/expofit_hg/py/server/server/wsgi.py
WSGIDaemonProcess example.com python-path=/home/user/Desktop/expofit/expofit_hg/py/server:/home/user/Desktop/expofit/expofit_env/lib/python2.7/site-packages
WSGIProcessGroup example.com
<Directory /home/user/Desktop/expofit/expofit_hg/py/server/server>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Alias /static/ /home/user/Desktop/expofit/expofit_hg/py/server/server/static
<Directory /home/user/Desktop/expofit/expofit_hg/py/server/server/static>
Order deny,allow
Allow from all
</Directory>
However, this ends with an error:
[Thu Dec 06 17:08:40 2012] [error] [client 192.168.56.1] ImportError: No module named django.core.wsgi
It seems that the standard python is accessible, since
import os
yields no errors. So it seems that modules imported from the virtualenv aren't importable.
The tutorial said:
A further change required to the above configuration if you use
daemon mode is that you can't use WSGIPythonPath; instead you should
use the python-path option to WSGIDaemonProcess, for example:
WSGIDaemonProcess example.com python-path=/path/to/mysite.com:/path/to/venv/lib/python2.7/site-packages
WSGIProcessGroup example.com
What am I missing?
The problem was in the permissions. I didn't check who was the user, and what the permissions were at the beginning, however, when I changed the permission 777 to all the directories containing Django code files, it started working.
I'm aware that a person has to be as careful as possible with permissions, and that giving 777 to everything isn't the best way to do it but should check how to make it work with minimum permission change. It however solves the problem in the question.
the pythonpath your envinronment is different than the apache one i think.
install django "globaly" with easy_install or pip
or add .virtualenv pythonpath to the mod_wsgi config
WSGIPythonPath directory|directory-1:directory-2:
MOD_wsgi config
For a single app this is the easiest to get out of the box, see http://code.google.com/p/modwsgi/wiki/VirtualEnvironments#Baseline_Environment Neither this or using WSGIPythonPath can be done for just a vhost but must be global.
WSGIPythonHome [path to virtualenv folder]
If you have multiple apps - using sys.path to append your virtualenv's site-packages folder at the top of wsgi.py seems the easiest thing to do, see http://code.google.com/p/modwsgi/wiki/VirtualEnvironments#Application_Environments.
Related
So I am trying to migrate my app to a new production server. I'm not getting a reply from the server Apache server when I access it. The server is on AWS and it's a standard Apache config with just one site enabled:
<VirtualHost *:80>
Alias /static/ /home/ubuntu/myapp/myapp/myapp/static
Alias /media/ /home/ubuntu/myapp/myapp/myapp/media
<Directory /home/ubuntu/myapp/myapp/myapp/static>
Require all granted
</Directory>
<Directory /home/ubuntu/myapp/myapp/myapp/media>
Require all granted
</Directory>
<Directory /home/ubuntu/myapp/myapp/myapp>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
WSGIDaemonProcess myapp python-home=/home/ubuntu/myapp/myapp/myapp python-path=/home/ubuntu/myapp:/home/ubuntu/myapp/lib/python3.6/site-packages
WSGIProcessGroup myapp
WSGIScriptAlias / /home/ubuntu/myapp/myapp/myapp/myapp/wsgi.py
ErrorLog /var/log/apache2/myapp_error.log
LogLevel warn
CustomLog /var/log/apache2/myapp_access.log combined
</VirtualHost>
I have made sure that all files are owned by the ubuntu user and that www-data has group rights.
The wsgi file is the original, but I added a print statement to see the folder it's checking for the application:
"""
WSGI config for match2 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.8/howto/deployment/wsgi/
"""
import os, sys
print(sys.path)
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapp.settings")
application = get_wsgi_application()
Eventually, the error log will produce:
Timeout when reading response headers from daemon process 'myapp': /home/ubuntu/myapp/myapp/myapp/myapp/wsgi.py
I'd appreciate any advice.
Timeout when reading response headers from daemon process 'myapp' means your application is taking to long to handle the request. This could be because it is deadlocked, or is waiting on backend service.
Add WSGIApplicationGroup to your virtual host configuration.
<VirtualHost *:80>
# config remaining parts
WSGIApplicationGroup %{GLOBAL}
# config remaining parts
</VirtualHost>
From docs
... forces the WSGI application to run in the main Python interpreter context of each process. This is preferred in this scenario as some third party packages for Python which include C extensions will not run in the Python sub interpreter contexts which mod_wsgi would use by default. By using the main Python interpreter context you eliminate the possibility of such third party packages for Python causing problems.
A similar case link.
Also:
Looking at this,
python-home=/home/ubuntu/myapp/myapp/myapp python-path=/home/ubuntu/myapp:/home/ubuntu/myapp/lib/python3.6/site-packages
I think you have the wrong path for python-home. Make sure python-home path is correctly provided. Activate your virtual environment and run the command to get the python-home path [docs].
python -c 'import sys; print(sys.prefix)'
I'm trying to serve a little django project with the following Apache configuration :
Apache virtualhost configuration :
<VirtualHost *>
ServerName servername
[...]
<Directory "/path/to/project/project">
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess project python-path=/path/to/project:/path/to/Envs/venv/lib/python3.5/site-packages
WSGIScriptAlias / /path/to/project/project/wsgi.py
</VirtualHost>
I also have the following wsgi.py :
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
application = get_wsgi_application()
I have no problem to serve STATIC files and MEDIA files.
I also checked permissions and tried to recursively use 755, then 777 to my virtualenv's site-package directory. It didn't work.
But when trying to reach the root of my site I get the following :
from django.core.wsgi import get_wsgi_application
ImportError: No module named 'django'
I guessed that it was a Python path related problem since django is installed in my virtualenv. But I added the relevant python paths to the WSGIDaemonProcess's python-path attribute so I don't get why it doesn't work.
I also guess I could add the relevant directory to my Python path in my wsgi.py by using the site module, but I'd like to understand why the Apache configuration I tried isn't enough. Did I miss something?
You are missing a WSGIProcessGroup directive or equivalent option on WSGIScriptAlias, so your application isn't actually being run in that daemon process group where you have set the virtual environment.
See Using mod_wsgi daemon mode
I would also recommend ensuring application group is set to '%{GLOBAL}' if that is the only application you are running in the daemon process group.
Thus use:
WSGIScriptAlias / /path/to/project/project/wsgi.py \
process-group=project application-group=%{GLOBAL}
Also better to use python-home for the virtual environment.
WSGIDaemonProcess project python-path=/path/to/project \
python-home=/path/to/Envs/venv
See:
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
My rep is not over 50 so I cannot comment, but I'd like to share my discovery.
In WSGIDaemonProcess, if you are using Python 3.5, you need to set exactly as #graham-dumpleton say, with
python-home=/path/to/Envs/venv
set explicitly.
However, if you are using Python 3.4 (or some older version Python like 2.7 as far as I know), you'll have to configure it as
python-path=/path/to/project:/path/to/Envs/venv/lib/python3.4/site-packages
just like what the asker did.
Really weird.
For me the problem was I had mod wsgi installed for python2. I had to reinstall it for python3:
sudo apt-get install libapache2-mod-wsgi-py3
The issue for me was that I was running libapache2-mod-wsgi-py3 on python version 3.9. When I rolled back the python version to 3.7, there was no issue.
Just set up a 64 bit ubuntu EC2 instance using the Bitnami DjangoStack image.
So far I have installed a few python dependencies and removed the Project django app which was created by default. I created a new app with 'django-admin.py startproject projectname'. I then followed the instructions here: http://wiki.bitnami.org/Components/Django, attempting to setup apache.
Here is my projectname.conf file:
Alias /static "/opt/bitnami/apps/django/lib/python2.7/site-packages/django/contrib/admin/static"
<Directory '/opt/bitnami/apps/django/lib/python2.7/site-packages/django/contrib/'>
Order allow,deny
Allow from all
</Directory>
WSGIScriptAlias /URL_mount_point "/opt/bitnami/apps/django/scripts/projectname.wsgi"
<Directory '/opt/bitnami/apps/django/scripts'>
Order allow,deny
Allow from all
</Directory>
Here is my projectname.wsgi
import os, sys
sys.path.append('/opt/bitnami/apps/django/django_projects')
sys.path.append('/opt/bitnami/apps/django/django_projects/projectname')
os.environ['DJANGO_SETTINGS_MODULE'] = 'projectname.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Here are the last three lines of my httpd.conf:
Include "/opt/bitnami/apache2/conf/ssi.conf"
Include "/opt/bitnami/apache2/conf/bitnami/httpd.conf"
Include "/opt/bitnami/apps/django/conf/projectname.conf"
After doing this and restarting apache, hitting mydomain.com/projectname still comes up with a 404 (the Bitnami landing page comes up just fine at mydomain.com).
Am I missing something here? Are my paths in projectname.wsgi incorrect (I have not strayed from the default Bitnami directory structure). Or is there some additional step I am missing here?
You should be accessing:
http://mydomain.com/URL_mount_point
Since it appears you have not shown your original configuration, hard to say whether that is the issue or whether is a typo of sorts.
I added this to my httpd.conf
WSGIScriptAlias / /opt/bitnami/apps/django/scripts/projectname.wsgi
<Directory '/opt/bitnami/apps/django/django_projects/projectname'>
Order allow,deny
Allow from all
</Directory>
and that seemed to fix it.
I'm deploying my first ever Django project and I get the feeling I'm very close, but just need some help getting over the line. Here's the problem:
My httpd.conf changes look like this:
WSGIScriptAlias / /home/miketnc/frontend/tncsite/wsgi.py
WSGIPythonPath /home/miketnc/frontend/tncsite
<Directory /home/miketnc/frontend/tncsite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
So far so good, the "hello world" script in wsgi.py runs just fine. The problem comes when I use the Django doc-recommended wsgi script:
import os, sys
sys.path.append('/home/miketnc/frontend/tncsite')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "tncsite.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
This causes a 500 error:
File "/home/miketnc/frontend/tncsite/wsgi.py", line 10, in ?
mod_wsgi (pid=15494): Exception occurred processing WSGI script '/home/miketnc/frontend/tncsite/wsgi.py'.
mod_wsgi (pid=15494): Target WSGI script '/home/miketnc/frontend/tncsite/wsgi.py' cannot be loaded as Python module.
All of the support I've seen on the error relates back to bad installations in apache, not finding modules etc, which can't be the case if "hello world" is running.
Any ideas?
UPDATE
After restarting on a fresh server, I've managed to move things forward slightly. The good news is that python and WSGI seem to be playing nice, the bad is that I'm now getting a different kind of 500 error.
The only error I'm getting back in the log is:
"[Mon Dec 05 18:22:45 2011] [error] [client ip] mod_wsgi (pid=19804): Exception occurred processing WSGI script '/home/miketnc/frontend/tncsite/apache/wsgi.py'."
The Hello World script still runs fine, the trigger for the error is the final line:
application = django.core.handlers.wsgi.WSGIHandler()
I've set all directories containing the project from frontend/ down to 777 and I've added a daemon process as myself:
LoadModule wsgi_module /usr/local/apache/extramodules/mod_wsgi.so
AddHandler wsgi-script .wsgi
WSGIDaemonProcess miketnc processes=2 maximum-requests=500 threads=1
WSGIProcessGroup miketnc
WSGIScriptAlias / /home/miketnc/frontend/tncsite/apache/wsgi.py
<Directory /home/miketnc/frontend/tncsite>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Anyone please able to advise further on how to get this working?
In your case:
WSGIPythonPath /home/miketnc/frontend/tncsite
is redundant, as your are setting sys.path in the WSGI script file.
What you are missing though is adding the parent directory of the site:
sys.path.append('/home/miketnc/frontend')
This is in addition to the existing line adding '/home/miketnc/frontend/tncsite'.
Read:
http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
and watch:
http://code.google.com/p/modwsgi/wiki/WhereToGetHelp?tm=6#Conference_Presentations
which talk about paths and permissions.
Solved.
I didn't realise that the error log in Cpanel is a tiny fraction of the error log Apache outputs. Once I viewed the Apache logs, the problem was obvious. In this case it was MySQLdb not being set up properly.
I worked through it, making some adjustments around .python-eggs, and all is now well.
Thanks for the responses and in particular thank you Graham for the work you've put into WSGI.
Apache & mod_wsgi are configured correctly (I've created a hello
world .html apache file and a hello world mod_wsgi application with
no problems). I now need my Django app to work with my django.wsgi
file. What makes me think that it's not recognizing my wsgi file is that I
went into my django.wsgi file I created and completely deleted all of
the code in the file and restarted Apache and it still gives me the
same page (a listing of the files from Django app, not my actual
Django application. Configuring Apache and mod_wsgi went really well
but I'm at a loss of how to fix this. Here are some details:
Here is my current django.wsgi file:
import os
import sys
sys.path.append('/srv/www/duckling.org/store/')
os.environ['DJANGO_SETTINGS_MODULE'] = 'store.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
I've tried a few different versions of the django.wsgi file
(including a version like the one over at http://www.djangoproject.com/).
This version of my wsgi is from here:
http://library.linode.com/frameworks/django-apache-mod-wsgi/ubuntu-10...
Also, here is my vhost apache configuration file below. I think these
are the main files that are suppose to do the job for me. Let me know if
you see any errors in what I'm doing and what else I might do to fix
this. The django app runs fine on the django's built-in development
server so I'm thinking it might have something with my paths.
No errors in my apache error.log file as well. It's acting as there's
no problem at all, which is not the case...the project isn't loading,
like I said just a listing of my files and directories of my Django
project. Here is my apache config file:
<VirtualHost 1.2.3.4:80>
ServerAdmin hi#duckling.org
ServerName duckling.org
ServerAlias www.duckling.org
DocumentRoot /srv/www/duckling.org/store/
<Directory /srv/www/duckling.org/store/>
Order Allow,Deny
Allow from all
</Directory>
Alias /static/ /srv/www/duckling.org/store/static/
<Directory /srv/www/duckling.org/store/static>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias store/ /srv/www/duckling.org/store/wsgi-scripts/django.wsgi
<Directory /srv/www/wsgi-scripts>
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
And here are versions of the stack that I'm using, I saw over at the
mod_wsgi site that you all would like the versions of what I'm using
on the server:
Apache/2.2.14 (Ubuntu) PHP/5.3.2-1ubuntu4.5 with Suhosin-Patch
mod_python/3.3.1 Python/2.6.5 mod_wsgi/2.8
thanks,
j.
For a start, you should definitely not keep your Django files under your DocumentRoot. There's no need for them to be there, and it's a potential security risk - as you've seen, your current misconfiguration allows Apache to serve up your files directly: an attacker could guess that and download your settings.py, complete with your database password.
So, get rid of that DocumentRoot directive completely, as well as the first Directory section which allows direct access to /srv/www/duckling.org/store/. (You probably don't need the one serving up /srv/www/wsgi-scripts either.) That should make things a bit better.
By the way, this configuration will serve your website under duckling.org/store - is that what you want? If you want it under the root, you should just use:
WSGIScriptAlias / /srv/www/duckling.org/store/wsgi-scripts/django.wsgi