How do I set a python path when using WSGIAuthUserScript? - python

I'm trying to implement Apache Basic Auth using mod_wsgi's WSGIAuthUserScript directive, and I can't figure out how to specify a python path. I'm using Django for the authentication, as detailed here, and I'm getting errors like:
Traceback (most recent call last):
File "/path-to-site/src/project/wsgi.py", line 21, in <module>
from django.contrib.auth.handlers.modwsgi import check_password
ImportError: No module named django.contrib.auth.handlers.modwsgi
My WSGIDaemonProcess directive uses the python-path option (pointing to a virtualenv's site-packages) but there doesn't seem to be a similar option for WSGIAuthUserScript. I've tried setting WSGIPythonPath, and setting the application-group option for WSGIAuthUserScript, but neither helped.

WSGIPythonPath should have worked. That or setting sys.path in the WSGI script file itself. What are you setting it to? Where is django installed? Does the user that Apache runs as have read permission down into where you have it installed?

I had similar problem, WSGIAuthUserScript does not use WSGIPythonPath or WSGIPythonHome nor process group. 2 solutions that worked for me:
Solution 1) compile mod_wsgi in your virtual env
# load your virtual environment
. bin/activate
# compiles AXXS needed by mod WSGI
pip install mod_wsgi-httpd
# Compile mod WSGI
pip install mod-wsgi
Install the mod_wsgi module in apache (CentOS & Co)
mod_wsgi-express install-module > /etc/httpd/conf.modules.d/25-wsgi.conf
Install the mod_wsgi module in apache (Debian & Co)
mod_wsgi-express install-module > /etc/apache2/mods-available/wsgi.conf
a2enmod wsgi
All your script should use your virtual env now.
Solution 2) load your venv within your auth script
python_home = "/myt_venv_path/"
sys.path.append(python_home)
# Needed by WSGIAuthUserScript
activate_this = python_home + '/bin/activate_this.py'
with open(activate_this) as venv:
exec(venv.read(), {'__file__': activate_this})

Related

mod_wsgi can't import flask with pipenv

I'm trying to deploy my first flask application and I'm running into some issues. I had my app working on my local machine with the build in flask development server, and all my dependencies were managed by pipenv. I uploaded my app to /var/www/directory_printer and ran pipenv install. Then I created a apache vhost file and pointed it to my .wsgi file:
WSGIScriptAlias / /var/www/directory_printer/directory.wsgi
In directory.wsgi, I import my app. At the beginning of my main app file, I import flask. When I try to access my app, I get a 500 error. In the apache error log I get:
ModuleNotFoundError: No module named 'flask'
If I start an interactive python shell in the directory_printer folder with the pipenv shell activated, I can import flask just fine.
I tried putting the path to my virtual env at the beginning of my directory.wsgi file:
#!/path/to/venv
but that doesn't seem to help. I'm sure I'm missing something simple, but I can't seem to see what it is. Any help would be appreciated. Thanks!
Often on Linux systems a home directory is not accessible to other users so the Apache user will not be able to read anything under the directory. Permissions can also be wrong on Python packages that have been installed making them inaccessible as well.
Ok, not sure if this is the correct answer, but it is now working for me.
First
create a .venv folder in the project root folder
then change permissions:
sudo chown www-data:www-data .venv
Then create a virtual environment and install your requirements from Pipfile as the user wsgi will run as:
sudo -su www-data python3 -m virtualenv -p python3 .venv pipenv install
This will install your virtual environment in the project folder. Check out this answer for more:
How to set PIPENV_VENV_IN_PROJECT on per-project basis
Then add this to your .wsgi folder:
with open(activate_this) as file_:
exec(file_.read(), dict(__file__=activate_this))
Bottom of this page for more info:
https://flask.palletsprojects.com/en/2.0.x/deploying/mod_wsgi/
And now it works! Hopefully this will help somebody else out as well.

mod_wsgi - Fatal Python error: initfsencoding: unable to load the file system codec

Using Red Hat, apache 2.4.6, worker mpm, mod_wsgi 4.6.5, and Python 3.7 When I start httpd I get the above error and:
ModuleNotFoundError: No module named 'encodings'
In the httpd error_log.
I'm using a python virtual environment created from a python installed from source under my home directory. I installed mod_wsgi from source using --with-python= option pointing to the python binary in my virtual environment, then I copied the mod_wsgi.so file into my apache modules directory as mod_wsgi37.so
I ran ldd on this file, and have a .conf file loading it into httpd like this:
LoadFile /home/myUser/pythonbuild/lib/libpython3.7m.so.1.0
LoadModule wsgi_module modules/mod_wsgi37.so
Then within my VirtualHost I have:
WSGIDaemonProcess wsgi group=www threads=12 processes=2 python-path=/var/
www/wsgi-scripts python-home=/var/www/wsgi-scripts/wsgi_env3
WSGIProcessGroup wsgi
WSGIScriptAlias /test /var/www/wsgi-scripts/test.py
from my virtual environment:
sys.prefix:'/var/www/wsgi-scripts/wsgi_env3'
sys.real_prefix:'/home/myUser/pythonbuild'
When I switch to the system-installed mod_wsgi/python combo (remove python-home line from WSGIDaemonProcess, and change the .conf file to load the original mod_wsgi.so) it works fine. It seems like some path variables aren't getting set properly. Is there another way to set variables like PYTHONHOME that I'm missing? How can I fix my install?
I had a very similar issue and I found that my manually specified LoadModule wsgi_module "/path_to_conda/" was being ignored because the previously apache-wide wsgi mod was being loaded. You can check if wsgi.* is present in /etc/apache2/mods-enabled.
If that is the case, consider a2dismod wsgi to disable the apache wsgi that loads the wrong python.
As I ran into this problem recently, I found a solution that works in my environment.
I don't work with a virtual environment, but have a non-standard python installation in my home folder (compiled and installed without root access) - this should be similar to a virtual environment.
My virtual host config is structured as follows:
WSGIPythonHome /home/myuser/usr/
<VirtualHost *:80>
...
WSGIDaemonProcess wsgi home=/path/to/my/project/folder processes=10 threads=10
WSGIScriptAlias / /path/to/my/project/folder/wsgi.py
WSGIProcessGroup wsgi
</VirtualHost>
First, I omitted python-path completely. Further, WSGIPythonHome should point to the parent folder of the bin/, lib/ and include/ directories with the python libraries.
I made the mistake to point it towards the bin/ folder.
Consequentially, WSGI could not load the default libraries, even when I added them to the python path manually via WSGIPythonPath.

Trouble hosting Django website in Ubuntu (Error)

I need to host a Django website in Ubuntu 18 (Desktop). I searched the web but couldn't find a well-written tutorial which demonstrates how to do this step by step. After doing some research I came across following procedure but I believe its incomplete.
Library installed
sudo apt-get install python3.6
pip3 install Django
sudo apt-get install apache2
sudo apt-get install libapache2-mod-wsgi
The project named mysite with an app polls and virtual environment mysite_env is located in /var/www with following directory structure
Configured wsgi.py at follows
import os
import sys
from django.core.wsgi import get_wsgi_application
sys.path.append('/var/www/mysite')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
application = get_wsgi_application()
Added following lines in apache2.conf located in etc/apache2/apache2.conf
#ServerName mysite.com
WSGIScriptAlias / /var/www/mysite/mysite/wsgi.py
WSGIPythonHome /var/www/mysite/mysite_env
#WSGIPythonPath /path/to/mysite.com
<Directory /var/www/mysite/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
If everything setups perfectly then on opening localhost in the browser will let Apache server to open Django app but on the other hand, by doing it Django app doesn't loads.
I am missing lots of things I know, I need to host it and access it on the web. Can anybody tell me what steps I am missing, Any suggestions would be of great help.
References
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/modwsgi/y
I followed this simple step to step tutorial which I can recommend. It is for Ubuntu 16.04 but I believe you can simply transfer it to 18.04
https://simpleisbetterthancomplex.com/tutorial/2016/10/14/how-to-deploy-to-digital-ocean.html

What is the point of a django virtualenv, if when deploying with apache, wsgi.py is executed on the server NOT in the virtualenv?

I have my apache config set up to point to my virtualenv, but when i load the page and look at the error log it gives the following error:
from django.core.wsgi import get_wsgi_application
ImportError: No module named django.core.wsgi
apache2 000-default.conf file:
WSGIDaemonProcess project python-home=/home/django/config/env python-path=/usr/local/bfx/Databases/project
WSGIProcessGroup project
WSGIScriptAlias / /usr/local/bfx/Databases/project/project/wsgi.py
Basically, it will work if I install django, and all my django packages on my server, but what is the point of the virtual env?
Thanks
Virtualenv allows to create isolated environments. So you could create and run multiple projects with different versions of the same library without conflicts, for example.
You have to install all libraries in the server too. Virtualenv do not create a bundle nor deploy it.

Invalid command 'WSGIReloadMechanism' in my Apache site's config file

I am trying to deploy a Django project and am using Apache2 with mod_wsgi. Here are the relevant lines in my Apache conf file:
WSGIScriptReloading On
WSGIDaemonProcess myprojectcom
WSGIReloadMechanism Process
WSGIProcessGroup myprojectcom
WSGIApplicationGroup myprojectcom
WSGIPassAuthorization On
WSGIScriptAlias / /home/myproject/myproject/deploy/deploy.wsgi
I've used a very similar conf file for many other deployments, but this is the first time that I'm getting the following error:
/etc/apache2/sites-available$ sudo /etc/init.d/apache2 restart
Syntax error on line 8 of /etc/apache2/sites-enabled/myproject.com:
Invalid command 'WSGIReloadMechanism', perhaps misspelled or defined by a module not included in the server configuration
Action 'configtest' failed.
The Apache error log may have more information.
...fail!
I don't see any syntax error, though. I'm on Ubuntu, using the libapache2-mod-wsgi package. What could be wrong?
Remove the whole line:
WSGIReloadMechanism Process
It isn't needed any more and the directive was removed completely in mod_wsgi 3.X.
You should preferable not rely on old blog posts for how to set up mod_wsgi and use the actual mod_wsgi documentation on the mod_wsgi site instead.

Categories

Resources