Can't run Apache2 with virtualenv - python

I'm making a website based on Django, on the server was installed a Python 3.5, but my project requires a Python 3.6. I decided to use virtualenv. I successfuly installed needed version of Python but I can't make it works with Apatche2 using virtualenv.
Website is able to run only on Python 2.7, otherwise nothing happens, page is loading for a long time without any error.
Here is my VirtualHost config with my try to run on Python 3.6.
<VirtualHost *:443>
ServerName <site_adress>:443
ServerAdmin admin#<site_adress>
DocumentRoot /var/www/html/MMServer
ErrorLog /var/www/logs/error.log
CustomLog /var/www/logs/custom.log combined
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/mm.cert
SSLCertificateKeyFile /etc/apache2/ssl/mm.key
Alias /static/ /var/www/html/MMServer/static/
<Directory /var/www/html/MMServer/static>
Require all granted
</Directory>
WSGIDaemonProcess MMServer python-path=/var/www/html/MMServer python-home=/var/www/html/venv
WSGIProcessGroup MMServer
WSGIScriptAlias / /var/www/html/MMServer/mm_server/wsgi.py
<Directory /var/www/html/MMServer/mm_server>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
Below is my wsgi.py file:
import os
import sys
def application(environ, start_response):
start_response('200 OK',[('Content-type','text/html')])
return [sys.version]
Only one thing what I can get this way (while WSGIDaemonProcess and WSGIProcessGroup is deleted) is:
2.7.13 (default, Nov 24 2017, 17:33:09) [GCC 6.3.0 20170516]
Edit 1:
There is a posiblity I have missing packages, bacause I made reinstalation of python 3.5, what are required packages to work?
Solution:
I did two things, I'm not sure what exacly help me but first of all I disabled a mod (a2dismod wsgi) and deleted a package libapache2-mod-wsgi.
Option 1:
apt-get install libapache2-mod-wsgi-py3
Option 2:
I installed a mod-wsgi from the source:
wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.6.3.tar.gz
tar -xf 4.6.3.tar.gz
./configure --with-python=/usr/local/bin/python3.6
make
make install
Now everything works perfectly.
Thanks #Graham Dumpleton, your answer was helpful.

The mod_wsgi module is C code which links to the Python library. Thus the version of Python it is compiled for is embedded in the module. It doesn't just execute python program. This means it has to be compiled for the version of Python you want to use. You cannot force it via a virtual environment to use a different Python version. This is stated in the documentation on using mod_wsgi with virtual environments.
http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html
In short, you need to uninstall the mod_wsgi module (likely the operating system packaged one), and install mod_wsgi yourself from source code, compiling it against the Python version you want to use. Easiest way of doing that is to use pip install method.
https://pypi.python.org/pypi/mod_wsgi

Related

Run Django Website with different mod_wsgi than default

I have an Apache2 server hosting multiple Django websites. All except one use Django 3.8, using a mod_wsgi compiled on Python 3.7. The outlier (let's call it SiteX) uses Django 4.0, which requires Python 3.8+. I want SiteX to use a virtual environment with these newer versions of Python and Django, while the other sites keep using their default versions.
For SiteX, I've created a virtual environment venv in its directory. But from what I understand, the current mod_wsgi installed is not compatible with its version of Python, so specifying WSGIPythonHome in the conf file won't do anything.
the current mod_wsgi (4.7/python 3.7) is loaded in /etc/apache2/mods-available/wsgi.load with the line
LoadModule wsgi_module /usr/lib/apache2/modules/mod_wsgi.so
I've tried creating a new mod_wsgi, this time using the Python module mod_wsgi, which I've installed in venv. In the .conf file for a group of Django sites (that include SiteX) I tried specifying this unique version of the mod_wsgi above the <VirtualHost> block with the line:
LoadModule wsgi_module "/var/www/html/app/SiteX/venv/lib/python3.9/site-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-x86_64-linux-gnu.so"
but running $ apachectl configtest says: module wsgi_module is already loaded, skipping.
I found a solution for multiple mod_wsgi's using WSGIDaemonProcess but the solution's .conf looks slightly different that mine. Below is a snippet of the relevant lines of the .conf, but I'm not sure where to insert WSGIDaemonProcess.
<IfModule mod_ssl.c>
# LoadModule wsgi_module, WSGIPythonHome, WSGIPythonPath here?
<VirtualHost _default_:443>
...
Alias /static /var/www/html/app/imagingTracking/static/
...
# other django website Directory blocks here
...
<Directory /var/www/html/app/SiteX/static/>
Require all granted
</Directory>
<Directory /var/www/html/app/SiteX/SiteX/>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
</VirtualHost>
</IfModule>
In addition I am not sure where to locate relevant .wsgi files for this.
Is my goal even tractable? It would be a nuisance if I'd have to downgrade SiteX just for this reason.

Run wsgi with apache and django in anaconda environment

I am trying to run a django application with wsgi_mod and apache2. But for some strange reason it cannot import django.
# /etc/apache2/apache2.conf
WSGIDaemonProcess django_apps python-home=/home/swacker/miniconda3/envs/django/
WSGIProcessGroup django_apps
WSGIScriptAlias /koala /var/www/production/Koala/Koala/wsgi.py process-group=django_apps
<Directory /var/www/production/Koala/>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
The application sits in /var/www/production/Koala.
My conda enviromnent is installed in /home/user/miniconda3/envs/django.
I installed wsgi inside the conda environment.
I tried different things, but nothing worked. This is what I did to get wsgi running.
sudo apt-get install libapache2-mod-wsgi
pip install mod_wsgi
conda install -c https://conda.binstar.org/travis uwsgi
It looks like wsgi is just not working with conda environments and I have to use virtualenv?? Wsgi works, I can render a test file just fine.
Though, when I go to localhost/koala the /var/log/apache2/error.log shows:
from django.core.wsgi import get_wsgi_application
ImportError: No module named 'django'
I searched a lot, but could not find an answer that addresses this properly.

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

error when installing mod_wsgi for python 2.7

I have installed mod_wsgi from source to use python2.7 like this:
git clone https://github.com/GrahamDumpleton/mod_wsgi.git
./configure --with-python=/usr/bin/python2.7
make
make install
When I try to start apache, I get the error:
Starting httpd: Syntax error on line 1020 of /etc/httpd/conf/httpd.conf:
Invalid command 'WSGIScriptAlias', perhaps misspelled or defined by a module not included in the server configuration
[FAILED]
My httpd.conf looks like this:
Alias /static/ /var/www/html/django/shared/static/
<Directory /var/www/html/django/shared/static/>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /var/www/html/django/wsgi.py
WSGIPythonPath /var/www/html/django
<Directory /var/www/html/django>
<Files wsgi.py>
Order deny,allow
Allow from all
</Files>
</Directory>
Why is apache not finding mod_wsgi?
If that's your entire config file, you never told Apache to load the module.
That's why the error message says "Invalid command 'WSGIScriptAlias', perhaps misspelled or defined by a module not included in the server configuration".
See LoadModule for reference, DSO support for an introduction, and the sample configs that come with Apache for examples.
As #abarnert mentioned above, I didn't not add the line to the modules section of apache config. Adding that solved the problem. This apparently doesn't get added automatically when you add mod_wsgi from source as opposed to a yum install.

Categories

Resources