I can't seem to find a good answer to this. Who needs to own the virtualenv when running it as a WSGIDaemon? I assume on my OS (Ubuntu 16) www-data, but I want to be sure. Trying some new things to get this thing working based off of the answer from this post...
django apache configuration with WSGIDaemonProcess not working
Does the django project, the virtualenv folder, or both need to be owned by the apache group? What ownerships need to be in place to serve a django project without specifying a port? Why do I get the following?
The root problem:
Call to 'site.addsitedir()' failed for '(null)'
When I start apache, I get this error. I've followed several different guides, including:
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
and
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/modwsgi/
but have had zero success.
My virtual environment path is /usr/local/virtualenvs/servicesite
My django project path is /home/addohm/projects/rtservice/servicesite
this is where manage.py resides,
which leaves /home/addohm/projects/rtservice/servicesite/servicesite as the location of my wsgi.py.
wsgi.py:
SERVICESITE = ['/usr/local/virtualenvs/servicesite/lib/python3.5/site-packages']
import os
import sys
import site
prev_sys_path = list(sys.path)
for directory in SERVICESITE
site.addsitedir(directory)
new_sys_path = []
for item in list(sys.path):
if item not in prev_sys_path:
new_sys_path.append(item)
sys.path.remove(item)
sys.path[:0] = new_sys_path
""" **Doesn't seem to work, throwing error in apache logs**
site.addsitedir('/usr/local/virtualenvs/servicesite/lib/python3.5/site-packages')
"""
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "servicesite.settings")
application = get_wsgi_application()
DJANGO_PATH = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
sys.path.append(DJANGO_PATH)
apache2.conf
[...]
WSGIDaemonProcess servicesite python-path=/home/addohm/projects/rtservice/servicesite:/usr/local/virtualenvs/servicesite/lib/python3.5/site-packages
WSGIProcessGroup servicesite
WSGIScriptAlias / /home/addohm/projects/rtservice/servicesite/servicesite/wsgi.py
Alias /static/ /home/addohm/projects/rtservice/servicesite/static/
<Directory /home/addohm/projects/rtservice/servicesite/static/>
Require all granted
</Directory>
<Directory /home/addohm/projects/rtservice/servicesite/servicesite>
<Files wsgy.py>
Require all granted
</Files>
</Directory>
[...]
You should not have need to change anything in the original wsgi.py generated by Django for you. It is generally sufficient to have:
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "servicesite.settings")
application = get_wsgi_application()
Your Apache configuration should then preferably be:
WSGIDaemonProcess service site python-home=/usr/local/virtualenvs/servicesite \
python-path=/home/addohm/projects/rtservice/servicesite
WSGIProcessGroup servicesite
WSGIScriptAlias / /home/addohm/projects/rtservice/servicesite/servicesite/wsgi.py
Alias /static/ /home/addohm/projects/rtservice/servicesite/static/
<Directory /home/addohm/projects/rtservice/servicesite/static/>
Require all granted
</Directory>
<Directory /home/addohm/projects/rtservice/servicesite/servicesite>
<Files wsgy.py>
Require all granted
</Files>
</Directory>
That is, use python-home for the location of the directory specified by sys.prefix for the virtual environment. Avoid using python-path and referring to the site-packages directory. Using python-home has been preferred way for a very long time and using it ensures that things fail in a more obvious way when you don't do things the correct way.
A few very important things.
The first is that mod_wsgi must be compiled for the specific Python major/minor version you want to use.
Second, the Python virtual environment must be created from the same Python installation as mod_wsgi was compiled for. You can't have mod_wsgi compiled against a system Python installation, but have your virtual environment based off a separate Python installation for same major/minor version in /usr/local.
Third, the user that Apache runs your code as must have read access to any directories/files for the main Python installation, the virtual environment and your application code. When you stick stuff under a home directory, it will not generally have access as the home directory prohibits others from reading anything in the home directory.
Fourth, if the mod_wsgi daemon process group is set to run as a different user than the Apache user, the Apache user still must at least have ability to read the wsgi.py file and all the directories down to that point.
Further reading on virtual environments which is more up to date:
http://blog.dscpl.com.au/2014/09/using-python-virtual-environments-with.html
Related
I need a bit of help here. I am new to python and django. For my project i am developing an system which deals with api fetching and insertions. I need this system to be online 24 * 7. so i need to the server to be running all the time.
Using the traditional method of:
python manage.py runserver
runs perfectly.
I even tried :
nohup python manage.py &
but when i access my project with the url. Its showing that it project is not online. How do i fix this?
If you are using Apache then mod_wsgi should be used along with Django for deployment. This is covered here in great detail.
If you want step by step guide then you can have a look at Digital Ocean's Guide.
Your Apache configuration will look like following:
<VirtualHost *:80>
Alias /static /home/user/myproject/static
<Directory /home/user/myproject/static>
Require all granted
</Directory>
<Directory /home/user/myproject/myproject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess myproject python-path=/home/user/myproject python-home=/home/user/myproject/myprojectenv
WSGIProcessGroup myproject
WSGIScriptAlias / /home/user/myproject/myproject/wsgi.py
</VirtualHost>
You will need to create a wsgi.py file which looks like following(the default one):
"""
WSGI config for myproject 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.7/howto/deployment/wsgi/
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Hope this helps.
I created a droplet(cloud server) on DigitalOcean and with no-ip.com I gave it the hostname - project.ddns.net.By ssh(ing) into the droplet I installed pip and virtualenv.
Inside /var/www/ I created a virtualenv and cloned the repository from github of my project.The directory struture is -
project_revamped (root of the project)
->requirements
->base.txt
->dev.txt
->project (django project)
->static
->media
->apps (folder which contains apps)
->manage.py
->project
->urls.py
->settings
->base.py
->dev.py
By following the official Django documentation I created httpd.conf in the /etc/apache2 path and included it in apache2.conf.
My httpd.confs reads as this -
WSGIScriptAlias / /var/www/project_revamped/project/project/wsgi.py
WSGIPythonPath /var/www/project_revamped/project:/var/www/.virtualenvs/projectenv/local/l ib/python2.7/site-packages
<Directory /var/www/project_revamped/project/project>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
and my wsgi.py reads as this -
import os
import sys
#Add the app's directory to the python path
sys.path.append('/var/www/project_revamped/project')
sys.path.append('/var/www/project_revamped/project/project')
os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings.dev'
#Activate your virtualenv
activate_env = os.path.expanduser('/var/www/.virtualenvs/typesetenv/bin/activate_this.py')
execfile(activate_env, dict(__file__=activate_env))
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
After changing the files I finally gave the commands -
service apache2 reload
service apache2 restart
However after doing these things right the corresponding ip says there is some problem the server and sends 500 error.I guess the problem is somewhere in my configuration because apache server was responding working fine.After I include django project with it the problem starts.
After checking the error logs I found these error messages -
mod_wsgi (pid=29458): Target WSGI script '/var/www/project_revamped/project/project/wsgi.py' cannot be loaded as Python module.
mod_wsgi (pid=29458): Exception occurred processing WSGI script '/var/www/project_revamped/project/project/wsgi.py'.
File "/var/www/project_revamped/project/project/wsgi.py", line 28, in <module>
[:error] [pid 29458:tid 140073924572928] [client 103.16.70.147:33613] application = get_wsgi_application()
Can anybody please help me here in the configuration? I am stuck in this for past 2 days and every different article on the internet tells the different story.
add this line to you wsgi.py file : sys.path.append('/var/www/project_revamped/project') before os.environ['DJANGO_SETTINGS_MODULE'] = 'project.settings.dev' and check if it works.
You may have a look at my VirtualHost configuration for Apache with mod_wsgi. This template can be automatically filled during project-creation, but you may be able to fill/replace variables and strip it down to your needs:
<VirtualHost *:80>
# This is name based virtual hosting. So place an appropriate server name
# here. Example: django.devsrv.local
ServerName [[SERVER_NAME]]
ServerAdmin webmaster#localhost
# This alias makes serving static files possible.
# Please note, that this is geared to our settings/common.py
# In production environment, you will propably adjust this!
Alias /static/ {{ project_directory }}/run/static/
# This alias makes serving media files possible.
# Please note, that this is geared to our settings/common.py
# In production environment, you will propably adjust this!
Alias /media/ {{ project_directory }}/run/media/
# Insert the full path to the wsgi.py-file here
WSGIScriptAlias / {{ project_directory }}/{{ project_name }}/wsgi.py
# PROCESS_NAME specifies a distinct name of this process
# see: https://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIDaemonProcess
# PATH/TO/PROJECT_ROOT is the full path to your project's root directory,
# containing your project files
# PATH/TO/VIRTUALENV/ROOT: If you are using a virtualenv specify the full
# path to its directory.
# Generally you must specify the path to Python's site-packages.
WSGIDaemonProcess {{ project_name }} python-path={{ project_directory }}:{{ project_directory }}/../lib/python2.7/site-packages
# PROCESS_GROUP specifies a distinct name for the process group
# see: https://code.google.com/p/modwsgi/wiki/ConfigurationDirectives#WSGIProcessGroup
WSGIProcessGroup {{ project_name }}
# Serving static files from this directory
# Please note, that this is geared to our settings/common.py
# In production environment, you will propably adjust this!
<Directory {{ project_directory }}/run/static>
Options -Indexes
Order deny,allow
Allow from all
</Directory>
# Serving media files from this directory
# Please note, that this is geared to our settings/common.py
# In production environment, you will propably adjust this!
<Directory {{ project_directory }}/run/media>
Options -Indexes
Order deny,allow
Allow from all
</Directory>
LogLevel warn
# PROJECT_NAME is used to seperate the log files of this application
ErrorLog ${APACHE_LOG_DIR}/{{ project_name }}_error.log
CustomLog ${APACHE_LOG_DIR}/{{ project_name }}_access.log combined
</VirtualHost>
You may see my project-skeleton on GitHub and here is the documentation of the Apache2-conf on RTD.org
I am trying to make my Flask application work on CentOS server. Basically the issue is that I have Python 2.6 installed in /usr/bin which is system default and Python 3.4 installed in /usr/local/bin. I would like to use Python 3.4 virtualenv or at least Python 3.4 interpreter for mod_wsgi to run my application.
I have created virtualenv in ~/virtualenvs/flask.
I have this WSGI script:
import os
import sys
from logging import Formatter, FileHandler
APP_HOME = r"/home/fenikso/Album"
activate_this = os.path.join("/home/fenikso/virtualenvs/flask/bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))
sys.path.insert(0, APP_HOME)
os.chdir(APP_HOME)
from app import app
handler = FileHandler("app.log")
handler.setFormatter(Formatter("[%(asctime)s | %(levelname)s] %(message)s"))
app.logger.addHandler(handler)
application = app
And following config in Apache:
<VirtualHost *:80>
ServerName album2.site.cz
Alias /static "/home/fenikso/Album/static"
Alias /photos "/home/fenikso/Album/photos"
Alias /thumbs "/home/fenikso/Album/thumbs"
WSGIScriptAlias / "/home/fenikso/Album/wsgi.py"
<Directory "/home/fenikso/Album">
AllowOverride None
Allow from all
</Directory>
<Directory "/home/fenikso/Album/static">
AllowOverride None
Allow from all
</Directory>
<Directory "/home/fenikso/Album/photos">
AllowOverride None
Allow from all
</Directory>
<Directory "/home/fenikso/Album/thumbs">
AllowOverride None
Allow from all
</Directory>
</VirtualHost>
However, when trying to run the application, I get an error:
Apache/2.2.15 (Unix) DAV/2 mod_wsgi/3.2 Python/2.6.6 mod_fcgid/2.3.7 PHP/5.3.3 mod_ssl/2.2.15 OpenSSL/1.0.1e-fips SVN/1.6.11 mod_perl/2.0.4 Perl/v5.10.1 configured -- resuming normal operations
mod_wsgi (pid=14627): Target WSGI script '/home/fenikso/Album/wsgi.py' cannot be loaded as Python module.
mod_wsgi (pid=14627): Exception occurred processing WSGI script '/home/fenikso/Album/wsgi.py'.
Traceback (most recent call last):
File "/home/fenikso/Album/wsgi.py", line 15, in <module>
from app import app
File "/home/fenikso/Album/app.py", line 1, in <module>
from flask import Flask
ImportError: No module named flask
I have noticed that either Python 2.6 is being ran and my virtualenv is not activated. What would be the proper way to get this working and still have the Python 2.6 as a system default?
You have to add the following line in your apache.conf in order to give the right executable and the path to the virtualenv.
WSGIPythonHome /usr/local/bin
WSGIPythonPath /home/fenikso/virtualenv/lib/python3.4/site-packages
You will find all the options of these two command in the mod_wsgi documentation
Be aware that you must have the version of mod_wsgi compatible with the python executable. In your case, you probably have to install mod_wsgi3.4 and configure apache to use it instead of the standart mod_wsgi module.
The whole configuration file should be :
WSGIPythonHome "/usr/local/bin"
WSGIPythonPath "/home/fenikso/virtualenv/lib/python3.4/site-packages"
<VirtualHost *:80>
ServerName album2.site.cz
Alias /static "/home/fenikso/Album/static"
Alias /photos "/home/fenikso/Album/photos"
Alias /thumbs "/home/fenikso/Album/thumbs"
WSGIScriptAlias / "/home/fenikso/Album/wsgi.py"
<Directory "/home/fenikso/Album">
AllowOverride None
Allow from all
</Directory>
<Directory "/home/fenikso/Album/static">
AllowOverride None
Allow from all
</Directory>
<Directory "/home/fenikso/Album/photos">
AllowOverride None
Allow from all
</Directory>
<Directory "/home/fenikso/Album/thumbs">
AllowOverride None
Allow from all
</Directory>
</VirtualHost>
Look into the WSGIPythonHome and WSGIPythonPath directives. It's also possible that you have a python2.6 mod_wsgi installed, mod_wsgi must be compiled for the intended python version and does not support multiple python versions. So check that your mod_wsgi is py3.4 compatible and set the directives above.
Alternatively, you could run the flask app with a python server like gunicorn and proxypass from apache to gunicorn.
Another option, which I believe is much cleaner, logical, and flexible, is to simply reference the python interpreter from your venv at the beginning of your wsgi file. This way, it is easy to change (no fiddling with system config files) and opens the possibility for multiple apps running with different python environments, like so:
#!/path/to/your/venv/bin/python
If the python version installed on the system is different from the python version used in the virtual environment, then mod_wsgi will not work because mod_wsgi is always compiled for a specific python version.
In this situation, you need to install mod_wsgi in a virtual environment
pip install mod_wsgi-standalone
Then such a module should be loaded instead of the default one installed in the system.
For Ubuntu for example, modify the path to the module in /etc/apache2/mods-available/wsgi.load
LoadModule wsgi_module /home/user/etc/.venv/lib/python3.9/site-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so
Then in order to avoid the error "no such file or directory: mod_wsgi (pid=XXXX): Couldn't bind unix domain socket '/usr/local/opt/httpd/logs/wsgi.xxxxx.11.1.sock" should be added to the httpd.conf file:
WSGISocketPrefix /var/run/wsgi
After restarting apache everything should work
I'm using centos, apache, mod_wsgi on server for django project.
After uploading over sftp of changed project files site opens with changes and without changes randomly.
I think, that changes should not be applied before restarting apache. Isn't it?
Apache settings
<VirtualHost *:88>
ServerName h1.ru
UseCanonicalName Off
ServerAdmin "admin#h1.ru"
DocumentRoot /var/www/h1/h1.ru/
AllowEncodedSlashes On
WSGIDaemonProcess h1 processes=4
#WSGIProcessGroup h1
WSGIScriptAlias /site /var/www/h1/pyh1/h1/wsgi.py
Alias /static /var/www/h1/pyh1/static
<IfModule mod_ssl.c>
SSLEngine off
</IfModule>
<Directory /var/www/h1/h1.ru>
php_admin_flag engine on
php_admin_flag safe_mode off
php_admin_value open_basedir "/var/www/h1/h1.ru:/tmp"
Options -Includes -ExecCGI
</Directory>
</VirtualHost>
wsgi:
#!/usr/local/bin/python2.7
import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "h1.settings")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Not true. Normally mod_wsgi will run in multiple separate processes, managing their startup and shutdown automatically. When a new process starts, Python code will be loaded from disk as it is imported, so that process will run with the newest versions of any files. Meanwhile, any processes that were already alive will use the versions they had previously loaded, so will not reflect the changes (unless a little-used code path is activated which leads to importing a so-far-unimported module).
Certainly the only way to be sure you have the latest choose in all processes is to restart Apache.
I am deploying a Django project on Apache. and after configuration, I open the "localhost" in the browser, and nothing showed up and the status bar just keep saying "Waiting for localhost". Here is some info.
1.Environment:
OS: Red Hat Enterprise Linux Server x86
Python: 2.7.2
Django: 1.3.1
Mod_wsgi: 3.3
Apache: 2.2.21
Django project: /var/www/html/server/video1
2.Apache Config file lines added:
LoadModule wsgi_module modules/mod_wsgi.so
WSGIScriptAlias / /var/www/html/server/video1/apache/django.wsgi
Alias /media/ /usr/local/apache2/htdocs/media/
Alias /static/ /usr/local/apache2/htdocs/static/
<Directory "/var/www/html/server/video">
Order Deny,Allow
Allow from all
</Directory>
<Directory "/usr/local/apache2/htdocs/media">
Order Deny,Allow
Allow from all
</Directory>
<Directory "/usr/local/apache2/htdocs/static">
Order Deny,Allow
Allow from all
</Directory>
3.Django.wsgi file:
import os
import os.path
import sys
sys.path.append('/var/www/html/server')
sys.path.append('/var/www/html/server/video')
os.environ['DJANGO_SETTINGS_MODULE'] = 'video1.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
4.settings.py lines added:
MEDIA_ROOT='/usr/local/apache2/htdocs/media/'
MEDIA_URL='/media/'
STATIC_ROOT='/usr/local/apache2/htdocs/static/'
STATIC_URL='/static/'
ADMIN_MEDIA_PREFIX='static/admin'
TEMPLATES_DIR = {
"/var/www/html/server/video1/templates"
}
INSTALLED_APPS = {
'django.contrib.admin'
}
5.restart apache
These are what I did, can someone help me to see if somewhere is wrong?
Thank you very much
The path '/var/www/html/server/video' doesn't match what you have in WSGIScriptAlias.
Besides that, did you actually try and deploy a WSGI hello world program first?
Also try setting LogLevel to info in Apache instead of warn. The Apache error log will then contain messages to say whether the WSGI script file is loaded. Right now not obvious whether your browser can't even contact server, or whether WSGI application loaded, but not responding.