Can´t load virtual enviroment in Apache, WSGI, Django and Windows

Viewed 1467

I'm trying to run a Django app in my development computer with windows. I have succesfully created a virtual enviroment with virtualenv (not virtualenvwrapper), installed Django and loaded it with the internal server running python manage.py runserver. I belive all things with PHP, path variable, etc, etc, are ok.

I've also succesfully installed WSGI following the instructions of https://modwsgi.readthedocs.io/en/develop/, but just with the global Python. I've installed the mod_wsgi perfoming these steps outside the virtualenv:

set "MOD_WSGI_APACHE_ROOTDIR=C:/wamp64/bin/apache/apache2.4.41"
pip install --upgrade setuptools
pip install mod_wsgi
mod_wsgi-express module-config

Then I copied the result lines to my httpd.conf:

LoadFile "c:/program files/python35/python35.dll"
LoadModule wsgi_module "c:/program files/python35/lib/site-packages/mod_wsgi/server/mod_wsgi.cp35-win_amd64.pyd"
WSGIPythonHome "c:/program files/python35"

Created an Alias in httpd.conf

Alias /test/ "C:/wamp64/apps/wsgi_app/"
<Location /test>
  SetHandler wsgi-script
  Options +ExecCGI
</Location>
<Directory "C:/wamp64/apps/wsgi_app">
  Options Indexes FollowSymLinks
  Require local
</Directory>

and successfully served a wsgi file:

import sys
def application(environ, start_response):
    status = '200 OK'
    output = u''
    output += u'sys.version = %s\n' % repr(sys.version)
    output += u'sys.prefix = %s\n' % repr(sys.prefix)
    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)
    return [output.encode('UTF-8')]

It works like a charm, indicating I don't have problems with VC versions, Python versions and so on.

When I try to do the same thing in a virtual environment, it seems that Apache can't load it. I did everything similar, installed everything from the scratch in my venv. The only different thing is that mod_wsgi-express module-config produces a different result:

LoadModule wsgi_module "c:/wamp64/venv/lib/site-packages/mod_wsgi/server/mod_wsgi.cp35-win_amd64.pyd"
WSGIPythonHome "c:/wamp64/venv"

The Apache server starts: Apache/2.4.41 (Win64) mod_fcgid/2.3.10-dev mod_wsgi/4.7.1 Python/3.5 PHP/7.3.12 configured -- resuming normal operations just to crash immediately Fatal Python error: Py_Initialize: unable to load the file system codec ImportError: No module named 'encodings'

I've tryed to initiate Apache with the venv previously activated in a cmd window and without previously activating it. It seems that Apache is not seeing or is not activating the virtual environment. The problem occurs before any Django interference, I can't even serve that test file that i showed. I even tryed to add a LoadFile "C:/wamp64/venv/Scripts/python35.dll" in httpd.conf but to no avail.

Is there anything I'm missing? Any help would be greatly appreciated.

1 Answers

I noticed this to be the case with more recent versions of apache24 and mod_wsgi. It wasn't the case when I ran the setup over a year ago, but over the past couple of days it's been gruelling attempting the setup again (with mod_wsgi 4.7.1 and apache 2.4.46).

Part of problem seems to be that because most of the core python modules are not directly available under the venv directory (as virtualenv does not copy those files to the venv directory, by design), somehow these new versions do not successfully find the encodings module (and possibly others), since the latter doesn't live under venv. E.g. when you activate your virtual environment and run

import encodings
encodings.__file__

you'd get the system-wide python lib directory, in my case c:/program files/python37/lib/encodings/__init__.py.

Try instead:

WSGIPythonHome "c:/program files/python37/"
WSGIPythonPath "/path/to/venv/site-packages;path/to/your/app/root/folder"

This solved the problem for me. It's similar to this answer, which helped me understand better what I'd been suspecting.

Related