Django+Apache+Virtualenv+WSGI(Can not change the primary interpreter) - python

I have virtualenv with python 2.7.3 and any site-packages.
On this server - python 2.6.6. I need python 2.7.3 as the main interpreter
wsgi.py file:
import os
import sys
import site
# Add the site-packages of the chosen virtualenv to work with
site.addsitedir('/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7/site-packages')
# Add the app's directory to the PYTHONPATH
sys.path.append('/var/www/mts_report/mts_report_project')
sys.path.append('/var/www/mts_report/mts_report_project/mts_report_project')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mts_report_project.settings.local'
# Activate your virtual env
activate_env="/home/aaodegov/virtual_envs/basic_env_2/bin/activate_this.py"
execfile(activate_env, dict(__file__=activate_env))
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
apache config:
<VirtualHost *:80>
ServerAdmin mail
ServerName server_name
ServerAlias alias_name
DocumentRoot /var/www/mts_report/mts_report_project
WSGIDaemonProcess mts_report processes=1 maximum-requests=1 threads=1 python-path=/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7:/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7/site-packages
WSGIProcessGroup mts_report
WSGIScriptAlias / var/www/mts_report/mts_report_project/wsgi.py
Alias /static/ /var/www/mts_report/mts_report_project/static/
Alias /home/aaodegov/virtual_envs/basic_env_2/lib/python2.7/site-packages/admin/media/
<Directory /var/www/mts_report/mts_report_project>
Options +Indexes
allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/servicescripts_error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/servicescripts_access.log combined
<Location "/static/">
Options -Indexes
</Location>
</VirtualHost>
Check python version(on debug django mode):
Python Executable: /usr/bin/python
Python Version: 2.6.6
Python Path:
['/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7',
'/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7/site-packages',
'/usr/local/lib/python2.6/dist-packages/pip-1.5.6-py2.6.egg',
'/usr/lib/python2.6',
'/usr/lib/python2.6/plat-linux2',
'/usr/lib/python2.6/lib-tk',
'/usr/lib/python2.6/lib-old',
'/usr/lib/python2.6/lib-dynload',
'/usr/local/lib/python2.6/dist-packages',
'/usr/lib/python2.6/dist-packages',
'/usr/lib/pymodules/python2.6',
'/var/www/mts_report/mts_report_project',
'/var/www/mts_report/mts_report_project/mts_report_project']
As a result, Django use site-packages from virtualenv, but main interpreter - from system.
How use interpreter(2.7.3) from virtualenv?
Thx.

Yesterday the problem was solved.
Useful to those who have encountered a similar problem.
mod_vsgi was not compiled for python 2.7.
Thank you all for your answers.
First, install apache2-threaded-dev
Then, compile PYTHON with --enable-shared. This is important.
./configure --enable-shared --prefix=/usr/local/python-2.7.3
make
make install
ln -s /usr/local/python-2.7.3/bin/python2.7 /usr/bin/python2.7.3
libpython2.7.so.1.0 not found problem:
ln -s /usr/local/python-2.7.3/lib/libpython2.7.so.1.0 /usr/lib/
ln -s /usr/local/python-2.7.3/lib/libpython2.7.so /usr/
compile MOD_WSGI with python2.7.3:
./configure --with-python=/usr/bin/python2.7.3
make
make install
restart apache:
service apache2 restart

In apache config add at the beginning
WSGIPythonHome PATH_TO_YOUR_2.7.3_PYTHON
<VirtualHost *:80>
...
Note you may have to also add something like
WSGISocketPrefix ../../var/run/wsgi
Also change
python-path=/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7:/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7/site-packages
to
python-path=/home/aaodegov/virtual_envs/basic_env_2/lib/python2.7/site-packages
and you don't need references to virtualenv in wsgi.py

Related

Cannot make Python 3.10 virtual environment work with mod_wsgi / Apache webserver

I'm trying to set up a Flask webserver. I'm trying to use virtual environment with Python 3.10. I've been at it for hours, and probably have tried every suggested solution from SO, but they all don't seem to work for me https://flask.palletsprojects.com/en/2.0.x/deploying/mod_wsgi/#working-with-virtual-environments. It just keeps defaulting to the system Python version. Is it even compatible with Python3.10 yet? With the system Python 3.8 (Ubuntu 20) venv it works completely fine for some reason...
.wsgi file:
#!/var/www/html/myApp/env/bin/python3
activate_this = '/var/www/html/myApp/env/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
import sys
print(sys.version)
sys.path.insert(0, "/var/www/html/myApp/")
from flask_app import app as application
Apache:
<VirtualHost *:80>
WSGIDaemonProcess myApp python-home=/var/www/html/myApp/env/
WSGIScriptAlias / /var/www/html/confgen-webapp/myApp.wsgi
<Directory /var/www/html/myApp>
WSGIProcessGroup myApp
WSGIApplicationGroup %{GLOBAL}
Order deny,allow
Allow from all
</Directory>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Django ModuleNotFoundError: No module named 'myProject'

ModuleNotFoundError: No module named 'myProject' error, but I do not know the cause. I am glad if you tell me.
・ CentOS 7.2
・ Python 3.6
・ Django 2.0
・ apache 2.4
I set the virtual environment as follows
pip install virtualenv
mkdir xxx
cd xxx
python3 -m venv xxx
source xxx/bin/activate
pip install mod_wsgi
mod_wsgi-express module-config
LoadModule wsgi_module "/home/username/myProject/myProject/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so"
WSGIPythonHome "/home/username/myProject/myProject"
■ /etc/httpd/conf.d/django.conf
NameVirtualHost *:80
LoadModule wsgi_module /home/username/myProject/myProject/lib/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
WSGIPythonHome /home/username/myProject/myProject
WSGISocketPrefix /var/run/wsgi
<VirtualHost *:80>
ServerName xxx.com
DocumentRoot /home/username
WSGIApplicationGroup %{GLOBAL}
WSGIDaemonProcess xxx python-home=/home/username/myProject/myProject python-path=/home/username/myProject/myProject/lib/python3.6/site-packages
WSGIProcessGroup xxx
WSGIScriptAlias / /home/username/myProject/myProject/wsgi.py
<Directory /home/username/myProject/myProject/static>
Require all granted
</Directory>
<Directory /home/username/myProject/myProject>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
■ wsgi.py
import os,sys
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")
application = get_wsgi_application()
Read:
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
The WSGIPythonHome directive or python-home option should point at the root directory for the Python virtual environment. This should be the same value as sys.prefix has when Python is run for that virtual environment.
The WSGIPythonPath directive or python-path option would then be set to your project code directory in which modules/packages exist, likely /home/username/myProject in your case.
Do not use these later options to point at the site-packages directory, use the first options for specifying the location of the virtual environment.
I would suggest since you are using daemon mode to add:
WSGIRestrictEmbedded On
after the LoadModule line. Then remove the WSGIPythonHome and WSGIPythonPath and rely on python-home and python-path options on WSGIDaemonProcess instead.
BTW, DJANGO_SETTINGS_MODULE wouldn't be xxx.settings. You likely mean myProject.settings.
Also, it appears that you have your virtual environment being your project code directory. If that is the case, is not really recommended. Create the virtual environment as a distinct sub directory somewhere of its own. Don't intermingle it with your code as then it becomes really hard to remove the virtual environment and re-create it.

Mod wsgi not using virtualenv python version on Arch linux

I have a website running on apache-python2(virtualenv)-flask stack on Arch linux server. It seems that wsgi application is not picking up the python from virtualenv, and instead uses system's python.
web/test.py
import sys
print(sys.version)
Result in: error_log
3.4.3 (default, Mar 25 2015, 17:13:50)
The default python on the server is
$ python --version
Python 3.4.3
The virtual environment I intend to use has python2
$ virtualenv -p /usr/bin/python2.7 flask
$ source flask/bin/activate
$ python --version
Python 2.7.10
The virtualhost apache file:
/etc/httpd/conf/vhosts/msw.com
<VirtualHost *:80>
ServerName msw.com
ServerAlias www.msw.com
ServerAdmin webmaster#localhost
WSGIDaemonProcess msw user=live group=live threads=5 python-path=/home/live/msw/flask/lib/python2.7/site-packages
WSGIScriptAlias / /home/live/msw/msw.wsgi
<Directory /home/live/msw>
#Header set Access-Control-Allow-Origin "*"
WSGIScriptReloading On
WSGIProcessGroup msw
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
Options All
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
The wsgi file:
/home/live/msw/msw.wsgi
import sys
activate_this = '/home/live/msw/flask/bin/activate_this.py'
#execfile(activate_this, dict(__file__=activate_this))
with open(activate_this) as f:
code = compile(f.read(), activate_this, 'exec')
exec(code, dict(__file__=activate_this))
sys.path.insert(0, '/home/live/msw/web')
sys.path.insert(0, '/home/live/msw')
from web import msw as application
Why is mod_wsgi not picking up virtualenv's python? What am I doing wrong?
I eventually figured it out. The official arch-linux documentation is a bit confusing, mod_wsgi. It tries to imply that mod_wsgi installation will work for both Python2/3. However, mod_wsgi still ends up using system's Python3. I solved the problem by installing mod_wsgi2 which is specific to Python2.
pacman -S mod_wsgi2

Run mod_wsgi with virtualenv or Python with version different that system default

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

How to set up multiple django versions on single apache service?

I'm using Windows XP and want to know how can I create multiple django versions on a single apache service through virtual host(of course).
I'm trying to do that with one instance of python too. Should i create 1 instance of python for each django version or django needs only its eggs to work, so I can have several eggs in just one python version?
You can do something like this in your httpd.conf
NameVirtualHost 0.0.0.0:80
<VirtualHost 0.0.0.0:80>
ServerName myserver.com
ServerAdmin myemail#gmail.com
DocumentRoot "/path/to/html/root"
ErrorLog "/path/to/apache-error.log"
CustomLog "/path/to/apache-access.log" common
Options ExecCGI FollowSymLinks MultiViews
AddHandler wsgi-script .wsgi
WSGIDaemonProcess djangoapp1
WSGIProcessGroup djangoapp1
WSGIScriptAlias / /path/to/djangoapp1.wsgi
Alias /static /path/to/static/files
DirectoryIndex index.html index.cgi
AddHandler cgi-script .cgi .pl
</VirtualHost>
NameVirtualHost 0.0.0.0:81
<VirtualHost 0.0.0.0:81>
ServerName myserver.com
ServerAdmin myemail#gmail.com
DocumentRoot "/path/to/html/root"
ErrorLog "/path/to/apache-error.log"
CustomLog "/path/to/apache-access.log" common
Options ExecCGI FollowSymLinks MultiViews
AddHandler wsgi-script .wsgi
WSGIDaemonProcess djangoapp2
WSGIProcessGroup djangoapp2
WSGIScriptAlias / /path/to/djangoapp2.wsgi
Alias /static /path/to/static/files
DirectoryIndex index.html index.cgi
AddHandler cgi-script .cgi .pl
</VirtualHost>
And then, in your djangoapp1.wsgi/djangoapp2.wsgi script you can define the different django versions and applications:
#!/usr/bin/python
import os
import sys
sys.path.append('')
sys.path.append('/path/to/python2.7/site-packages')
sys.path.append('/path/to/python2.7/dist-packages/Django-1.3-py2.7.egg ')
... etc ...
sys.path.append('/path/to/djangoapp1/src')
os.environ['DJANGO_SETTINGS_MODULE'] = 'djangoapp1.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Method 1:
put django source anywhere you want and manually specify path to django source in your manage.py and wsgi.py:
import os
os.path.insert(0, 'path-to-django-source');
You can also use virtualenv. Virtualenv fixes paths for console apps automatically, however for wsgi.py you still have to write down path's manually.
Method 2:
Use zc.buildout and djangorecipe, it will do all the stuff for you including:
donwloads django
download other modules
creates wsgi.py at project-dir\bin\wsgi
creates manage.py at project-dir\bin\django.exe
All this is done with a single config file buildout.cfg- here you list your modules and other settings, and then you run a command: buildout -N.
However buildout might not be a good solution if you have tight deadlines because there will be things you'll need learn about it but if you are planning to do more python apps I definitely recommend trying it.
Here are some examples for django+buildout setup:
http://www.google.lt/search?q=django+buildout+template+OR+skeleton
An update to your comment
You cannot install two django versions system wide.
What you can do though is either:
Do not install django, just drop the django-base/django folder into your project path. You will have to compile the internationalization files manually (if you use i18n):
cd django\conf
python ..\..\manage.py compilemessages
Or, install django with python setup.py install, but use extra arguments to change installation destination. Python documentation covers few different methods.

Categories

Resources