12

I'm trying to serve a little django project with the following Apache configuration :

Apache virtualhost configuration :

<VirtualHost *>
    ServerName servername

    [...]

    <Directory "/path/to/project/project">
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>

    WSGIDaemonProcess project python-path=/path/to/project:/path/to/Envs/venv/lib/python3.5/site-packages                           
    WSGIScriptAlias / /path/to/project/project/wsgi.py

</VirtualHost>

I also have the following wsgi.py :

import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
application = get_wsgi_application()

I have no problem to serve STATIC files and MEDIA files.

I also checked permissions and tried to recursively use 755, then 777 to my virtualenv's site-package directory. It didn't work.

But when trying to reach the root of my site I get the following :

from django.core.wsgi import get_wsgi_application
ImportError: No module named 'django'

I guessed that it was a Python path related problem since django is installed in my virtualenv. But I added the relevant python paths to the WSGIDaemonProcess's python-path attribute so I don't get why it doesn't work.

I also guess I could add the relevant directory to my Python path in my wsgi.py by using the site module, but I'd like to understand why the Apache configuration I tried isn't enough. Did I miss something?

Community
  • 1
  • 1
vmonteco
  • 14,136
  • 15
  • 55
  • 86
  • Does [this](https://stackoverflow.com/questions/59088010/wsgi-importerror-no-module-named-hello-module-in-the-same-directory-of-the-ma/59089237#59089237) solve the problem for you too? – Basj Nov 28 '19 at 12:52

4 Answers4

23

You are missing a WSGIProcessGroup directive or equivalent option on WSGIScriptAlias, so your application isn't actually being run in that daemon process group where you have set the virtual environment.

See Using mod_wsgi daemon mode

I would also recommend ensuring application group is set to '%{GLOBAL}' if that is the only application you are running in the daemon process group.

Thus use:

WSGIScriptAlias / /path/to/project/project/wsgi.py \
    process-group=project application-group=%{GLOBAL}

Also better to use python-home for the virtual environment.

    WSGIDaemonProcess project python-path=/path/to/project \
        python-home=/path/to/Envs/venv

See:

Graham Dumpleton
  • 57,726
  • 6
  • 119
  • 134
7

My rep is not over 50 so I cannot comment, but I'd like to share my discovery.

In WSGIDaemonProcess, if you are using Python 3.5, you need to set exactly as @graham-dumpleton say, with

python-home=/path/to/Envs/venv

set explicitly.

However, if you are using Python 3.4 (or some older version Python like 2.7 as far as I know), you'll have to configure it as

python-path=/path/to/project:/path/to/Envs/venv/lib/python3.4/site-packages

just like what the asker did.

Really weird.

Valorad
  • 726
  • 1
  • 10
  • 20
  • 2
    If using Python 3.4 or 2.7, you should still use ``python-home``. I know of no issues with using the non preferred way of setting ``python-path``, but it simply isn't what you should be doing. The ``python-home`` option has been the best way of setting the location of the virtual environment for a long time. So long that even Linux distros with ancient mod_wsgi versions should still work. This is the case even if the documentation may still not have been updated. :-) – Graham Dumpleton Oct 07 '16 at 03:50
  • @graham-dumpleton Thanks for your advice. But in my case, I'm using python 3.4, and the setting was the "python-home" way as you mentioned. However, my site cannot be visited, as Apache keeps sending error "Import Error:No module named 'site'". As long as I configure it to "non preferred way", using ":" like the asker did, this issue was solved. And yes, for Python 3.5, you should use "python-home" way, or [ImportError : No module named 'django'] issue will rise. – Valorad Oct 07 '16 at 06:12
  • 2
    That means your mod_wsgi is not actually compiled for that version of Python. You cannot force mod_wsgi to use a different Python version than it was compiled for. One of the problems with using ``python-path`` is that it doesn't show as well when you are doing the wrong thing and trying to force mod_wsgi to use a virtual environment for a different Python version than mod_wsgi is compiled for. When using ``python-home`` it will instead fail properly thus telling you that you are doing something wrong. – Graham Dumpleton Oct 07 '16 at 06:27
  • 1
    Use the documented check for determining what Python version mod_wsgi is compiled for. If it isn't the Python version you want to use, you must uninstall mod_wsgi and install from a package one for the correct version, or compile from source code to ensure is for correct version. Do not use ``python-path`` to workaround it, as it will fail later in strange ways. http://modwsgi.readthedocs.io/en/develop/user-guides/checking-your-installation.html#python-installation-in-use – Graham Dumpleton Oct 07 '16 at 06:29
5

For me the problem was I had mod wsgi installed for python2. I had to reinstall it for python3:

sudo apt-get install libapache2-mod-wsgi-py3
Marijus
  • 4,195
  • 15
  • 52
  • 87
0

The issue for me was that I was running libapache2-mod-wsgi-py3 on python version 3.9. When I rolled back the python version to 3.7, there was no issue.

davjfish
  • 305
  • 4
  • 14