Why is my virtualenv not activated by uwsgi?

On a fresh install of Debian Bullseye I am unable to use the uwsgi command. It fails to load the requested virtualenv.

This is the command that fails:

uwsgi --plugins http,python3 --wsgi-file wsgi.py --http :9090 --virtualenv /opt/example/virtualenv

The content of wsgi.py is just the default Django-generated file with an added print() statement:

import os, sys
print(sys.path)
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'example.settings')
application = get_wsgi_application()

And this is the output of the uwsgi command:

$ uwsgi --plugins http,python3 --wsgi-file wsgi.py --http :9090 --virtualenv /opt/example/virtualenv
*** Starting uWSGI 2.0.19.1-debian (64bit) on [Tue Nov 24 16:33:40 2020] ***
compiled with version: 10.2.0 on 23 November 2020 03:27:28
os: Linux-5.9.0-2-cloud-amd64 #1 SMP Debian 5.9.6-1 (2020-11-08)
nodename: exodus
machine: x86_64
clock source: unix
pcre jit disabled
detected number of CPU cores: 1
current working directory: /opt/example
detected binary path: /usr/bin/uwsgi-core
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 3868
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uWSGI http bound on :9090 fd 4
spawned uWSGI http 1 (pid: 33793)
uwsgi socket 0 bound to TCP address 127.0.0.1:41467 (port auto-assigned) fd 3
Python version: 3.9.0+ (default, Oct 19 2020, 09:51:18)  [GCC 10.2.0]
PEP 405 virtualenv detected: /opt/example/virtualenv
Set PythonHome to /opt/example/virtualenv
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x562115d61f30
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 72920 bytes (71 KB) for 1 cores
*** Operational MODE: single process ***
['.', '', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload']
Traceback (most recent call last):
  File "wsgi.py", line 12, in <module>
    from django.core.wsgi import get_wsgi_application
ModuleNotFoundError: No module named 'django'
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI worker 1 (and the only) (pid: 33792, cores: 1)

As you can see, uwsgi informs me that is has detected the virtualenv and has "Set PythonHome to /opt/example/virtualenv", but the output of the print() statement shows that this is not the case.

If I activate the virtualenv manually, I can confirm that Django is correctly installed inside the virtualenv:

$ . /opt/example/virtualenv/bin/activate
$ python
Python 3.8.6 (default, Sep 25 2020, 09:36:53) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.__file__
'/opt/example/virtualenv/lib/python3.8/site-packages/django/__init__.py'
>>>

What's wrong and how can I fix this?


I've seen similar things before and what I do is install uwsgi via pip so when you run it, uwsgi is already "in" the virtualenv and therefore activated.