Issue
Maybe some needed context:
I installed python3.9 into a directory /opt/python39/
. I compiled mod_wsgi with this version of python (href="https://stackoverflow.com/questions/72552357/httpd-wont-start-with-custom-conf-files-and-mod-wsgi-built-with-python3-9">as per this post) and was able to conduct a test to make sure that it was working correctly. I am not using a virtual environment.
I am trying to move my django project to production, so naturally, I am following the django docs. When I use the default file configurations at the very beginning, i.e.:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonHome /opt/python39/bin/python3.9
WSGIPythonPath /path/to/mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
It works (for the most part - there are resources missing on the page, but thats for another SO post) like a charm.
So I continue through the docs (which is now telling me that I should move it to "Daemon mode"):
“Daemon mode” is the recommended mode for running mod_wsgi (on non-Windows platforms). To create the required daemon process group and delegate the Django instance to run in it, you will need to add appropriate WSGIDaemonProcess and WSGIProcessGroup directives. A further change required to the above configuration if you use daemon mode is that you can’t use WSGIPythonPath; instead you should use the python-path option to WSGIDaemonProcess, for example:
So I change my file to look like:
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
#WSGIPythonHome /opt/python39/bin/python3.9
#WSGIPythonPath /path/to/mysite.com
WSGIDaemonProcess mysite.com python-home=/opt/python39/bin/python3.9 python-path=/path/to/mysite.com
WSGIProcessGroup mysite.com
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
then run sudo apachectl restart
, go back to my browser, refresh, shows 500 internal server error, check my logs, and "what do you know?" - ImportError: "No module named 'django'".
I've come across this SO article that seems to be describing my problem, but for virtual environments, and offers a solution, but I give it a go anyway:
WSGIProcessGroup mysite.com
WSGIDaemonProcess mysite.com python-home=/opt/python39 python-path=/path/to/mysite.com
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py process-group=iengravethat.com application-group=%{GLOBAL}
<Directory /path/to/mysite.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
I rerun sudo apachectl restart
, check my browser - same error, check the logs - same error.
I have tried a multitude of other configurations, but they all boil down to this error. Does anyone have any idea as to how to remedy this problem?
---UPDATE---
SUTerliakov and I opened up a channel for discussion, the end conclusion was thus:
Regarding recompilation - I was absolutely happy with the following installation (from Dockerfile, but it doesn't really matter):
pip install -U --no-cache-dir mod-wsgi
mod_wsgi-express install-module | tee /etc/apache2/mods-available/wsgi_express.load /etc/apache2/mods-available/wsgi_express.conf
And it can be done from venv too. I really don't understand why did your paths stop working after switching to daemon mode. I just suggest to try virtualenv instead, because this method is recommended by maintainer. You can just drop "tee" part and use standalone mod_wsgi-express install-module. It will print two lines of config, you can add them to your config file manually. It will print WSGIPythonHome, take this value and use for python-home option of WSGIDaemonProcess. (may require root, AFAIR)
So, basically just create a venv and link it in your .conf file.
- Create a virtual environment with the python interpreter you want to use and activate it.
pip install
the packages you were using for django.pip install mod-wsgi
.- Grab the version of mod_wsgi you want.
- un
tar
it and enter the directory. ./configure --with-python=python3
(This python3 is the same version as the python3 I wanted - not python 3.6 which comes pre-installed on centos7).make LDFLAGS='-L/path/to/venv/lib -Wl,-rpath,/path/to/venv/lib'
.sudo make install
.- run
mod_wsgi-express module-config
and copy and paste it at the top of your .conf file. deactivate
your environment.- restart apache -
sudo apachectl restart
Solution
I have the following config:
ServerName ${SERVER_NAME}
ServerAdmin ${SERVER_ADMIN}
<IfModule unixd_module>
User ${APP_USER}
Group ${APP_USER}
</IfModule>
WSGIRestrictEmbedded On
WSGIPassAuthorization On
IncludeOptional /etc/apache2/conf.d/*.conf
Timeout 60
<VirtualHost *:80>
Redirect permanent / https://${SERVER_NAME}/
</VirtualHost>
<VirtualHost *:443>
Alias /media <media folder>
<Directory <media_folder> >
Options -Indexes
Require all granted
</Directory>
Alias /static <static_folder>
<Directory <static_folder> >
Options -Indexes
Require all granted
</Directory>
WSGIDaemonProcess <name> processes=1 threads=5 display-name=%{GROUP} home=<top_folder>
WSGIScriptAlias / <wsgi.py path> process-group=<name> application-group=%{GLOBAL}
... SSL config here ...
</VirtualHost>
It is not a full config: logging, SSL and WebSocket proxies are thrown away.
<name>
is any alias<top_folder>
is folder withmanage.py
file<wsgi.py path>
is<top_folder>/something/wsgi.py
<media_folder>
and<static_folder>
are paths ofMEDIA_ROOT
andSTATIC_ROOT
settings.
It is deployed with docker (system-level package installation as root, no virtual environment).
Final attempt
Probably something gets messed up when using system python that is not the default interpreter. You can set up virtual environment and make httpd use it. To avoid manual recompilation, mod_wsgi
pip package can be used:
# With venv activated
pip install mod_wsgi
sudo mod_wsgi-express install-module
This will install mod_wsgi
for venv python and print two lines of config: LoadModule ...
and WSGIPythonHome <path>
. You can add LoadModule
to configuration file and use the following daemon config:
WSGIDaemonProcess mysite.com home=/path/to/mysite.com python-home=<venv_root>
Note
You don't need to recompile mod_wsgi
manually with this package, it is the most amazing aspect of such installation! Two commands above are sufficient to install mod_wsgi
. It will copy module files to required folders for you (see end of this readme), so your steps 4-8 can be omitted.
Answered By - SUTerliakov Answer Checked By - Dawn Plyler (WPSolving Volunteer)