3

Trying to get my django project hosted using apache2 and mod_wsgi. I've tried various configurations, but keep getting import errors when hitting the site in a browser such as:

Traceback (most recent call last):
  File "/home/user/projects/my_projectMain/my_project/my_project/wsgi.py", line 19, in <module>
    application = get_wsgi_application()
  File "/usr/local/lib/python3.4/dist-packages/django/core/wsgi.py", line 13, in get_wsgi_application
    django.setup(set_prefix=False)
  File "/usr/local/lib/python3.4/dist-packages/django/__init__.py", line 22, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
  File "/usr/local/lib/python3.4/dist-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/usr/local/lib/python3.4/dist-packages/django/conf/__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "/usr/local/lib/python3.4/dist-packages/django/conf/__init__.py", line 97, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2212, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2224, in _find_and_load_unlocked
ImportError: No module named 'my_project'

Here's my directory structure(/home/user/projects/my_projectMain/):

-- my_projectEnv\ (virtualenv w/ python 3.5.2, django 1.10, django-bootstrap3, django-static-jquery==2.1.4)
-- my_project\
 |-- app\
 |-- manage.py
 |-- static\
 |-- my_project\
 |-- | -- __init__.py
 |-- | -- __pycache__
 |-- | -- settings.py
 |-- | -- wsgi.py
 `-- | -- urls.py

wsgi.py:

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings")

application = get_wsgi_application()

/etc/apache2/sites-available/000-default.conf:

...
#ServerName www.example.com

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html    

Alias /static /home/user/projects/my_projectMain/my_project/static
        <Directory /home/user/projects/my_projectMain/my_project/static>
            Require all granted
        </Directory>

        <Directory /home/user/projects/my_projectMain/my_project/my_project>
            <Files wsgi.py>
                Require all granted
            </Files>
        </Directory>

        WSGIDaemonProcess my_project python-path=/home/user/projects python-home=/home/user/projects/my_projectMain/my_projectEnv
        WSGIProcessGroup my_project
        WSGIScriptAlias / /home/user/projects/my_projectMain/my_project/my_project/wsgi.py
...

I'm concerned about my directory structure being the problem, but also have seen a lot of other posts related to the path not being correct in wsgi.py.


EDIT: If I change python-path to:

WSGIDaemonProcess my_project python-path=/home/user/projects/my_projectMain/my_project/my_project

I get:

 Traceback (most recent call last):
   File "/home/user/projects/my_projectMain/my_project/my_project/wsgi.py", line 25, in <module>
     application = get_wsgi_application()
   File "/usr/local/lib/python3.4/dist-packages/django/core/wsgi.py", line 13, in get_wsgi_application
     django.setup(set_prefix=False)
   File "/usr/local/lib/python3.4/dist-packages/django/__init__.py", line 27, in setup
     apps.populate(settings.INSTALLED_APPS)
   File "/usr/local/lib/python3.4/dist-packages/django/apps/registry.py", line 85, in populate
     app_config = AppConfig.create(entry)
   File "/usr/local/lib/python3.4/dist-packages/django/apps/config.py", line 90, in create
     module = import_module(entry)
   File "/usr/lib/python3.4/importlib/__init__.py", line 109, in import_module
     return _bootstrap._gcd_import(name[level:], package, level)
   File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
   File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
   File "<frozen importlib._bootstrap>", line 2224, in _find_and_load_unlocked
 ImportError: No module named 'django_static_jquery'
  1. Does this mean that I've gotten past it not being able to import my_project?
  2. I've ran collectstatic and ensured that static_jquery is in my STATIC_ROOT, how could it not be able to import that installed app?
brewcrazy
  • 623
  • 13
  • 30
  • Likely unrelated, but you cannot use mod_wsgi compiled against Python 3.4 with a Python virtual environment constructed using Python 3.5. Mixing the streams is bad and can cause various problems. See http://modwsgi.readthedocs.io/en/develop/user-guides/virtual-environments.html which warns about that. – Graham Dumpleton Mar 02 '17 at 23:21
  • I noticed that too and will fix it later as long as you think its unrelated to the issue above. – brewcrazy Mar 03 '17 at 00:26
  • I would fix it first. Nothing is guaranteed without it matching properly. Also check whether your directories/files have permissions which the user that Apache runs as could access. – Graham Dumpleton Mar 03 '17 at 04:24
  • This is end up being a problem. Details in my answer. Thanks for the assistance. – brewcrazy Mar 04 '17 at 18:17
  • Are you saying you dropped the ``python-home``? What you changed ``python-path`` to looks wrong based on other information you provide about directory structure. You sure you didn't change other things? – Graham Dumpleton Mar 04 '17 at 22:28
  • I added my final dir structure and details from 000-default.conf below. – brewcrazy Mar 04 '17 at 23:21

2 Answers2

1

I was doing a few things wrong that contributed to the error(s) that I was getting. Some of which may be obvious to more experienced users, but hopefully writing about these lessons will help someone else down the road. I know that I had to dig pretty deep and in many man locations to figure some of this stuff out.

I learned that once a virtualenv is set up (virtualenv -p /usr/local/bin/python3 <path/to/new/virtualenv/> btw), you should only use pip and python (as opposed to pip3 and python3 respectively) while the virtualenv is active. Eg.:

(venv) user my_projectMain $ pip install django-bootstrap3

instead of:

(venv) user my_projectMain $ pip3 install django-bootstrap3

My question edit shows that I figured out the correct WSGIDaemonProcess python-path for my directory structure. Thanks to @spectras for the help there.


Next were some filesystem permission setup steps that I was completely glossing over in the guide that I was following (link below).


After all of that, I was still getting: ImportError: No module named 'django_static_jquery'. If I removed that line from my INSTALLED_APPS in settings.py, then the site would load properly.

Ultimately, this was because I was using mod_wsgi compiled against Python 3.4, in my Python 3.5.2 virtualenv as @Graham Dumpleton noted above. I had been installing mod_wsgi using:

sudo apt-get install libapache2-mod-wsgi-py3

Which was using the Python 3.4 that came with my OS(raspbian jessie, btw).

However, since I had installed Python 3.5.2 manually, I also needed to install mod_wsgi manually and compile it against my 3.5.2 install. Here's what I did:

mkdir ~/mod_wsgiPy3.5
cd ~/mod_wsgiPy3.5
wget https://pypi.python.org/packages/84/65/44a10ac5e117abc40078575a3dcf3256545ba20495b7330ba59045ec3503/mod_wsgi-4.5.9.tar.gz
tar -zxvf mod_wsgi-4.5.9.tar.gz
cd mod_wsgi-4.5.9/
./configure --with-python=/usr/local/bin/python3
make
sudo make install

After this, apache wouldn't restart because . I discovered this was because I had to activate this newly install mod_wsgi module in apache. This was accomplished with:

sudo a2enmod
wsgi
sudo systemctl restart apache2

/etc/apache2/sites-available/000-default.conf:

...
WSGIDaemonProcess my_project python-path=/home/user/my_projectMain/my_project/my_project python-home=/home/user/my_projectMain/venv
WSGIProcessGroup my_project
WSGIScriptAlias / /home/user/my_projectMain/my_project/my_project/wsgi.py
...

Final directory structure (~/my_projectMain/):

.
├── my_project
│   ├── app
│   ├── db.sqlite3
│   ├── manage.py
│   ├── my_project
│   └── static
└── venv

Everything is working great now. I recommend this guide as it helped me through a lot: How To Serve Django Applications with Apache and mod_wsgi on Debian 8. Looks like they have a few of those for various OSs

brewcrazy
  • 623
  • 13
  • 30
0

In Apache configuration, WSGIDaemonProcess directive:

Your python-path is either incorrect or incomplete. For my_project to be importable, you must add /home/pi/projects/my_projectMain/my_project to python path.

For instance:

WSGIDaemonProcess my_project python-path=/home/user/projects/my_projectMain/my_project python-home=/home/user/projects/my_projectMain/my_projectEnv

Double-check the all the configuration in that file, it's probably pi instead of user in most places. Including the line above.

spectras
  • 13,105
  • 2
  • 31
  • 53
  • The user is pi everywhere appropriate in my files. I just tried to genericize everything above and missed that one line in the stack trace. – brewcrazy Mar 02 '17 at 22:07
  • `WSGIDaemonProcess my_project python-path=/home/user/projects/my_projectMain/my_project` yields the same error: ImportError: No module named 'my_project' – brewcrazy Mar 02 '17 at 22:11
  • Just checking that you changed it: it should probably be `pi` in that line as well – spectras Mar 02 '17 at 22:40
  • Yes of course. The actual line uses pi in place of user – brewcrazy Mar 02 '17 at 22:49
  • I don't see where it goes wrong then. Can you somehow output the `sys.path` variable in your `wsgi.py` to check whether the python path value actually gets through to it? Perhaps by writing it to a temp file. – spectras Mar 02 '17 at 23:23
  • This what you're looking for? Printed from wsgi.py `sys path: ['/home/user/projects/my_projectMain/my_project', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-arm-linux-gnueabihf', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages', '/home/user/projects/my_projectMain', '/home/user/projects']` – brewcrazy Mar 03 '17 at 02:06
  • @brewcrazy> yes! As I see in your edited question, python now finds your settings correctly. And errs a bit later, looking for another module. That's another path you have to add, so it can be found as well. – spectras Mar 03 '17 at 09:26
  • Thanks for your help. I eventually got everything working. Details in my answer. – brewcrazy Mar 04 '17 at 18:16