The error occurs when running a2enmod
because Ubuntu/Debian packages name the module differently than expected. Here's what's happening under the hood:
# The package installs these config files:
/etc/apache2/mods-available/wsgi.load
/etc/apache2/mods-available/wsgi.conf
Instead of using mod-wsgi
or libapache2-mod-wsgi
as the module name, use the correct syntax:
sudo a2enmod wsgi # Note: just 'wsgi' without any prefixes
sudo systemctl restart apache2
To confirm the module is properly loaded:
apache2ctl -t -D DUMP_MODULES | grep wsgi
# Should output: wsgi_module (shared)
Here's a proper virtual host configuration for WSGI applications:
<VirtualHost *:80>
ServerName yourdomain.com
WSGIDaemonProcess myapp python-home=/path/to/venv
WSGIScriptAlias / /var/www/myapp/wsgi.py
<Directory /var/www/myapp>
WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}
Require all granted
</Directory>
</VirtualHost>
If your WSGI script still shows as plain text:
# 1. Check file permissions:
sudo chmod 755 /var/www/myapp/wsgi.py
# 2. Verify MIME types are configured:
AddType text/html .py .wsgi
# 3. Ensure Python headers are correct:
def application(environ, start_response):
status = '200 OK'
headers = [('Content-type', 'text/html; charset=utf-8')]
start_response(status, headers)
return [b"Hello World"]
For production environments, consider these optimizations:
# In your WSGI configuration:
WSGIDaemonProcess myapp \
python-home=/path/to/venv \
python-path=/path/to/app \
processes=4 \
threads=25 \
display-name=myapp-process
# For better performance:
WSGISocketPrefix /var/run/apache2/wsgi
Remember to always test your configuration changes before restarting Apache:
sudo apache2ctl configtest
sudo systemctl restart apache2
When setting up MOD_WSGI on Ubuntu, many developers encounter the frustrating "module not found" error despite successful package installation. The root cause typically lies in Ubuntu's package naming conventions and Apache module loading mechanisms.
First, confirm the package is properly installed:
dpkg -l libapache2-mod-wsgi
dpkg -s libapache2-mod-wsgi
The critical mistake is using wrong module names. Ubuntu expects:
sudo a2enmod wsgi
sudo systemctl restart apache2
For your virtual host configuration, ensure proper WSGI handler setup:
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Require all granted
AddHandler wsgi-script .wsgi
WSGIScriptAlias / /var/www/test.wsgi
</Directory>
Here's a more robust test application with debugging:
def application(environ, start_response):
# Debug output to check environment
import pprint
with open('/tmp/wsgi_debug.log', 'w') as f:
pprint.pprint(environ, stream=f)
status = '200 OK'
headers = [
('Content-type', 'text/plain; charset=utf-8'),
('Cache-Control', 'no-store, no-cache, must-revalidate')
]
start_response(status, headers)
return [b'WSGI Test Successful!\n',
b'Python Version: ' + environ['mod_wsgi.version'].encode('utf-8')]
- Check Apache error logs:
tail -f /var/log/apache2/error.log
- Verify module symlinks exist in
/etc/apache2/mods-enabled/
- Test WSGI configuration:
apache2ctl configtest
- Ensure correct permissions on WSGI files
If package installation fails, consider compiling from source:
sudo apt install apache2-dev python-dev
wget https://github.com/GrahamDumpleton/mod_wsgi/archive/refs/tags/4.9.3.tar.gz
tar xvfz 4.9.3.tar.gz
cd mod_wsgi-4.9.3
./configure --with-python=/usr/bin/python3
make
sudo make install
For deployment environments, consider these optimizations:
WSGIDaemonProcess myapp python-home=/path/to/venv python-path=/path/to/app
WSGIProcessGroup myapp
WSGIScriptReloading On
WSGIPassAuthorization On